From 1dca8c4447cb2a4c004b4de3956e957b44b75e26 Mon Sep 17 00:00:00 2001 From: almeidx Date: Sat, 11 Mar 2023 19:31:36 +0000 Subject: [PATCH] half the number of errors --- backend/package-lock.json | 99 ++++++++++++------- backend/package.json | 11 ++- backend/src/api/guilds/misc.ts | 3 - backend/src/data/AllowedGuilds.ts | 1 - backend/src/data/ApiAuditLog.ts | 1 - backend/src/data/GuildArchives.ts | 8 +- backend/src/data/GuildCases.ts | 1 - backend/src/data/GuildRoleButtons.ts | 6 -- backend/src/data/GuildRoleQueue.ts | 4 - backend/src/data/GuildSavedMessages.ts | 2 - backend/src/data/Mutes.ts | 2 +- backend/src/data/entities/ApiAuditLogEntry.ts | 3 +- backend/src/data/entities/CounterTrigger.ts | 2 +- backend/src/data/entities/Reminder.ts | 2 +- backend/src/data/entities/ScheduledPost.ts | 2 +- backend/src/data/entities/VCAlert.ts | 2 +- .../data/loops/expiredArchiveDeletionLoop.ts | 1 - backend/src/data/loops/expiringMutesLoop.ts | 2 +- backend/src/data/loops/phishermanLoops.ts | 2 +- backend/src/index.ts | 67 +++++++++---- backend/src/pluginUtils.ts | 18 +--- .../plugins/AutoDelete/util/deleteNextItem.ts | 5 +- .../AutoDelete/util/onMessageCreate.ts | 1 - .../commands/NewAutoReactionsCmd.ts | 2 +- .../AutoReactions/events/AddReactionsEvt.ts | 3 +- .../src/plugins/Automod/actions/addRoles.ts | 5 +- .../plugins/Automod/actions/addToCounter.ts | 1 - backend/src/plugins/Automod/actions/alert.ts | 8 +- .../plugins/Automod/actions/archiveThread.ts | 4 +- .../plugins/Automod/actions/changeNickname.ts | 1 - backend/src/plugins/Automod/actions/clean.ts | 2 +- backend/src/plugins/Automod/actions/log.ts | 4 +- backend/src/plugins/Automod/actions/mute.ts | 1 - .../plugins/Automod/actions/removeRoles.ts | 5 +- backend/src/plugins/Automod/actions/reply.ts | 14 +-- .../src/plugins/Automod/actions/setCounter.ts | 1 - .../plugins/Automod/actions/setSlowmode.ts | 7 +- .../plugins/Automod/actions/startThread.ts | 12 +-- .../Automod/events/runAutomodOnMessage.ts | 1 - .../functions/getTextMatchPartialSummary.ts | 2 +- .../matchMultipleTextTypesOnMessage.ts | 7 +- .../functions/resolveActionContactMethods.ts | 2 +- .../plugins/Automod/functions/runAutomod.ts | 2 +- .../Automod/functions/setAntiraidLevel.ts | 2 - .../plugins/Automod/triggers/anyMessage.ts | 2 +- .../Automod/triggers/matchAttachmentType.ts | 4 +- .../plugins/Automod/triggers/matchLinks.ts | 1 - .../plugins/Automod/triggers/matchMimeType.ts | 6 +- .../plugins/Automod/triggers/threadArchive.ts | 3 +- .../plugins/Automod/triggers/threadCreate.ts | 3 +- .../plugins/Automod/triggers/threadDelete.ts | 3 +- .../Automod/triggers/threadUnarchive.ts | 3 +- backend/src/plugins/Automod/types.ts | 2 +- .../commands/AddDashboardUserCmd.ts | 3 +- .../commands/AddServerFromInviteCmd.ts | 21 ++-- .../BotControl/commands/AllowServerCmd.ts | 9 +- .../BotControl/commands/ChannelToServerCmd.ts | 11 +-- .../BotControl/commands/DisallowServerCmd.ts | 6 +- .../BotControl/commands/EligibleCmd.ts | 9 +- .../BotControl/commands/LeaveServerCmd.ts | 8 +- .../commands/ListDashboardPermsCmd.ts | 19 ++-- .../commands/ListDashboardUsersCmd.ts | 7 +- .../BotControl/commands/ProfilerDataCmd.ts | 5 +- .../commands/RateLimitPerformanceCmd.ts | 7 +- .../commands/ReloadGlobalPluginsCmd.ts | 11 ++- .../BotControl/commands/ReloadServerCmd.ts | 8 +- .../commands/RemoveDashboardUserCmd.ts | 5 +- .../BotControl/commands/RestPerformanceCmd.ts | 6 +- .../plugins/BotControl/commands/ServersCmd.ts | 3 +- .../src/plugins/Cases/functions/createCase.ts | 2 +- .../plugins/Cases/functions/getCaseEmbed.ts | 4 +- .../Cases/functions/postToCaseLogChannel.ts | 25 +++-- .../plugins/Censor/util/applyFiltersToMsg.ts | 4 +- .../src/plugins/Censor/util/censorMessage.ts | 7 +- .../commands/ArchiveChannelCmd.ts | 2 +- .../ChannelArchiver/rehostAttachment.ts | 9 +- .../src/plugins/ContextMenus/actions/clean.ts | 5 +- .../src/plugins/ContextMenus/actions/mute.ts | 5 +- .../plugins/ContextMenus/actions/userInfo.ts | 4 +- .../ContextMenus/events/ContextClickedEvt.ts | 5 +- .../ContextMenus/utils/contextRouter.ts | 4 +- .../ContextMenus/utils/loadAllCommands.ts | 7 +- .../Counters/commands/ViewCounterCmd.ts | 2 +- .../CustomEvents/CustomEventsPlugin.ts | 4 +- .../CustomEvents/actions/addRoleAction.ts | 1 - .../actions/makeRoleMentionableAction.ts | 16 +-- .../actions/makeRoleUnmentionableAction.ts | 7 +- .../actions/setChannelPermissionOverrides.ts | 6 +- .../CustomEvents/functions/runEvent.ts | 4 +- .../GuildInfoSaver/GuildInfoSaverPlugin.ts | 2 +- backend/src/plugins/GuildInfoSaver/types.ts | 1 - .../InternalPoster/InternalPosterPlugin.ts | 9 +- .../InternalPoster/functions/editMessage.ts | 16 +-- .../functions/getOrCreateWebhookForChannel.ts | 9 +- .../LocateUser/events/SendAlertsEvts.ts | 14 +-- backend/src/plugins/LocateUser/types.ts | 1 - .../plugins/LocateUser/utils/moveMember.ts | 4 +- .../plugins/LocateUser/utils/sendAlerts.ts | 12 ++- .../src/plugins/LocateUser/utils/sendWhere.ts | 4 +- backend/src/plugins/Logs/LogsPlugin.ts | 6 +- .../Logs/events/LogsChannelModifyEvts.ts | 2 - .../events/LogsEmojiAndStickerModifyEvts.ts | 2 +- .../plugins/Logs/events/LogsGuildBanEvts.ts | 15 ++- .../Logs/events/LogsGuildMemberAddEvt.ts | 5 - .../Logs/events/LogsGuildMemberRemoveEvt.ts | 2 - .../plugins/Logs/events/LogsRoleModifyEvts.ts | 4 +- .../events/LogsStageInstanceModifyEvts.ts | 4 +- .../Logs/events/LogsThreadModifyEvts.ts | 4 +- .../plugins/Logs/events/LogsUserUpdateEvts.ts | 2 - .../Logs/events/LogsVoiceChannelEvts.ts | 2 - .../plugins/Logs/logFunctions/logCensor.ts | 2 +- .../Logs/logFunctions/logChannelCreate.ts | 4 +- .../Logs/logFunctions/logChannelDelete.ts | 4 +- .../Logs/logFunctions/logChannelUpdate.ts | 6 +- .../src/plugins/Logs/logFunctions/logClean.ts | 4 +- .../plugins/Logs/logFunctions/logMemberBan.ts | 2 +- .../Logs/logFunctions/logMemberKick.ts | 4 +- .../Logs/logFunctions/logMemberMute.ts | 4 +- .../Logs/logFunctions/logMemberUnban.ts | 4 +- .../Logs/logFunctions/logMemberUnmute.ts | 4 +- .../Logs/logFunctions/logMessageDelete.ts | 2 +- .../Logs/logFunctions/logMessageDeleteAuto.ts | 4 +- .../Logs/logFunctions/logMessageDeleteBare.ts | 2 +- .../Logs/logFunctions/logMessageDeleteBulk.ts | 2 +- .../Logs/logFunctions/logMessageEdit.ts | 2 +- .../logFunctions/logMessageSpamDetected.ts | 4 +- .../logFunctions/logPostedScheduledMessage.ts | 2 +- .../Logs/logFunctions/logRepeatedMessage.ts | 2 +- .../Logs/logFunctions/logScheduledMessage.ts | 2 +- .../logScheduledRepeatedMessage.ts | 2 +- .../logFunctions/logStageInstanceUpdate.ts | 4 +- .../Logs/logFunctions/logThreadCreate.ts | 4 +- .../Logs/logFunctions/logThreadDelete.ts | 4 +- .../Logs/logFunctions/logThreadUpdate.ts | 6 +- .../logVoiceChannelForceDisconnect.ts | 4 +- .../logFunctions/logVoiceChannelForceMove.ts | 6 +- .../Logs/logFunctions/logVoiceChannelJoin.ts | 4 +- .../Logs/logFunctions/logVoiceChannelLeave.ts | 4 +- .../Logs/logFunctions/logVoiceChannelMove.ts | 6 +- backend/src/plugins/Logs/types.ts | 10 +- .../src/plugins/Logs/util/getLogMessage.ts | 4 +- backend/src/plugins/Logs/util/log.ts | 6 +- .../src/plugins/Logs/util/onMessageDelete.ts | 9 +- .../plugins/Logs/util/onMessageDeleteBulk.ts | 10 +- .../src/plugins/Logs/util/onMessageUpdate.ts | 4 +- .../MessageSaver/MessageSaverPlugin.ts | 1 - .../MessageSaver/events/SaveMessagesEvts.ts | 6 +- .../plugins/MessageSaver/saveMessagesToDB.ts | 4 +- backend/src/plugins/MessageSaver/types.ts | 1 - .../plugins/ModActions/commands/AddCaseCmd.ts | 2 - .../src/plugins/ModActions/commands/BanCmd.ts | 2 - .../ModActions/commands/CasesModCmd.ts | 8 +- .../ModActions/commands/CasesUserCmd.ts | 8 +- .../ModActions/commands/DeleteCaseCmd.ts | 12 +-- .../ModActions/commands/ForcebanCmd.ts | 5 +- .../plugins/ModActions/commands/MassBanCmd.ts | 11 +-- .../ModActions/commands/MassUnbanCmd.ts | 5 +- .../ModActions/commands/MassmuteCmd.ts | 5 +- .../plugins/ModActions/commands/NoteCmd.ts | 2 - .../plugins/ModActions/commands/UnbanCmd.ts | 1 - .../plugins/ModActions/commands/WarnCmd.ts | 3 +- .../events/CreateBanCaseOnManualBanEvt.ts | 9 +- .../events/CreateKickCaseOnManualKickEvt.ts | 6 +- .../events/CreateUnbanCaseOnManualUnbanEvt.ts | 10 +- .../events/PostAlertOnMemberJoinEvt.ts | 1 - .../functions/actualKickMemberCmd.ts | 8 +- .../ModActions/functions/actualMuteUserCmd.ts | 18 ++-- .../functions/actualUnmuteUserCmd.ts | 10 +- .../plugins/ModActions/functions/banUserId.ts | 5 +- .../ModActions/functions/clearTempban.ts | 2 +- .../plugins/ModActions/functions/isBanned.ts | 1 - .../functions/readContactMethodsFromArgs.ts | 4 +- .../ModActions/functions/updateCase.ts | 9 +- .../ModActions/functions/warnMember.ts | 3 +- backend/src/plugins/ModActions/types.ts | 6 +- backend/src/plugins/Mutes/MutesPlugin.ts | 1 - .../Mutes/commands/ClearBannedMutesCmd.ts | 2 +- .../src/plugins/Mutes/commands/MutesCmd.ts | 20 ++-- .../events/ReapplyActiveMuteOnJoinEvt.ts | 2 - .../src/plugins/Mutes/functions/muteUser.ts | 2 +- .../src/plugins/Mutes/functions/unmuteUser.ts | 3 - backend/src/plugins/Mutes/types.ts | 2 - .../plugins/NameHistory/NameHistoryPlugin.ts | 1 - .../src/plugins/Persist/events/LoadDataEvt.ts | 12 +-- .../plugins/Phisherman/PhishermanPlugin.ts | 10 +- .../PingableRoles/PingableRolesPlugin.ts | 1 - .../events/ChangePingableEvts.ts | 2 +- .../utils/disablePingableRoles.ts | 7 +- .../utils/enablePingableRoles.ts | 7 +- backend/src/plugins/Post/commands/EditCmd.ts | 1 - .../src/plugins/Post/commands/EditEmbedCmd.ts | 4 +- .../Post/commands/ScheduledPostsShowCmd.ts | 3 +- .../src/plugins/Post/util/actualPostCmd.ts | 42 +++----- backend/src/plugins/Post/util/postMessage.ts | 12 +-- .../plugins/Post/util/postScheduledPost.ts | 3 +- .../util/addMemberPendingRoleChange.ts | 7 +- .../applyReactionRoleReactionsToMessage.ts | 8 +- .../Reminders/functions/postReminder.ts | 7 +- .../plugins/RoleButtons/RoleButtonsPlugin.ts | 1 - .../RoleButtons/functions/applyRoleButtons.ts | 8 +- .../convertButtonStyleStringToEnum.ts | 17 ++++ .../functions/createButtonComponents.ts | 19 ++-- backend/src/plugins/RoleButtons/types.ts | 7 ++ backend/src/plugins/RoleManager/types.ts | 3 +- .../src/plugins/Roles/commands/AddRoleCmd.ts | 1 - .../plugins/Roles/commands/MassAddRoleCmd.ts | 1 - .../Roles/commands/MassRemoveRoleCmd.ts | 1 - .../plugins/Roles/commands/RemoveRoleCmd.ts | 1 - .../Slowmode/commands/SlowmodeGetCmd.ts | 3 +- .../Slowmode/commands/SlowmodeSetCmd.ts | 29 +++--- .../Slowmode/util/actualDisableSlowmodeCmd.ts | 10 +- .../Slowmode/util/applyBotSlowmodeToUserId.ts | 5 +- .../util/clearBotSlowmodeFromUserId.ts | 4 +- .../Slowmode/util/clearExpiredSlowmodes.ts | 2 - .../util/disableBotSlowmodeForChannel.ts | 4 +- .../plugins/Slowmode/util/onMessageCreate.ts | 6 +- .../Spam/util/logAndDetectMessageSpam.ts | 1 - .../Spam/util/logAndDetectOtherSpam.ts | 2 - .../src/plugins/Starboard/StarboardPlugin.ts | 26 ++--- .../util/createStarboardEmbedFromMessage.ts | 4 +- .../Starboard/util/saveMessageToStarboard.ts | 6 +- .../src/plugins/Tags/commands/TagEvalCmd.ts | 5 +- .../src/plugins/Tags/util/onMessageCreate.ts | 5 +- .../src/plugins/Tags/util/onMessageDelete.ts | 14 +-- backend/src/plugins/Utility/UtilityPlugin.ts | 2 +- .../src/plugins/Utility/commands/AboutCmd.ts | 34 +++---- .../src/plugins/Utility/commands/AvatarCmd.ts | 6 +- .../src/plugins/Utility/commands/JumboCmd.ts | 2 +- .../src/plugins/Utility/commands/SourceCmd.ts | 1 - .../Utility/commands/VcdisconnectCmd.ts | 6 -- .../src/plugins/Utility/commands/VcmoveCmd.ts | 6 -- .../Utility/functions/getChannelInfoEmbed.ts | 30 +++--- .../Utility/functions/getEmojiInfoEmbed.ts | 17 ++-- .../Utility/functions/getInviteInfoEmbed.ts | 14 ++- .../Utility/functions/getMessageInfoEmbed.ts | 38 ++++--- .../Utility/functions/getRoleInfoEmbed.ts | 20 ++-- .../Utility/functions/getServerInfoEmbed.ts | 47 +++------ .../functions/getSnowflakeInfoEmbed.ts | 15 ++- .../Utility/functions/getUserInfoEmbed.ts | 6 +- backend/src/plugins/Utility/search.ts | 23 ++--- .../events/SendWelcomeMessageEvt.ts | 4 +- backend/src/types.ts | 22 ----- backend/src/utils.ts | 16 ++- backend/src/utils/calculateEmbedSize.ts | 4 +- backend/src/utils/createPaginatedMessage.ts | 2 - backend/src/utils/crypt.ts | 1 - backend/src/utils/filterObject.ts | 2 +- .../src/utils/findMatchingAuditLogEntry.ts | 7 +- backend/src/utils/getGuildPrefix.ts | 1 + backend/src/utils/isDmChannel.ts | 2 +- backend/src/utils/isGuildChannel.ts | 4 +- backend/src/utils/isThreadChannel.ts | 2 +- backend/src/utils/messageHasContent.ts | 6 +- backend/src/utils/messageIsEmpty.ts | 3 +- backend/src/utils/permissionNames.ts | 6 +- backend/src/utils/resolveMessageTarget.ts | 2 +- backend/src/utils/typeUtils.ts | 4 + backend/src/utils/validateNoObjectAliases.ts | 2 - backend/src/utils/waitForInteraction.ts | 5 - package-lock.json | 19 ++-- package.json | 4 +- 261 files changed, 760 insertions(+), 1023 deletions(-) create mode 100644 backend/src/plugins/RoleButtons/functions/convertButtonStyleStringToEnum.ts diff --git a/backend/package-lock.json b/backend/package-lock.json index 992344d5..5a37b769 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -13,8 +13,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord-api-types": "^0.33.1", - "discord.js": "^14.7.1", + "discord.js": "14.7.2-dev.1678536262-1b29099.0", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -53,7 +52,7 @@ "tsconfig-paths": "^3.9.0", "twemoji": "^12.1.4", "typeorm": "^0.2.31", - "typescript": "4.9", + "typescript": "~4.9.5", "utf-8-validate": "^5.0.5", "uuid": "^3.3.2", "yawn-yaml": "github:dragory/yawn-yaml#string-number-fix-build", @@ -158,6 +157,22 @@ "node": ">=16.9.0" } }, + "node_modules/@discordjs/formatters": { + "version": "0.1.1-dev.1678536268-1b29099.0", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.1.1-dev.1678536268-1b29099.0.tgz", + "integrity": "sha512-cMjsbJPW23HolJdx6zefhtc12qfHO7AY10miC3pSMB47dnvO4w8yJwBy6N7Y8pKpQzf5GNqOrJ87Z16CTeWHjw==", + "dependencies": { + "discord-api-types": "^0.37.35" + }, + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/@discordjs/formatters/node_modules/discord-api-types": { + "version": "0.37.35", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.35.tgz", + "integrity": "sha512-iyKZ/82k7FX3lcmHiAvvWu5TmyfVo78RtghBV/YsehK6CID83k5SI03DKKopBcln+TiEIYw5MGgq7SJXSpNzMg==" + }, "node_modules/@discordjs/rest": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-1.5.0.tgz", @@ -478,8 +493,9 @@ "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.3", - "license": "MIT", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", + "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", "dependencies": { "@types/node": "*" } @@ -1752,28 +1768,24 @@ "node": ">=8" } }, - "node_modules/discord-api-types": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.4.tgz", - "integrity": "sha512-Y6RMvXsHKiBgQhm/q5MgRieXc4Tzh5p/JuDyqreI48lmy+AQfO+g9Xhz0tuGBaN1FtsrLT7mD+lbFONPo5vdwA==" - }, "node_modules/discord.js": { - "version": "14.7.1", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.7.1.tgz", - "integrity": "sha512-1FECvqJJjjeYcjSm0IGMnPxLqja/pmG1B0W2l3lUY2Gi4KXiyTeQmU1IxWcbXHn2k+ytP587mMWqva2IA87EbA==", + "version": "14.7.2-dev.1678536262-1b29099.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.7.2-dev.1678536262-1b29099.0.tgz", + "integrity": "sha512-Z2D0Ae4yxeVvaPa9ot88fPMuzADsKqZuqCLFKJ91XGjY5AL7uZxUCrnNNMUoi4JfSrL4GIG6eA7ddX/lORoCmQ==", "dependencies": { "@discordjs/builders": "^1.4.0", "@discordjs/collection": "^1.3.0", - "@discordjs/rest": "^1.4.0", + "@discordjs/formatters": "^0.1.0", + "@discordjs/rest": "^1.5.0", "@discordjs/util": "^0.1.0", - "@sapphire/snowflake": "^3.2.2", - "@types/ws": "^8.5.3", - "discord-api-types": "^0.37.20", + "@sapphire/snowflake": "^3.4.0", + "@types/ws": "^8.5.4", + "discord-api-types": "^0.37.35", "fast-deep-equal": "^3.1.3", "lodash.snakecase": "^4.1.1", - "tslib": "^2.4.1", - "undici": "^5.13.0", - "ws": "^8.11.0" + "tslib": "^2.5.0", + "undici": "^5.20.0", + "ws": "^8.12.1" }, "engines": { "node": ">=16.9.0" @@ -5523,6 +5535,21 @@ "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.3.0.tgz", "integrity": "sha512-ylt2NyZ77bJbRij4h9u/wVy7qYw/aDqQLWnadjvDqW/WoWCxrsX6M3CIw9GVP5xcGCDxsrKj5e0r5evuFYwrKg==" }, + "@discordjs/formatters": { + "version": "0.1.1-dev.1678536268-1b29099.0", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.1.1-dev.1678536268-1b29099.0.tgz", + "integrity": "sha512-cMjsbJPW23HolJdx6zefhtc12qfHO7AY10miC3pSMB47dnvO4w8yJwBy6N7Y8pKpQzf5GNqOrJ87Z16CTeWHjw==", + "requires": { + "discord-api-types": "^0.37.35" + }, + "dependencies": { + "discord-api-types": { + "version": "0.37.35", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.35.tgz", + "integrity": "sha512-iyKZ/82k7FX3lcmHiAvvWu5TmyfVo78RtghBV/YsehK6CID83k5SI03DKKopBcln+TiEIYw5MGgq7SJXSpNzMg==" + } + } + }, "@discordjs/rest": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-1.5.0.tgz", @@ -5779,7 +5806,9 @@ "dev": true }, "@types/ws": { - "version": "8.5.3", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", + "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", "requires": { "@types/node": "*" } @@ -6599,28 +6628,24 @@ "path-type": "^4.0.0" } }, - "discord-api-types": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.4.tgz", - "integrity": "sha512-Y6RMvXsHKiBgQhm/q5MgRieXc4Tzh5p/JuDyqreI48lmy+AQfO+g9Xhz0tuGBaN1FtsrLT7mD+lbFONPo5vdwA==" - }, "discord.js": { - "version": "14.7.1", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.7.1.tgz", - "integrity": "sha512-1FECvqJJjjeYcjSm0IGMnPxLqja/pmG1B0W2l3lUY2Gi4KXiyTeQmU1IxWcbXHn2k+ytP587mMWqva2IA87EbA==", + "version": "14.7.2-dev.1678536262-1b29099.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.7.2-dev.1678536262-1b29099.0.tgz", + "integrity": "sha512-Z2D0Ae4yxeVvaPa9ot88fPMuzADsKqZuqCLFKJ91XGjY5AL7uZxUCrnNNMUoi4JfSrL4GIG6eA7ddX/lORoCmQ==", "requires": { "@discordjs/builders": "^1.4.0", "@discordjs/collection": "^1.3.0", - "@discordjs/rest": "^1.4.0", + "@discordjs/formatters": "0.1.1-dev.1678536268-1b29099.0", + "@discordjs/rest": "^1.5.0", "@discordjs/util": "^0.1.0", - "@sapphire/snowflake": "^3.2.2", - "@types/ws": "^8.5.3", - "discord-api-types": "^0.37.20", + "@sapphire/snowflake": "^3.4.0", + "@types/ws": "^8.5.4", + "discord-api-types": "^0.37.35", "fast-deep-equal": "^3.1.3", "lodash.snakecase": "^4.1.1", - "tslib": "^2.4.1", - "undici": "^5.13.0", - "ws": "^8.11.0" + "tslib": "^2.5.0", + "undici": "^5.20.0", + "ws": "^8.12.1" }, "dependencies": { "discord-api-types": { @@ -7214,7 +7239,7 @@ "integrity": "sha512-tT27Qr8qpge+EWonrMyw54mZ67/1WP3oKF7QgTdK6cYArTdERuYxF9X7ngd9JXcVeW9/WYz/62jq42/w9lDzIA==", "requires": { "discord-api-types": "^0.37.10", - "discord.js": "^14", + "discord.js": "14.7.2-dev.1678536262-1b29099.0", "knub-command-manager": "^9.1.0", "ts-essentials": "^9", "zod": "^3.19.1" diff --git a/backend/package.json b/backend/package.json index 9c30ca3e..52dc90be 100644 --- a/backend/package.json +++ b/backend/package.json @@ -28,8 +28,7 @@ "cors": "^2.8.5", "cross-env": "^5.2.0", "deep-diff": "^1.0.2", - "discord-api-types": "^0.33.1", - "discord.js": "^14.7.1", + "discord.js": "14.7.2-dev.1678536262-1b29099.0", "dotenv": "^4.0.0", "emoji-regex": "^8.0.0", "erlpack": "github:discord/erlpack", @@ -68,7 +67,7 @@ "tsconfig-paths": "^3.9.0", "twemoji": "^12.1.4", "typeorm": "^0.2.31", - "typescript": "4.9", + "typescript": "~4.9.5", "utf-8-validate": "^5.0.5", "uuid": "^3.3.2", "yawn-yaml": "github:dragory/yawn-yaml#string-number-fix-build", @@ -103,5 +102,11 @@ "require": [ "./register-tsconfig-paths.js" ] + }, + "overrides": { + "@discordjs/formatters": "0.1.1-dev.1678536268-1b29099.0", + "knub": { + "discord.js": "14.7.2-dev.1678536262-1b29099.0" + } } } diff --git a/backend/src/api/guilds/misc.ts b/backend/src/api/guilds/misc.ts index c4083c05..630e03d4 100644 --- a/backend/src/api/guilds/misc.ts +++ b/backend/src/api/guilds/misc.ts @@ -5,7 +5,6 @@ import { validateGuildConfig } from "../../configValidator"; import { AllowedGuilds } from "../../data/AllowedGuilds"; import { ApiPermissionAssignments, ApiPermissionTypes } from "../../data/ApiPermissionAssignments"; import { Configs } from "../../data/Configs"; -import { apiTokenAuthHandlers } from "../auth"; import { hasGuildPermission, requireGuildPermission } from "../permissions"; import { clientError, ok, serverError, unauthorized } from "../responses"; import { loadYamlSafely } from "../../utils/loadYamlSafely"; @@ -15,8 +14,6 @@ import moment from "moment-timezone"; import { ApiAuditLog } from "../../data/ApiAuditLog"; import { AuditLogEventTypes } from "../../data/apiAuditLogTypes"; import { Queue } from "../../Queue"; -import { GuildCases } from "../../data/GuildCases"; -import { z } from "zod"; const apiPermissionAssignments = new ApiPermissionAssignments(); const auditLog = new ApiAuditLog(); diff --git a/backend/src/data/AllowedGuilds.ts b/backend/src/data/AllowedGuilds.ts index a9d86220..747dbb87 100644 --- a/backend/src/data/AllowedGuilds.ts +++ b/backend/src/data/AllowedGuilds.ts @@ -4,7 +4,6 @@ import { BaseRepository } from "./BaseRepository"; import { AllowedGuild } from "./entities/AllowedGuild"; import moment from "moment-timezone"; import { DBDateFormat } from "../utils"; -import { env } from "../env"; export class AllowedGuilds extends BaseRepository { private allowedGuilds: Repository; diff --git a/backend/src/data/ApiAuditLog.ts b/backend/src/data/ApiAuditLog.ts index 199747ef..6088ed48 100644 --- a/backend/src/data/ApiAuditLog.ts +++ b/backend/src/data/ApiAuditLog.ts @@ -1,7 +1,6 @@ import { BaseRepository } from "./BaseRepository"; import { getRepository, Repository } from "typeorm/index"; import { ApiAuditLogEntry } from "./entities/ApiAuditLogEntry"; -import { ApiLogin } from "./entities/ApiLogin"; import { AuditLogEventData, AuditLogEventType } from "./apiAuditLogTypes"; export class ApiAuditLog extends BaseRepository { diff --git a/backend/src/data/GuildArchives.ts b/backend/src/data/GuildArchives.ts index b9ae4c05..ca73c892 100644 --- a/backend/src/data/GuildArchives.ts +++ b/backend/src/data/GuildArchives.ts @@ -1,4 +1,4 @@ -import { Guild, Snowflake, User } from "discord.js"; +import { Guild, Snowflake } from "discord.js"; import moment from "moment-timezone"; import { isDefaultSticker } from "src/utils/isDefaultSticker"; import { getRepository, Repository } from "typeorm"; @@ -6,11 +6,7 @@ import { renderTemplate, TemplateSafeValueContainer } from "../templateFormatter import { trimLines } from "../utils"; import { BaseGuildRepository } from "./BaseGuildRepository"; import { ArchiveEntry } from "./entities/ArchiveEntry"; -import { - channelToTemplateSafeChannel, - guildToTemplateSafeGuild, - userToTemplateSafeUser, -} from "../utils/templateSafeObjects"; +import { channelToTemplateSafeChannel, guildToTemplateSafeGuild } from "../utils/templateSafeObjects"; import { SavedMessage } from "./entities/SavedMessage"; import { decrypt, encrypt } from "../utils/crypt"; diff --git a/backend/src/data/GuildCases.ts b/backend/src/data/GuildCases.ts index 9c41c8b6..31a499a4 100644 --- a/backend/src/data/GuildCases.ts +++ b/backend/src/data/GuildCases.ts @@ -4,7 +4,6 @@ import { CaseTypes } from "./CaseTypes"; import { connection } from "./db"; import { Case } from "./entities/Case"; import { CaseNote } from "./entities/CaseNote"; -import moment from "moment-timezone"; import { chunkArray } from "../utils"; import { Queue } from "../Queue"; diff --git a/backend/src/data/GuildRoleButtons.ts b/backend/src/data/GuildRoleButtons.ts index 106e0055..833fb775 100644 --- a/backend/src/data/GuildRoleButtons.ts +++ b/backend/src/data/GuildRoleButtons.ts @@ -1,11 +1,5 @@ import { getRepository, Repository } from "typeorm"; -import { Reminder } from "./entities/Reminder"; -import { BaseRepository } from "./BaseRepository"; -import moment from "moment-timezone"; -import { DBDateFormat } from "../utils"; import { BaseGuildRepository } from "./BaseGuildRepository"; -import { RoleQueueItem } from "./entities/RoleQueueItem"; -import { connection } from "./db"; import { RoleButtonsItem } from "./entities/RoleButtonsItem"; export class GuildRoleButtons extends BaseGuildRepository { diff --git a/backend/src/data/GuildRoleQueue.ts b/backend/src/data/GuildRoleQueue.ts index 20d84012..bad25a73 100644 --- a/backend/src/data/GuildRoleQueue.ts +++ b/backend/src/data/GuildRoleQueue.ts @@ -1,8 +1,4 @@ import { getRepository, Repository } from "typeorm"; -import { Reminder } from "./entities/Reminder"; -import { BaseRepository } from "./BaseRepository"; -import moment from "moment-timezone"; -import { DBDateFormat } from "../utils"; import { BaseGuildRepository } from "./BaseGuildRepository"; import { RoleQueueItem } from "./entities/RoleQueueItem"; import { connection } from "./db"; diff --git a/backend/src/data/GuildSavedMessages.ts b/backend/src/data/GuildSavedMessages.ts index a8724938..06b9d7d2 100644 --- a/backend/src/data/GuildSavedMessages.ts +++ b/backend/src/data/GuildSavedMessages.ts @@ -1,13 +1,11 @@ import { GuildChannel, Message } from "discord.js"; import moment from "moment-timezone"; import { getRepository, Repository } from "typeorm"; -import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity"; import { QueuedEventEmitter } from "../QueuedEventEmitter"; import { BaseGuildRepository } from "./BaseGuildRepository"; import { ISavedMessageData, SavedMessage } from "./entities/SavedMessage"; import { buildEntity } from "./buildEntity"; import { noop } from "../utils"; -import { decrypt } from "../utils/crypt"; import { decryptJson, encryptJson } from "../utils/cryptHelpers"; import { asyncMap } from "../utils/async"; diff --git a/backend/src/data/Mutes.ts b/backend/src/data/Mutes.ts index 5734f334..e8c5fefc 100644 --- a/backend/src/data/Mutes.ts +++ b/backend/src/data/Mutes.ts @@ -1,5 +1,5 @@ import moment from "moment-timezone"; -import { Brackets, getRepository, Repository } from "typeorm"; +import { getRepository, Repository } from "typeorm"; import { Mute } from "./entities/Mute"; import { DAYS, DBDateFormat } from "../utils"; import { BaseRepository } from "./BaseRepository"; diff --git a/backend/src/data/entities/ApiAuditLogEntry.ts b/backend/src/data/entities/ApiAuditLogEntry.ts index 0491c313..6c142bd8 100644 --- a/backend/src/data/entities/ApiAuditLogEntry.ts +++ b/backend/src/data/entities/ApiAuditLogEntry.ts @@ -1,5 +1,4 @@ -import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm"; -import { ApiUserInfo } from "./ApiUserInfo"; +import { Column, Entity, PrimaryColumn } from "typeorm"; import { AuditLogEventData, AuditLogEventType } from "../apiAuditLogTypes"; @Entity("api_audit_log") diff --git a/backend/src/data/entities/CounterTrigger.ts b/backend/src/data/entities/CounterTrigger.ts index 91cbf995..90cdf488 100644 --- a/backend/src/data/entities/CounterTrigger.ts +++ b/backend/src/data/entities/CounterTrigger.ts @@ -2,7 +2,7 @@ import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; export const TRIGGER_COMPARISON_OPS = ["=", "!=", ">", "<", ">=", "<="] as const; -export type TriggerComparisonOp = typeof TRIGGER_COMPARISON_OPS[number]; +export type TriggerComparisonOp = (typeof TRIGGER_COMPARISON_OPS)[number]; const REVERSE_OPS: Record = { "=": "!=", diff --git a/backend/src/data/entities/Reminder.ts b/backend/src/data/entities/Reminder.ts index e7ce506b..e876efd7 100644 --- a/backend/src/data/entities/Reminder.ts +++ b/backend/src/data/entities/Reminder.ts @@ -1,4 +1,4 @@ -import { Column, Entity, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; @Entity("reminders") export class Reminder { diff --git a/backend/src/data/entities/ScheduledPost.ts b/backend/src/data/entities/ScheduledPost.ts index c4b31c52..45ba547e 100644 --- a/backend/src/data/entities/ScheduledPost.ts +++ b/backend/src/data/entities/ScheduledPost.ts @@ -1,5 +1,5 @@ import { Attachment } from "discord.js"; -import { Column, Entity, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; import { StrictMessageContent } from "../../utils"; @Entity("scheduled_posts") diff --git a/backend/src/data/entities/VCAlert.ts b/backend/src/data/entities/VCAlert.ts index 5f0011d7..d82ae033 100644 --- a/backend/src/data/entities/VCAlert.ts +++ b/backend/src/data/entities/VCAlert.ts @@ -1,4 +1,4 @@ -import { Column, Entity, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm"; +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; @Entity("vc_alerts") export class VCAlert { diff --git a/backend/src/data/loops/expiredArchiveDeletionLoop.ts b/backend/src/data/loops/expiredArchiveDeletionLoop.ts index 7aa794ed..be39ab27 100644 --- a/backend/src/data/loops/expiredArchiveDeletionLoop.ts +++ b/backend/src/data/loops/expiredArchiveDeletionLoop.ts @@ -2,7 +2,6 @@ import { lazyMemoize, MINUTES } from "../../utils"; import { Archives } from "../Archives"; -import moment from "moment-timezone"; const LOOP_INTERVAL = 15 * MINUTES; const getArchivesRepository = lazyMemoize(() => new Archives()); diff --git a/backend/src/data/loops/expiringMutesLoop.ts b/backend/src/data/loops/expiringMutesLoop.ts index 027a3ac9..9d291745 100644 --- a/backend/src/data/loops/expiringMutesLoop.ts +++ b/backend/src/data/loops/expiringMutesLoop.ts @@ -1,6 +1,6 @@ // tslint:disable:no-console -import { lazyMemoize, memoize, MINUTES } from "../../utils"; +import { lazyMemoize, MINUTES } from "../../utils"; import { Mutes } from "../Mutes"; import Timeout = NodeJS.Timeout; import moment from "moment-timezone"; diff --git a/backend/src/data/loops/phishermanLoops.ts b/backend/src/data/loops/phishermanLoops.ts index 1ed9a2d2..6ab89488 100644 --- a/backend/src/data/loops/phishermanLoops.ts +++ b/backend/src/data/loops/phishermanLoops.ts @@ -1,6 +1,6 @@ // tslint:disable:no-console -import { HOURS, MINUTES } from "../../utils"; +import { MINUTES } from "../../utils"; import { deleteStalePhishermanCacheEntries, deleteStalePhishermanKeyCacheEntries, diff --git a/backend/src/index.ts b/backend/src/index.ts index 31b2c0a8..966df980 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,4 +1,16 @@ -import { Client, Constants, Intents, Options, TextChannel, ThreadChannel } from "discord.js"; +import { + Client, + Events, + GatewayIntentBits, + GuildTextBasedChannel, + Message, + Options, + Partials, + RESTEvents, + TextBasedChannel, + TextChannel, + ThreadChannel, +} from "discord.js"; import { Knub, PluginError } from "knub"; import { PluginLoadError } from "knub/dist/plugins/PluginLoadError"; // Always use UTC internally @@ -14,13 +26,11 @@ import { logger } from "./logger"; import { baseGuildPlugins, globalPlugins, guildPlugins } from "./plugins/availablePlugins"; import { RecoverablePluginError } from "./RecoverablePluginError"; import { SimpleError } from "./SimpleError"; -import { ZeppelinGlobalConfig, ZeppelinGuildConfig } from "./types"; import { startUptimeCounter } from "./uptime"; import { errorMessage, isDiscordAPIError, isDiscordHTTPError, MINUTES, SECONDS, sleep, successMessage } from "./utils"; import { loadYamlSafely } from "./utils/loadYamlSafely"; import { DecayingCounter } from "./utils/DecayingCounter"; import { PluginNotLoadedError } from "knub/dist/plugins/PluginNotLoadedError"; -import { logRestCall } from "./restCallStats"; import { logRateLimit } from "./rateLimitStats"; import { runExpiringMutesLoop } from "./data/loops/expiringMutesLoop"; import { runUpcomingRemindersLoop } from "./data/loops/upcomingRemindersLoop"; @@ -37,6 +47,19 @@ import { hasPhishermanMasterAPIKey } from "./data/Phisherman"; import { consumeQueryStats } from "./data/queryLogger"; import { EventEmitter } from "events"; import { env } from "./env"; +import { ZeppelinGlobalConfig, ZeppelinGuildConfig } from "./types"; + +// TODO: Remove this once fixed on upstream +declare module "knub/dist/helpers" { + export function waitForReply( + client: Client, + channel: GuildTextBasedChannel, + restrictToUserId?: string, + timeout?: number, + ): Promise; + + export function createChunkedMessage(channel: TextBasedChannel, messageText: string): Promise; +} // Error handling let recentPluginErrors = 0; @@ -188,17 +211,19 @@ setInterval(() => { logger.info("Connecting to database"); connect().then(async () => { const client = new Client({ - partials: ["USER", "CHANNEL", "GUILD_MEMBER", "MESSAGE", "REACTION"], + partials: [Partials.User, Partials.Channel, Partials.GuildMember, Partials.Message, Partials.Reaction], makeCache: Options.cacheWithLimits({ - ...Options.defaultMakeCacheSettings, + ...Options.DefaultMakeCacheSettings, MessageManager: 1, // GuildMemberManager: 15000, GuildInviteManager: 0, }), - restGlobalRateLimit: 50, - // restTimeOffset: 1000, + rest: { + // globalRequestsPerSecond: 50, + // offset: 1000, + }, // Disable mentions by default allowedMentions: { @@ -209,25 +234,25 @@ connect().then(async () => { }, intents: [ // Privileged - Intents.FLAGS.GUILD_MEMBERS, - // Intents.FLAGS.GUILD_PRESENCES, - Intents.FLAGS.GUILD_MESSAGE_TYPING, + GatewayIntentBits.GuildMembers, + // GatewayIntentBits.GuildPresences, // Regular - Intents.FLAGS.DIRECT_MESSAGES, - Intents.FLAGS.GUILD_BANS, - Intents.FLAGS.GUILD_EMOJIS_AND_STICKERS, - Intents.FLAGS.GUILD_INVITES, - Intents.FLAGS.GUILD_MESSAGE_REACTIONS, - Intents.FLAGS.GUILD_MESSAGES, - Intents.FLAGS.GUILDS, - Intents.FLAGS.GUILD_VOICE_STATES, + GatewayIntentBits.GuildMessageTyping, + GatewayIntentBits.DirectMessages, + GatewayIntentBits.GuildModeration, + GatewayIntentBits.GuildEmojisAndStickers, + GatewayIntentBits.GuildInvites, + GatewayIntentBits.GuildMessageReactions, + GatewayIntentBits.GuildMessages, + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildVoiceStates, ], }); // FIXME: TS doesn't see Client as a child of EventEmitter for some reason (client as unknown as EventEmitter).setMaxListeners(200); - client.on(Constants.Events.RATE_LIMIT, (data) => { + client.rest.on(RESTEvents.RateLimited, (data) => { // tslint:disable-next-line:no-console // console.log(`[DEBUG] [RATE_LIMIT] ${JSON.stringify(data)}`); }); @@ -235,7 +260,7 @@ connect().then(async () => { const safe429DecayInterval = 5 * SECONDS; const safe429MaxCount = 5; const safe429Counter = new DecayingCounter(safe429DecayInterval); - client.on(Constants.Events.DEBUG, (errorText) => { + client.on(Events.Debug, (errorText) => { if (!errorText.includes("429")) { return; } @@ -346,7 +371,7 @@ connect().then(async () => { startUptimeCounter(); }); - client.on(Constants.Events.RATE_LIMIT, (data) => { + client.rest.on(RESTEvents.RateLimited, (data) => { logRateLimit(data); }); diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index 79e2eb94..175367c1 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -2,17 +2,7 @@ * @file Utility functions that are plugin-instance-specific (i.e. use PluginData) */ -import { - ChannelType, - GuildMember, - GuildTextBasedChannel, - Message, - MessageCreateOptions, - MessageMentionOptions, - MessagePayload, - TextBasedChannel, - TextChannel, -} from "discord.js"; +import { GuildMember, Message, MessageCreateOptions, MessageMentionOptions, TextBasedChannel } from "discord.js"; import * as t from "io-ts"; import { CommandContext, configUtils, ConfigValidationError, GuildPluginData, helpers, PluginOptions } from "knub"; import { PluginOverrideCriteria } from "knub/dist/config/configTypes"; @@ -198,7 +188,7 @@ export function getPluginConfigPreprocessor( export async function sendSuccessMessage( pluginData: AnyPluginData, - channel: GuildTextBasedChannel, + channel: TextBasedChannel, body: string, allowedMentions?: MessageMentionOptions, ): Promise { @@ -211,7 +201,7 @@ export async function sendSuccessMessage( return channel .send({ ...content }) // Force line break .catch((err) => { - const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : channel.id; + const channelInfo = "guild" in channel ? `${channel.id} (${channel.guild.id})` : channel.id; logger.warn(`Failed to send success message to ${channelInfo}): ${err.code} ${err.message}`); return undefined; }); @@ -232,7 +222,7 @@ export async function sendErrorMessage( return channel .send({ ...content }) // Force line break .catch((err) => { - const channelInfo = channel.guild ? `${channel.id} (${channel.guild.id})` : channel.id; + const channelInfo = "guild" in channel ? `${channel.id} (${channel.guild.id})` : channel.id; logger.warn(`Failed to send error message to ${channelInfo}): ${err.code} ${err.message}`); return undefined; }); diff --git a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts index e6851f0b..9432141e 100644 --- a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts +++ b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts @@ -1,7 +1,6 @@ -import { PermissionsBitField, Snowflake, TextChannel } from "discord.js"; +import { PermissionsBitField, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { resolveUser, verboseChannelMention } from "../../../utils"; @@ -47,7 +46,7 @@ export async function deleteNextItem(pluginData: GuildPluginData { + channel.messages.delete(itemToDelete.message.id as Snowflake).catch((err) => { if (err.code === 10008) { // "Unknown Message", probably already deleted by automod or another bot, ignore return; diff --git a/backend/src/plugins/AutoDelete/util/onMessageCreate.ts b/backend/src/plugins/AutoDelete/util/onMessageCreate.ts index 1fb07295..fad3e8ea 100644 --- a/backend/src/plugins/AutoDelete/util/onMessageCreate.ts +++ b/backend/src/plugins/AutoDelete/util/onMessageCreate.ts @@ -1,6 +1,5 @@ import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { LogType } from "../../../data/LogType"; import { convertDelayStringToMS, resolveMember } from "../../../utils"; import { AutoDeletePluginType, MAX_DELAY } from "../types"; import { addMessageToDeletionQueue } from "./addMessageToDeletionQueue"; diff --git a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts index 538e92bf..a64cb95c 100644 --- a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts @@ -1,4 +1,4 @@ -import { GuildChannel, PermissionsBitField } from "discord.js"; +import { PermissionsBitField } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { canUseEmoji, customEmojiRegex, isEmoji } from "../../../utils"; diff --git a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts index 25f9fc39..157160cb 100644 --- a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts +++ b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts @@ -1,5 +1,4 @@ -import { GuildChannel, GuildTextBasedChannel, PermissionsBitField } from "discord.js"; -import { LogType } from "../../../data/LogType"; +import { GuildTextBasedChannel, PermissionsBitField } from "discord.js"; import { isDiscordAPIError } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; diff --git a/backend/src/plugins/Automod/actions/addRoles.ts b/backend/src/plugins/Automod/actions/addRoles.ts index c2311102..ce2f02d9 100644 --- a/backend/src/plugins/Automod/actions/addRoles.ts +++ b/backend/src/plugins/Automod/actions/addRoles.ts @@ -1,6 +1,5 @@ -import { PermissionsBitField, Snowflake } from "discord.js"; +import { PermissionFlagsBits, Snowflake } from "discord.js"; import * as t from "io-ts"; -import { LogType } from "../../../data/LogType"; import { nonNullish, unique } from "../../../utils"; import { canAssignRole } from "../../../utils/canAssignRole"; import { getMissingPermissions } from "../../../utils/getMissingPermissions"; @@ -10,7 +9,7 @@ import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ignoreRoleChange } from "../functions/ignoredRoleChanges"; import { automodAction } from "../helpers"; -const p = PermissionsBitField.Flags; +const p = PermissionFlagsBits; export const AddRolesAction = automodAction({ configType: t.array(t.string), diff --git a/backend/src/plugins/Automod/actions/addToCounter.ts b/backend/src/plugins/Automod/actions/addToCounter.ts index 04d73f83..7e7f4ac8 100644 --- a/backend/src/plugins/Automod/actions/addToCounter.ts +++ b/backend/src/plugins/Automod/actions/addToCounter.ts @@ -1,5 +1,4 @@ import * as t from "io-ts"; -import { LogType } from "../../../data/LogType"; import { CountersPlugin } from "../../Counters/CountersPlugin"; import { automodAction } from "../helpers"; import { LogsPlugin } from "../../Logs/LogsPlugin"; diff --git a/backend/src/plugins/Automod/actions/alert.ts b/backend/src/plugins/Automod/actions/alert.ts index a1defe71..706552b2 100644 --- a/backend/src/plugins/Automod/actions/alert.ts +++ b/backend/src/plugins/Automod/actions/alert.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel, ThreadChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import * as t from "io-ts"; import { erisAllowedMentionsToDjsMentionOptions } from "src/utils/erisAllowedMentionsToDjsMentionOptions"; import { LogType } from "../../../data/LogType"; @@ -9,9 +9,7 @@ import { TemplateSafeValueContainer, } from "../../../templateFormatter"; import { - createChunkedMessage, messageLink, - stripObjectToScalars, tAllowedMentions, tNormalizedNullOptional, isTruthy, @@ -21,7 +19,7 @@ import { } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { automodAction } from "../helpers"; -import { TemplateSafeUser, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { messageIsEmpty } from "../../../utils/messageIsEmpty"; import { InternalPosterPlugin } from "../../InternalPoster/InternalPosterPlugin"; @@ -96,7 +94,7 @@ export const AlertAction = automodAction({ const chunks = chunkMessageLines(rendered); for (const chunk of chunks) { await poster.sendMessage(channel, { - content: rendered, + content: chunk, allowedMentions: erisAllowedMentionsToDjsMentionOptions(actionConfig.allowed_mentions), }); } diff --git a/backend/src/plugins/Automod/actions/archiveThread.ts b/backend/src/plugins/Automod/actions/archiveThread.ts index 6fe871a5..d94afdf7 100644 --- a/backend/src/plugins/Automod/actions/archiveThread.ts +++ b/backend/src/plugins/Automod/actions/archiveThread.ts @@ -1,4 +1,4 @@ -import { ThreadChannel } from "discord.js"; +import { AnyThreadChannel } from "discord.js"; import * as t from "io-ts"; import { noop } from "../../../utils"; import { automodAction } from "../helpers"; @@ -11,7 +11,7 @@ export const ArchiveThreadAction = automodAction({ const threads = contexts .filter((c) => c.message?.channel_id) .map((c) => pluginData.guild.channels.cache.get(c.message!.channel_id)) - .filter((c): c is ThreadChannel => c?.isThread() ?? false); + .filter((c): c is AnyThreadChannel => c?.isThread() ?? false); for (const thread of threads) { await thread.setArchived().catch(noop); diff --git a/backend/src/plugins/Automod/actions/changeNickname.ts b/backend/src/plugins/Automod/actions/changeNickname.ts index 0a368355..9cd4790e 100644 --- a/backend/src/plugins/Automod/actions/changeNickname.ts +++ b/backend/src/plugins/Automod/actions/changeNickname.ts @@ -1,5 +1,4 @@ import * as t from "io-ts"; -import { LogType } from "../../../data/LogType"; import { nonNullish, unique } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { automodAction } from "../helpers"; diff --git a/backend/src/plugins/Automod/actions/clean.ts b/backend/src/plugins/Automod/actions/clean.ts index 83beba5c..91bf37ac 100644 --- a/backend/src/plugins/Automod/actions/clean.ts +++ b/backend/src/plugins/Automod/actions/clean.ts @@ -1,4 +1,4 @@ -import { GuildTextBasedChannel, Snowflake, TextChannel } from "discord.js"; +import { GuildTextBasedChannel, Snowflake } from "discord.js"; import * as t from "io-ts"; import { LogType } from "../../../data/LogType"; import { noop } from "../../../utils"; diff --git a/backend/src/plugins/Automod/actions/log.ts b/backend/src/plugins/Automod/actions/log.ts index 62f57a20..82075a2e 100644 --- a/backend/src/plugins/Automod/actions/log.ts +++ b/backend/src/plugins/Automod/actions/log.ts @@ -1,9 +1,7 @@ import * as t from "io-ts"; -import { LogType } from "../../../data/LogType"; -import { isTruthy, stripObjectToScalars, unique } from "../../../utils"; +import { isTruthy, unique } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { automodAction } from "../helpers"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; export const LogAction = automodAction({ configType: t.boolean, diff --git a/backend/src/plugins/Automod/actions/mute.ts b/backend/src/plugins/Automod/actions/mute.ts index a1bb9299..3219c712 100644 --- a/backend/src/plugins/Automod/actions/mute.ts +++ b/backend/src/plugins/Automod/actions/mute.ts @@ -1,5 +1,4 @@ import * as t from "io-ts"; -import { LogType } from "../../../data/LogType"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; import { convertDelayStringToMS, nonNullish, tDelayString, tNullable, unique } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; diff --git a/backend/src/plugins/Automod/actions/removeRoles.ts b/backend/src/plugins/Automod/actions/removeRoles.ts index 6c8c12aa..a46d8262 100644 --- a/backend/src/plugins/Automod/actions/removeRoles.ts +++ b/backend/src/plugins/Automod/actions/removeRoles.ts @@ -1,6 +1,5 @@ -import { PermissionsBitField, Snowflake } from "discord.js"; +import { PermissionFlagsBits, Snowflake } from "discord.js"; import * as t from "io-ts"; -import { LogType } from "../../../data/LogType"; import { nonNullish, unique } from "../../../utils"; import { canAssignRole } from "../../../utils/canAssignRole"; import { getMissingPermissions } from "../../../utils/getMissingPermissions"; @@ -10,7 +9,7 @@ import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ignoreRoleChange } from "../functions/ignoredRoleChanges"; import { automodAction } from "../helpers"; -const p = PermissionsBitField.Flags; +const p = PermissionFlagsBits; export const RemoveRolesAction = automodAction({ configType: t.array(t.string), diff --git a/backend/src/plugins/Automod/actions/reply.ts b/backend/src/plugins/Automod/actions/reply.ts index 6db970fb..b333614f 100644 --- a/backend/src/plugins/Automod/actions/reply.ts +++ b/backend/src/plugins/Automod/actions/reply.ts @@ -1,12 +1,4 @@ -import { - GuildTextBasedChannel, - MessageOptions, - PermissionsBitField, - Snowflake, - TextChannel, - ThreadChannel, - User, -} from "discord.js"; +import { GuildTextBasedChannel, MessageCreateOptions, PermissionsBitField, Snowflake, User } from "discord.js"; import * as t from "io-ts"; import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter"; @@ -71,7 +63,7 @@ export const ReplyAction = automodAction({ const formatted = typeof actionConfig === "string" ? await renderReplyText(actionConfig) - : ((await renderRecursively(actionConfig.text, renderReplyText)) as MessageOptions); + : ((await renderRecursively(actionConfig.text, renderReplyText)) as MessageCreateOptions); if (formatted) { const channel = pluginData.guild.channels.cache.get(channelId as Snowflake) as GuildTextBasedChannel; @@ -107,7 +99,7 @@ export const ReplyAction = automodAction({ const messageContent = validateAndParseMessageContent(formatted); - const messageOpts: MessageOptions = { + const messageOpts: MessageCreateOptions = { ...messageContent, allowedMentions: { users: [user.id], diff --git a/backend/src/plugins/Automod/actions/setCounter.ts b/backend/src/plugins/Automod/actions/setCounter.ts index 5be82cf6..5206e579 100644 --- a/backend/src/plugins/Automod/actions/setCounter.ts +++ b/backend/src/plugins/Automod/actions/setCounter.ts @@ -1,5 +1,4 @@ import * as t from "io-ts"; -import { LogType } from "../../../data/LogType"; import { CountersPlugin } from "../../Counters/CountersPlugin"; import { automodAction } from "../helpers"; import { LogsPlugin } from "../../Logs/LogsPlugin"; diff --git a/backend/src/plugins/Automod/actions/setSlowmode.ts b/backend/src/plugins/Automod/actions/setSlowmode.ts index 4c3cc135..fc404a60 100644 --- a/backend/src/plugins/Automod/actions/setSlowmode.ts +++ b/backend/src/plugins/Automod/actions/setSlowmode.ts @@ -1,6 +1,5 @@ -import { ChannelType, GuildTextBasedChannel, Snowflake, TextChannel } from "discord.js"; +import { ChannelType, GuildTextBasedChannel, Snowflake } from "discord.js"; import * as t from "io-ts"; -import { LogType } from "../../../data/LogType"; import { convertDelayStringToMS, isDiscordAPIError, tDelayString, tNullable } from "../../../utils"; import { automodAction } from "../helpers"; import { LogsPlugin } from "../../Logs/LogsPlugin"; @@ -42,9 +41,7 @@ export const SetSlowmodeAction = automodAction({ try { for (const chan of channelsToSlowmode) { - await chan.edit({ - rateLimitPerUser: slowmodeSeconds, - }); + await chan.setRateLimitPerUser(slowmodeSeconds); } } catch (e) { // Check for invalid form body -> indicates duration was too large diff --git a/backend/src/plugins/Automod/actions/startThread.ts b/backend/src/plugins/Automod/actions/startThread.ts index 2ab89361..cb2741b7 100644 --- a/backend/src/plugins/Automod/actions/startThread.ts +++ b/backend/src/plugins/Automod/actions/startThread.ts @@ -1,5 +1,4 @@ -import { GuildFeature, ThreadAutoArchiveDuration } from "discord-api-types/v9"; -import { BaseGuildTextChannel, ChannelType, GuildTextBasedChannel, TextChannel } from "discord.js"; +import { ChannelType, GuildFeature, ThreadAutoArchiveDuration } from "discord.js"; import * as t from "io-ts"; import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter"; import { convertDelayStringToMS, MINUTES, noop, tDelayString, tNullable } from "../../../utils"; @@ -35,8 +34,7 @@ export const StartThreadAction = automodAction({ // check against max threads per channel if (actionConfig.limit_per_channel && actionConfig.limit_per_channel > 0) { const threadCount = channel.threads.cache.filter( - (tr) => - tr.ownerId === pluginData.client.user!.id && !tr.deleted && !tr.archived && tr.parentId === channel.id, + (tr) => tr.ownerId === pluginData.client.user!.id && !tr.archived && tr.parentId === channel.id, ).size; if (threadCount >= actionConfig.limit_per_channel) return false; } @@ -52,7 +50,9 @@ export const StartThreadAction = automodAction({ : ThreadAutoArchiveDuration.OneHour; for (const threadContext of threads) { - const channel = pluginData.guild.channels.cache.get(threadContext.message!.channel_id) as BaseGuildTextChannel; + const channel = pluginData.guild.channels.cache.get(threadContext.message!.channel_id); + if (!channel || !("threads" in channel)) continue; + const renderThreadName = async (str: string) => renderTemplate( str, @@ -62,7 +62,7 @@ export const StartThreadAction = automodAction({ }), ); const threadName = await renderThreadName(actionConfig.name ?? "{user.tag}s thread"); - const thread = await channel!.threads + const thread = await channel.threads .create({ name: threadName, autoArchiveDuration: autoArchive, diff --git a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts index 4b595036..dc9bab2e 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts @@ -1,4 +1,3 @@ -import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { SavedMessage } from "../../../data/entities/SavedMessage"; diff --git a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts index 24965dca..3d7e993f 100644 --- a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts +++ b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts @@ -1,4 +1,4 @@ -import { ActivityType, Snowflake, TextChannel } from "discord.js"; +import { ActivityType, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { messageSummary, verboseChannelMention } from "../../../utils"; import { AutomodContext, AutomodPluginType } from "../types"; diff --git a/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts b/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts index 08492589..f084bfa0 100644 --- a/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts +++ b/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts @@ -1,8 +1,9 @@ -import { Constants, MessageEmbed } from "discord.js"; +import { ActivityType, Embed } from "discord.js"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { resolveMember } from "../../../utils"; import { AutomodPluginType } from "../types"; +import { DeepMutable } from "../../../utils/typeUtils.js"; type TextTriggerWithMultipleMatchTypes = { match_messages: boolean; @@ -33,7 +34,7 @@ export async function* matchMultipleTextTypesOnMessage( } if (trigger.match_embeds && msg.data.embeds?.length) { - const copiedEmbed: MessageEmbed = JSON.parse(JSON.stringify(msg.data.embeds[0])); + const copiedEmbed: DeepMutable = JSON.parse(JSON.stringify(msg.data.embeds[0])); if (copiedEmbed.video) { copiedEmbed.description = ""; // The description is not rendered, hence it doesn't need to be matched } @@ -53,7 +54,7 @@ export async function* matchMultipleTextTypesOnMessage( } for (const activity of member.presence?.activities ?? []) { - if (activity.type === Constants.ActivityTypes[4]) { + if (activity.type === ActivityType.Custom) { yield ["customstatus", `${activity.emoji} ${activity.name}`]; break; } diff --git a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts index 36a31ec1..d26c318b 100644 --- a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts +++ b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel, ThreadChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils"; diff --git a/backend/src/plugins/Automod/functions/runAutomod.ts b/backend/src/plugins/Automod/functions/runAutomod.ts index a711fa09..d13fe678 100644 --- a/backend/src/plugins/Automod/functions/runAutomod.ts +++ b/backend/src/plugins/Automod/functions/runAutomod.ts @@ -1,4 +1,4 @@ -import { GuildTextBasedChannel, Snowflake, TextChannel, ThreadChannel } from "discord.js"; +import { GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { availableActions } from "../actions/availableActions"; import { CleanAction } from "../actions/clean"; diff --git a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts index c77cb414..a21d58b0 100644 --- a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts +++ b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts @@ -1,7 +1,5 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogType } from "../../../data/LogType"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { runAutomodOnAntiraidLevel } from "../events/runAutomodOnAntiraidLevel"; import { AutomodPluginType } from "../types"; diff --git a/backend/src/plugins/Automod/triggers/anyMessage.ts b/backend/src/plugins/Automod/triggers/anyMessage.ts index 2599f9d1..8ed6eedc 100644 --- a/backend/src/plugins/Automod/triggers/anyMessage.ts +++ b/backend/src/plugins/Automod/triggers/anyMessage.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import * as t from "io-ts"; import { verboseChannelMention } from "../../../utils"; import { automodTrigger } from "../helpers"; diff --git a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts index 57a7f9ff..8328caef 100644 --- a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts +++ b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts @@ -1,4 +1,4 @@ -import { escapeInlineCode, Snowflake, TextChannel } from "discord.js"; +import { escapeInlineCode, Snowflake } from "discord.js"; import * as t from "io-ts"; import { asSingleLine, messageSummary, verboseChannelMention } from "../../../utils"; import { automodTrigger } from "../helpers"; @@ -66,7 +66,7 @@ export const MatchAttachmentTypeTrigger = automodTrigger()({ }, renderMatchInformation({ pluginData, contexts, matchResult }) { - const channel = pluginData.guild.channels.cache.get(contexts[0].message!.channel_id as Snowflake); + const channel = pluginData.guild.channels.cache.get(contexts[0].message!.channel_id as Snowflake)!; const prettyChannel = verboseChannelMention(channel); return ( diff --git a/backend/src/plugins/Automod/triggers/matchLinks.ts b/backend/src/plugins/Automod/triggers/matchLinks.ts index f1270e7c..068e64da 100644 --- a/backend/src/plugins/Automod/triggers/matchLinks.ts +++ b/backend/src/plugins/Automod/triggers/matchLinks.ts @@ -1,4 +1,3 @@ -import escapeStringRegexp from "escape-string-regexp"; import * as t from "io-ts"; import { allowTimeout } from "../../../RegExpRunner"; import { getUrlsInString, tNullable } from "../../../utils"; diff --git a/backend/src/plugins/Automod/triggers/matchMimeType.ts b/backend/src/plugins/Automod/triggers/matchMimeType.ts index 6af0d381..23251a7e 100644 --- a/backend/src/plugins/Automod/triggers/matchMimeType.ts +++ b/backend/src/plugins/Automod/triggers/matchMimeType.ts @@ -1,7 +1,7 @@ import { automodTrigger } from "../helpers"; import * as t from "io-ts"; import { asSingleLine, messageSummary, verboseChannelMention } from "../../../utils"; -import { escapeInlineCode, GuildChannel } from "discord.js"; +import { escapeInlineCode } from "discord.js"; interface MatchResultType { matchedType: string; @@ -65,8 +65,8 @@ export const MatchMimeTypeTrigger = automodTrigger()({ renderMatchInformation({ pluginData, contexts, matchResult }) { const { message } = contexts[0]; - const channel = pluginData.guild.channels.resolve(message!.channel_id); - const prettyChannel = verboseChannelMention(channel as GuildChannel); + const channel = pluginData.guild.channels.resolve(message!.channel_id)!; + const prettyChannel = verboseChannelMention(channel); const { matchedType, mode } = matchResult.extra; return ( diff --git a/backend/src/plugins/Automod/triggers/threadArchive.ts b/backend/src/plugins/Automod/triggers/threadArchive.ts index 3e2d852f..6177983e 100644 --- a/backend/src/plugins/Automod/triggers/threadArchive.ts +++ b/backend/src/plugins/Automod/triggers/threadArchive.ts @@ -1,5 +1,4 @@ -import { Snowflake } from "discord-api-types/v9"; -import { escapeBold, User } from "discord.js"; +import { escapeBold, User, type Snowflake } from "discord.js"; import * as t from "io-ts"; import { tNullable } from "../../../utils"; import { automodTrigger } from "../helpers"; diff --git a/backend/src/plugins/Automod/triggers/threadCreate.ts b/backend/src/plugins/Automod/triggers/threadCreate.ts index 5c1b9ee0..640432c3 100644 --- a/backend/src/plugins/Automod/triggers/threadCreate.ts +++ b/backend/src/plugins/Automod/triggers/threadCreate.ts @@ -1,5 +1,4 @@ -import { Snowflake } from "discord-api-types/v9"; -import { escapeBold, User } from "discord.js"; +import { escapeBold, User, type Snowflake } from "discord.js"; import * as t from "io-ts"; import { automodTrigger } from "../helpers"; diff --git a/backend/src/plugins/Automod/triggers/threadDelete.ts b/backend/src/plugins/Automod/triggers/threadDelete.ts index 3e1fd2dc..25a93268 100644 --- a/backend/src/plugins/Automod/triggers/threadDelete.ts +++ b/backend/src/plugins/Automod/triggers/threadDelete.ts @@ -1,5 +1,4 @@ -import { Snowflake } from "discord-api-types/v9"; -import { escapeBold, User } from "discord.js"; +import { escapeBold, User, type Snowflake } from "discord.js"; import * as t from "io-ts"; import { automodTrigger } from "../helpers"; diff --git a/backend/src/plugins/Automod/triggers/threadUnarchive.ts b/backend/src/plugins/Automod/triggers/threadUnarchive.ts index e50e8186..897f685e 100644 --- a/backend/src/plugins/Automod/triggers/threadUnarchive.ts +++ b/backend/src/plugins/Automod/triggers/threadUnarchive.ts @@ -1,5 +1,4 @@ -import { Snowflake } from "discord-api-types/v9"; -import { escapeBold, User } from "discord.js"; +import { escapeBold, User, type Snowflake } from "discord.js"; import * as t from "io-ts"; import { tNullable } from "../../../utils"; import { automodTrigger } from "../helpers"; diff --git a/backend/src/plugins/Automod/types.ts b/backend/src/plugins/Automod/types.ts index 130a885a..0711d76b 100644 --- a/backend/src/plugins/Automod/types.ts +++ b/backend/src/plugins/Automod/types.ts @@ -1,4 +1,4 @@ -import { GuildMember, GuildTextBasedChannel, PartialGuildMember, TextChannel, ThreadChannel, User } from "discord.js"; +import { GuildMember, GuildTextBasedChannel, PartialGuildMember, ThreadChannel, User } from "discord.js"; import * as t from "io-ts"; import { BasePluginType, CooldownManager } from "knub"; import { SavedMessage } from "../../data/entities/SavedMessage"; diff --git a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts index b8f6d720..4ac812a7 100644 --- a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts @@ -1,5 +1,4 @@ import { ApiPermissions } from "@shared/apiPermissions"; -import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { botControlCmd } from "../types"; @@ -38,7 +37,7 @@ export const AddDashboardUserCmd = botControlCmd({ const userNameList = args.users.map((user) => `<@!${user.id}> (**${user.tag}**, \`${user.id}\`)`); sendSuccessMessage( pluginData, - msg.channel as TextChannel, + msg.channel, `The following users were given dashboard access for **${guild.name}**:\n\n${userNameList}`, ); }, diff --git a/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts b/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts index 1f29e822..e46dd5dc 100644 --- a/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts @@ -1,8 +1,7 @@ import { ApiPermissions } from "@shared/apiPermissions"; -import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { DBDateFormat, isGuildInvite, isSnowflake, resolveInvite } from "../../../utils"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { DBDateFormat, isGuildInvite, resolveInvite } from "../../../utils"; import { botControlCmd } from "../types"; import moment from "moment-timezone"; import { isEligible } from "../functions/isEligible"; @@ -19,23 +18,19 @@ export const AddServerFromInviteCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const invite = await resolveInvite(pluginData.client, args.inviteCode, true); if (!invite || !isGuildInvite(invite)) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not resolve invite"); // :D + sendErrorMessage(pluginData, msg.channel, "Could not resolve invite"); // :D return; } const existing = await pluginData.state.allowedGuilds.find(invite.guild.id); if (existing) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Server is already allowed!"); + sendErrorMessage(pluginData, msg.channel, "Server is already allowed!"); return; } const { result, explanation } = await isEligible(pluginData, args.user, invite); if (!result) { - sendErrorMessage( - pluginData, - msg.channel as TextChannel, - `Could not add server because it's not eligible: ${explanation}`, - ); + sendErrorMessage(pluginData, msg.channel, `Could not add server because it's not eligible: ${explanation}`); return; } @@ -56,10 +51,6 @@ export const AddServerFromInviteCmd = botControlCmd({ ); } - sendSuccessMessage( - pluginData, - msg.channel as TextChannel, - "Server was eligible and is now allowed to use Zeppelin!", - ); + sendSuccessMessage(pluginData, msg.channel, "Server was eligible and is now allowed to use Zeppelin!"); }, }); diff --git a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts index 1aa665b5..b19e44c8 100644 --- a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts @@ -1,5 +1,4 @@ import { ApiPermissions } from "@shared/apiPermissions"; -import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { DBDateFormat, isSnowflake } from "../../../utils"; @@ -21,17 +20,17 @@ export const AllowServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const existing = await pluginData.state.allowedGuilds.find(args.guildId); if (existing) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Server is already allowed!"); + sendErrorMessage(pluginData, msg.channel, "Server is already allowed!"); return; } if (!isSnowflake(args.guildId)) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Invalid server ID!"); + sendErrorMessage(pluginData, msg.channel, "Invalid server ID!"); return; } if (args.userId && !isSnowflake(args.userId)) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Invalid user ID!"); + sendErrorMessage(pluginData, msg.channel, "Invalid user ID!"); return; } @@ -52,6 +51,6 @@ export const AllowServerCmd = botControlCmd({ ); } - sendSuccessMessage(pluginData, msg.channel as TextChannel, "Server is now allowed to use Zeppelin!"); + sendSuccessMessage(pluginData, msg.channel, "Server is now allowed to use Zeppelin!"); }, }); diff --git a/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts b/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts index 49f0ff73..11d3a487 100644 --- a/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts @@ -1,9 +1,6 @@ -import { Guild, GuildChannel, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { GuildInvite, isGuildInvite, resolveInvite, verboseUserMention } from "../../../utils"; +import { isStaffPreFilter, sendErrorMessage } from "../../../pluginUtils"; import { botControlCmd } from "../types"; -import { isEligible } from "../functions/isEligible"; export const ChannelToServerCmd = botControlCmd({ trigger: ["channel_to_server", "channel2server"], @@ -19,13 +16,13 @@ export const ChannelToServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const channel = pluginData.client.channels.cache.get(args.channelId); if (!channel) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Channel not found in cache!"); + sendErrorMessage(pluginData, msg.channel, "Channel not found in cache!"); return; } - const channelName = channel.isVoice() ? channel.name : `#${(channel as TextChannel).name}`; + const channelName = channel.isVoiceBased() ? channel.name : `#${"name" in channel ? channel.name : channel.id}`; - const guild: Guild | null = (channel as GuildChannel).guild ?? null; + const guild = "guild" in channel ? channel.guild : null; const guildInfo = guild ? `${guild.name} (\`${guild.id}\`)` : "Not a server"; msg.channel.send(`**Channel:** ${channelName} (\`${channel.type}\`) (<#${channel.id}>)\n**Server:** ${guildInfo}`); diff --git a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts index c7067341..06bc1b14 100644 --- a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { noop } from "../../../utils"; @@ -18,7 +18,7 @@ export const DisallowServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const existing = await pluginData.state.allowedGuilds.find(args.guildId); if (!existing) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "That server is not allowed in the first place!"); + sendErrorMessage(pluginData, msg.channel, "That server is not allowed in the first place!"); return; } @@ -27,6 +27,6 @@ export const DisallowServerCmd = botControlCmd({ .get(args.guildId as Snowflake) ?.leave() .catch(noop); - sendSuccessMessage(pluginData, msg.channel as TextChannel, "Server removed!"); + sendSuccessMessage(pluginData, msg.channel, "Server removed!"); }, }); diff --git a/backend/src/plugins/BotControl/commands/EligibleCmd.ts b/backend/src/plugins/BotControl/commands/EligibleCmd.ts index 0be29978..969b4a11 100644 --- a/backend/src/plugins/BotControl/commands/EligibleCmd.ts +++ b/backend/src/plugins/BotControl/commands/EligibleCmd.ts @@ -1,7 +1,6 @@ -import { Guild, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { GuildInvite, isGuildInvite, resolveInvite, verboseUserMention } from "../../../utils"; +import { isGuildInvite, resolveInvite } from "../../../utils"; import { botControlCmd } from "../types"; import { isEligible } from "../functions/isEligible"; @@ -17,17 +16,17 @@ export const EligibleCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const invite = await resolveInvite(pluginData.client, args.inviteCode, true); if (!invite || !isGuildInvite(invite)) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not resolve invite"); + sendErrorMessage(pluginData, msg.channel, "Could not resolve invite"); return; } const { result, explanation } = await isEligible(pluginData, args.user, invite); if (result) { - sendSuccessMessage(pluginData, msg.channel as TextChannel, `Server is eligible: ${explanation}`); + sendSuccessMessage(pluginData, msg.channel, `Server is eligible: ${explanation}`); return; } - sendErrorMessage(pluginData, msg.channel as TextChannel, `Server is **NOT** eligible: ${explanation}`); + sendErrorMessage(pluginData, msg.channel, `Server is **NOT** eligible: ${explanation}`); }, }); diff --git a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts index 20d0b14b..14aaf833 100644 --- a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { botControlCmd } from "../types"; @@ -16,7 +16,7 @@ export const LeaveServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { if (!pluginData.client.guilds.cache.has(args.guildId as Snowflake)) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "I am not in that guild"); + sendErrorMessage(pluginData, msg.channel, "I am not in that guild"); return; } @@ -26,10 +26,10 @@ export const LeaveServerCmd = botControlCmd({ try { await pluginData.client.guilds.cache.get(args.guildId as Snowflake)?.leave(); } catch (e) { - sendErrorMessage(pluginData, msg.channel as TextChannel, `Failed to leave guild: ${e.message}`); + sendErrorMessage(pluginData, msg.channel, `Failed to leave guild: ${e.message}`); return; } - sendSuccessMessage(pluginData, msg.channel as TextChannel, `Left guild **${guildName}**`); + sendSuccessMessage(pluginData, msg.channel, `Left guild **${guildName}**`); }, }); diff --git a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts index 590522f1..6513276c 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts @@ -1,8 +1,7 @@ -import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { AllowedGuild } from "../../../data/entities/AllowedGuild"; import { ApiPermissionAssignment } from "../../../data/entities/ApiPermissionAssignment"; -import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { resolveUser } from "../../../utils"; import { botControlCmd } from "../types"; @@ -17,7 +16,7 @@ export const ListDashboardPermsCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { if (!args.user && !args.guildId) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Must specify at least guildId, user, or both."); + sendErrorMessage(pluginData, msg.channel, "Must specify at least guildId, user, or both."); return; } @@ -25,7 +24,7 @@ export const ListDashboardPermsCmd = botControlCmd({ if (args.guildId) { guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Server is not using Zeppelin"); + sendErrorMessage(pluginData, msg.channel, "Server is not using Zeppelin"); return; } } @@ -34,7 +33,7 @@ export const ListDashboardPermsCmd = botControlCmd({ if (args.user) { existingUserAssignment = await pluginData.state.apiPermissionAssignments.getByUserId(args.user.id); if (existingUserAssignment.length === 0) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "The user has no assigned permissions."); + sendErrorMessage(pluginData, msg.channel, "The user has no assigned permissions."); return; } } @@ -57,7 +56,7 @@ export const ListDashboardPermsCmd = botControlCmd({ if (finalMessage === "") { sendErrorMessage( pluginData, - msg.channel as TextChannel, + msg.channel, `The user ${userInfo} has no assigned permissions on the specified server.`, ); return; @@ -68,11 +67,7 @@ export const ListDashboardPermsCmd = botControlCmd({ const existingGuildAssignment = await pluginData.state.apiPermissionAssignments.getByGuildId(guild.id); if (existingGuildAssignment.length === 0) { - sendErrorMessage( - pluginData, - msg.channel as TextChannel, - `The server ${guildInfo} has no assigned permissions.`, - ); + sendErrorMessage(pluginData, msg.channel, `The server ${guildInfo} has no assigned permissions.`); return; } @@ -83,6 +78,6 @@ export const ListDashboardPermsCmd = botControlCmd({ } } - await sendSuccessMessage(pluginData, msg.channel as TextChannel, finalMessage.trim(), {}); + await sendSuccessMessage(pluginData, msg.channel, finalMessage.trim(), {}); }, }); diff --git a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts index 90fee6ff..2c53d27b 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts @@ -1,6 +1,5 @@ -import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { resolveUser } from "../../../utils"; import { botControlCmd } from "../types"; @@ -15,7 +14,7 @@ export const ListDashboardUsersCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Server is not using Zeppelin"); + sendErrorMessage(pluginData, msg.channel, "Server is not using Zeppelin"); return; } @@ -33,7 +32,7 @@ export const ListDashboardUsersCmd = botControlCmd({ sendSuccessMessage( pluginData, - msg.channel as TextChannel, + msg.channel, `The following users have dashboard access for **${guild.name}**:\n\n${userNameList.join("\n")}`, {}, ); diff --git a/backend/src/plugins/BotControl/commands/ProfilerDataCmd.ts b/backend/src/plugins/BotControl/commands/ProfilerDataCmd.ts index 1ddc9dc6..e162330a 100644 --- a/backend/src/plugins/BotControl/commands/ProfilerDataCmd.ts +++ b/backend/src/plugins/BotControl/commands/ProfilerDataCmd.ts @@ -1,7 +1,6 @@ -import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getBaseUrl, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { createChunkedMessage, formatNumber, resolveInvite, sorter, verboseUserMention } from "../../../utils"; +import { getBaseUrl } from "../../../pluginUtils"; +import { sorter } from "../../../utils"; import { botControlCmd } from "../types"; import { GuildArchives } from "../../../data/GuildArchives"; import moment from "moment-timezone"; diff --git a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts index ac355689..bdf2b153 100644 --- a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts +++ b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts @@ -2,8 +2,7 @@ import { botControlCmd } from "../types"; import { getRateLimitStats } from "../../../rateLimitStats"; import moment from "moment-timezone"; import { GuildArchives } from "../../../data/GuildArchives"; -import { getBaseUrl, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { TextChannel } from "discord.js"; +import { getBaseUrl, sendSuccessMessage } from "../../../pluginUtils"; export const RateLimitPerformanceCmd = botControlCmd({ trigger: ["rate_limit_performance"], @@ -14,7 +13,7 @@ export const RateLimitPerformanceCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const logItems = getRateLimitStats(); if (logItems.length === 0) { - sendSuccessMessage(pluginData, msg.channel as TextChannel, `No rate limits hit`); + sendSuccessMessage(pluginData, msg.channel, `No rate limits hit`); return; } @@ -25,7 +24,7 @@ export const RateLimitPerformanceCmd = botControlCmd({ if (item.data.global) items.push("GLOBAL"); items.push(item.data.method.toUpperCase()); items.push(item.data.route); - items.push(`stalled for ${item.data.timeout}ms`); + items.push(`stalled for ${item.data.timeToReset}ms`); items.push(`(max requests ${item.data.limit})`); return items.join(" "); }); diff --git a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts index 0cd4ec0b..4f59f8a2 100644 --- a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts @@ -1,5 +1,4 @@ -import { TextChannel } from "discord.js"; -import { isStaffPreFilter } from "../../../pluginUtils"; +import { isStaffPreFilter, sendErrorMessage } from "../../../pluginUtils"; import { getActiveReload, setActiveReload } from "../activeReload"; import { botControlCmd } from "../types"; @@ -13,7 +12,13 @@ export const ReloadGlobalPluginsCmd = botControlCmd({ async run({ pluginData, message }) { if (getActiveReload()) return; - setActiveReload((message.channel as TextChannel).guild?.id, message.channel.id); + const guildId = "guild" in message.channel ? message.channel.guild.id : null; + if (!guildId) { + sendErrorMessage(pluginData, message.channel, "This command can only be used in a server"); + return; + } + + setActiveReload(guildId, message.channel.id); await message.channel.send("Reloading global plugins..."); pluginData.getKnubInstance().reloadGlobalContext(); diff --git a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts index 645e4cf4..0440129b 100644 --- a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { botControlCmd } from "../types"; @@ -16,18 +16,18 @@ export const ReloadServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { if (!pluginData.client.guilds.cache.has(args.guildId as Snowflake)) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "I am not in that guild"); + sendErrorMessage(pluginData, msg.channel, "I am not in that guild"); return; } try { await pluginData.getKnubInstance().reloadGuild(args.guildId); } catch (e) { - sendErrorMessage(pluginData, msg.channel as TextChannel, `Failed to reload guild: ${e.message}`); + sendErrorMessage(pluginData, msg.channel, `Failed to reload guild: ${e.message}`); return; } const guild = await pluginData.client.guilds.fetch(args.guildId as Snowflake); - sendSuccessMessage(pluginData, msg.channel as TextChannel, `Reloaded guild **${guild?.name || "???"}**`); + sendSuccessMessage(pluginData, msg.channel, `Reloaded guild **${guild?.name || "???"}**`); }, }); diff --git a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts index d5dd674b..c3f0c0d7 100644 --- a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts @@ -1,4 +1,3 @@ -import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { botControlCmd } from "../types"; @@ -18,7 +17,7 @@ export const RemoveDashboardUserCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Server is not using Zeppelin"); + sendErrorMessage(pluginData, msg.channel, "Server is not using Zeppelin"); return; } @@ -37,7 +36,7 @@ export const RemoveDashboardUserCmd = botControlCmd({ const userNameList = args.users.map((user) => `<@!${user.id}> (**${user.tag}**, \`${user.id}\`)`); sendSuccessMessage( pluginData, - msg.channel as TextChannel, + msg.channel, `The following users were removed from the dashboard for **${guild.name}**:\n\n${userNameList}`, ); }, diff --git a/backend/src/plugins/BotControl/commands/RestPerformanceCmd.ts b/backend/src/plugins/BotControl/commands/RestPerformanceCmd.ts index 84b1f40e..737f6648 100644 --- a/backend/src/plugins/BotControl/commands/RestPerformanceCmd.ts +++ b/backend/src/plugins/BotControl/commands/RestPerformanceCmd.ts @@ -1,7 +1,5 @@ -import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { createChunkedMessage, formatNumber, resolveInvite, sorter, verboseUserMention } from "../../../utils"; +import { createChunkedMessage } from "../../../utils"; import { botControlCmd } from "../types"; import { getTopRestCallStats } from "../../../restCallStats"; @@ -22,6 +20,6 @@ export const RestPerformanceCmd = botControlCmd({ const cleanSource = callStats.source.replace(leadingPathRegex, ""); return `**${callStats.count} calls**\n${callStats.method.toUpperCase()} ${callStats.path}\n${cleanSource}`; }); - createChunkedMessage(msg.channel as TextChannel, `Top rest calls:\n\n${formatted.join("\n")}`); + createChunkedMessage(msg.channel, `Top rest calls:\n\n${formatted.join("\n")}`); }, }); diff --git a/backend/src/plugins/BotControl/commands/ServersCmd.ts b/backend/src/plugins/BotControl/commands/ServersCmd.ts index cee486d2..23146d21 100644 --- a/backend/src/plugins/BotControl/commands/ServersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ServersCmd.ts @@ -1,4 +1,3 @@ -import { TextChannel } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter } from "../../../pluginUtils"; @@ -51,7 +50,7 @@ export const ServersCmd = botControlCmd({ const owner = getUser(pluginData.client, g.ownerId); return `\`${paddedId}\` **${g.name}** (${g.memberCount} members) (owner **${owner.tag}** \`${owner.id}\`)`; }); - createChunkedMessage(msg.channel as TextChannel, lines.join("\n")); + createChunkedMessage(msg.channel, lines.join("\n")); } else { msg.channel.send("No servers matched the filters"); } diff --git a/backend/src/plugins/Cases/functions/createCase.ts b/backend/src/plugins/Cases/functions/createCase.ts index 0a0925d7..8aa39f6f 100644 --- a/backend/src/plugins/Cases/functions/createCase.ts +++ b/backend/src/plugins/Cases/functions/createCase.ts @@ -1,10 +1,10 @@ -import type { Snowflake } from "discord-api-types/globals"; import { GuildPluginData } from "knub"; import { logger } from "../../../logger"; import { resolveUser } from "../../../utils"; import { CaseArgs, CasesPluginType } from "../types"; import { createCaseNote } from "./createCaseNote"; import { postCaseToCaseLogChannel } from "./postToCaseLogChannel"; +import type { Snowflake } from "discord.js"; export async function createCase(pluginData: GuildPluginData, args: CaseArgs) { const user = await resolveUser(pluginData.client, args.userId); diff --git a/backend/src/plugins/Cases/functions/getCaseEmbed.ts b/backend/src/plugins/Cases/functions/getCaseEmbed.ts index 45550ef8..908a47b1 100644 --- a/backend/src/plugins/Cases/functions/getCaseEmbed.ts +++ b/backend/src/plugins/Cases/functions/getCaseEmbed.ts @@ -1,4 +1,4 @@ -import { escapeCodeBlock, MessageEditOptions, MessageOptions } from "discord.js"; +import { escapeCodeBlock, MessageEditOptions, MessageCreateOptions } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { CaseTypes } from "../../../data/CaseTypes"; @@ -14,7 +14,7 @@ export async function getCaseEmbed( caseOrCaseId: Case | number, requestMemberId?: string, noOriginalCaseLink?: boolean, -): Promise { +): Promise { const theCase = await pluginData.state.cases.with("notes").find(resolveCaseId(caseOrCaseId)); if (!theCase) { throw new Error("Unknown case"); diff --git a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts index 1d363d60..c0f8b1aa 100644 --- a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts +++ b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts @@ -1,4 +1,4 @@ -import { FileOptions, MessageOptions, NewsChannel, Snowflake, TextChannel } from "discord.js"; +import { MessageCreateOptions, NewsChannel, RESTJSONErrorCodes, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { Case } from "../../../data/entities/Case"; import { isDiscordAPIError } from "../../../utils"; @@ -11,8 +11,8 @@ import { InternalPosterMessageResult } from "../../InternalPoster/functions/send export async function postToCaseLogChannel( pluginData: GuildPluginData, - content: MessageOptions, - file?: FileOptions[], + content: MessageCreateOptions, + files?: MessageCreateOptions["files"], ): Promise { const caseLogChannelId = pluginData.config.get().case_log_channel; if (!caseLogChannelId) return null; @@ -23,13 +23,16 @@ export async function postToCaseLogChannel( let result: InternalPosterMessageResult | null = null; try { - if (file != null) { - content.files = file; + if (files != null) { + content.files = files; } const poster = pluginData.getPlugin(InternalPosterPlugin); result = await poster.sendMessage(caseLogChannel, { ...content }); } catch (e) { - if (isDiscordAPIError(e) && (e.code === 50013 || e.code === 50001)) { + if ( + isDiscordAPIError(e) && + (e.code === RESTJSONErrorCodes.MissingPermissions || e.code === RESTJSONErrorCodes.MissingAccess) + ) { pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Missing permissions to post mod cases in <#${caseLogChannel.id}>`, }); @@ -57,10 +60,12 @@ export async function postCaseToCaseLogChannel( try { const poster = pluginData.getPlugin(InternalPosterPlugin); - const channel = pluginData.guild.channels.resolve(channelId as Snowflake) as TextChannel; - const message = await channel.messages.fetch(messageId); - if (message) { - await poster.editMessage(message, caseEmbed); + const channel = pluginData.guild.channels.resolve(channelId as Snowflake); + if (channel?.isTextBased()) { + const message = await channel.messages.fetch(messageId); + if (message) { + await poster.editMessage(message, caseEmbed); + } } return; } catch {} // tslint:disable-line:no-empty diff --git a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts index 5e92a305..a0dcdf58 100644 --- a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts +++ b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts @@ -1,4 +1,4 @@ -import { Invite, MessageEmbed } from "discord.js"; +import { Invite, Embed } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; import { GuildPluginData } from "knub"; import cloneDeep from "lodash.clonedeep"; @@ -19,7 +19,7 @@ export async function applyFiltersToMsg( let messageContent = savedMessage.data.content || ""; if (savedMessage.data.attachments) messageContent += " " + JSON.stringify(savedMessage.data.attachments); if (savedMessage.data.embeds) { - const embeds = (savedMessage.data.embeds as MessageEmbed[]).map((e) => cloneDeep(e)); + const embeds = (savedMessage.data.embeds as Embed[]).map((e) => cloneDeep(e)); for (const embed of embeds) { if (embed.type === "video") { // Ignore video descriptions as they're not actually shown on the embed diff --git a/backend/src/plugins/Censor/util/censorMessage.ts b/backend/src/plugins/Censor/util/censorMessage.ts index 6375da79..2241417c 100644 --- a/backend/src/plugins/Censor/util/censorMessage.ts +++ b/backend/src/plugins/Censor/util/censorMessage.ts @@ -1,6 +1,5 @@ -import { BaseGuildTextChannel, GuildTextBasedChannel, Snowflake, TextChannel, ThreadChannel } from "discord.js"; +import { GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; import { resolveUser } from "../../../utils"; @@ -15,8 +14,8 @@ export async function censorMessage( pluginData.state.serverLogs.ignoreLog(LogType.MESSAGE_DELETE, savedMessage.id); try { - const resolvedChannel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake) as TextChannel; - await resolvedChannel.messages.delete(savedMessage.id as Snowflake); + const resolvedChannel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake); + if (resolvedChannel?.isTextBased()) await resolvedChannel.messages.delete(savedMessage.id as Snowflake); } catch { return; } diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index 2fe94bb9..9b8b2239 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -1,4 +1,4 @@ -import { Collection, Message, Snowflake } from "discord.js"; +import { Snowflake } from "discord.js"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isOwner, sendErrorMessage } from "../../../pluginUtils"; diff --git a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts index 9f5c6423..b166b830 100644 --- a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts +++ b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts @@ -1,14 +1,11 @@ -import { MessageAttachment, MessageOptions, TextChannel, ThreadChannel } from "discord.js"; +import { GuildTextBasedChannel, Attachment, MessageCreateOptions } from "discord.js"; import fs from "fs"; import { downloadFile } from "../../utils"; const fsp = fs.promises; const MAX_ATTACHMENT_REHOST_SIZE = 1024 * 1024 * 8; -export async function rehostAttachment( - attachment: MessageAttachment, - targetChannel: TextChannel | ThreadChannel, -): Promise { +export async function rehostAttachment(attachment: Attachment, targetChannel: GuildTextBasedChannel): Promise { if (attachment.size > MAX_ATTACHMENT_REHOST_SIZE) { return "Attachment too big to rehost"; } @@ -21,7 +18,7 @@ export async function rehostAttachment( } try { - const content: MessageOptions = { + const content: MessageCreateOptions = { content: `Rehost of attachment ${attachment.id}`, files: [{ name: attachment.name ? attachment.name : undefined, attachment: await fsp.readFile(downloaded.path) }], }; diff --git a/backend/src/plugins/ContextMenus/actions/clean.ts b/backend/src/plugins/ContextMenus/actions/clean.ts index 1831f7d8..7fd124e9 100644 --- a/backend/src/plugins/ContextMenus/actions/clean.ts +++ b/backend/src/plugins/ContextMenus/actions/clean.ts @@ -1,6 +1,5 @@ -import { ContextMenuInteraction, TextChannel } from "discord.js"; +import { ContextMenuCommandInteraction, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; import { UtilityPlugin } from "../../../plugins/Utility/UtilityPlugin"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; import { LogsPlugin } from "../../Logs/LogsPlugin"; @@ -9,7 +8,7 @@ import { ContextMenuPluginType } from "../types"; export async function cleanAction( pluginData: GuildPluginData, amount: number, - interaction: ContextMenuInteraction, + interaction: ContextMenuCommandInteraction, ) { interaction.deferReply({ ephemeral: true }); const executingMember = await pluginData.guild.members.fetch(interaction.user.id); diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index 5735337a..4dfc682e 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -1,9 +1,8 @@ -import { ContextMenuInteraction } from "discord.js"; +import { ContextMenuCommandInteraction } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; import { canActOn } from "src/pluginUtils"; -import { LogType } from "../../../data/LogType"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; import { convertDelayStringToMS } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; @@ -14,7 +13,7 @@ import { ContextMenuPluginType } from "../types"; export async function muteAction( pluginData: GuildPluginData, duration: string | undefined, - interaction: ContextMenuInteraction, + interaction: ContextMenuCommandInteraction, ) { interaction.deferReply({ ephemeral: true }); const executingMember = await pluginData.guild.members.fetch(interaction.user.id); diff --git a/backend/src/plugins/ContextMenus/actions/userInfo.ts b/backend/src/plugins/ContextMenus/actions/userInfo.ts index c4dd4a34..5818d57c 100644 --- a/backend/src/plugins/ContextMenus/actions/userInfo.ts +++ b/backend/src/plugins/ContextMenus/actions/userInfo.ts @@ -1,11 +1,11 @@ -import { ContextMenuInteraction } from "discord.js"; +import { ContextMenuCommandInteraction } from "discord.js"; import { GuildPluginData } from "knub"; import { UtilityPlugin } from "../../../plugins/Utility/UtilityPlugin"; import { ContextMenuPluginType } from "../types"; export async function userInfoAction( pluginData: GuildPluginData, - interaction: ContextMenuInteraction, + interaction: ContextMenuCommandInteraction, ) { interaction.deferReply({ ephemeral: true }); const executingMember = await pluginData.guild.members.fetch(interaction.user.id); diff --git a/backend/src/plugins/ContextMenus/events/ContextClickedEvt.ts b/backend/src/plugins/ContextMenus/events/ContextClickedEvt.ts index 62675e41..98e6ab1f 100644 --- a/backend/src/plugins/ContextMenus/events/ContextClickedEvt.ts +++ b/backend/src/plugins/ContextMenus/events/ContextClickedEvt.ts @@ -1,4 +1,3 @@ -import { ContextMenuInteraction } from "discord.js"; import { contextMenuEvt } from "../types"; import { routeContextAction } from "../utils/contextRouter"; @@ -6,8 +5,8 @@ export const ContextClickedEvt = contextMenuEvt({ event: "interactionCreate", async listener(meta) { - if (!meta.args.interaction.isContextMenu) return; - const inter = meta.args.interaction as ContextMenuInteraction; + if (!meta.args.interaction.isContextMenuCommand()) return; + const inter = meta.args.interaction; await routeContextAction(meta.pluginData, inter); }, }); diff --git a/backend/src/plugins/ContextMenus/utils/contextRouter.ts b/backend/src/plugins/ContextMenus/utils/contextRouter.ts index 1bda0ff8..18b7b064 100644 --- a/backend/src/plugins/ContextMenus/utils/contextRouter.ts +++ b/backend/src/plugins/ContextMenus/utils/contextRouter.ts @@ -1,11 +1,11 @@ -import { ContextMenuInteraction } from "discord.js"; +import { ContextMenuCommandInteraction } from "discord.js"; import { GuildPluginData } from "knub"; import { ContextMenuPluginType } from "../types"; import { hardcodedActions } from "./hardcodedContextOptions"; export async function routeContextAction( pluginData: GuildPluginData, - interaction: ContextMenuInteraction, + interaction: ContextMenuCommandInteraction, ) { const contextLink = await pluginData.state.contextMenuLinks.get(interaction.commandId); if (!contextLink) return; diff --git a/backend/src/plugins/ContextMenus/utils/loadAllCommands.ts b/backend/src/plugins/ContextMenus/utils/loadAllCommands.ts index 8272d8b3..e9c2e3c6 100644 --- a/backend/src/plugins/ContextMenus/utils/loadAllCommands.ts +++ b/backend/src/plugins/ContextMenus/utils/loadAllCommands.ts @@ -1,5 +1,4 @@ -import { ApplicationCommandData, Constants } from "discord.js"; -import { LogType } from "../../../data/LogType"; +import { ApplicationCommandData, ApplicationCommandType } from "discord.js"; import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; import { GuildPluginData } from "knub"; import { ContextMenuPluginType } from "../types"; @@ -14,9 +13,7 @@ export async function loadAllCommands(pluginData: GuildPluginData { - role - .edit( - { - mentionable: false, - }, - `Custom event: ${event.name}`, - ) - .catch(noop); + role.setMentionable(false, `Custom event: ${event.name}`).catch(noop); }, timeout); } diff --git a/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts b/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts index 1975b1c1..d245d33d 100644 --- a/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts +++ b/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts @@ -23,10 +23,5 @@ export async function makeRoleUnmentionableAction( throw new ActionError(`Unknown role: ${role}`); } - await role.edit( - { - mentionable: false, - }, - `Custom event: ${event.name}`, - ); + await role.setMentionable(false, `Custom event: ${event.name}`); } diff --git a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts index a1aa2e09..c0d9e873 100644 --- a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts +++ b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel, PermissionsString, PermissionsBitField } from "discord.js"; +import { Snowflake, PermissionsString, PermissionsBitField } from "discord.js"; import * as t from "io-ts"; import { GuildPluginData } from "knub"; import { ActionError } from "../ActionError"; @@ -26,8 +26,8 @@ export async function setChannelPermissionOverridesAction( event: TCustomEvent, eventData: any, ) { - const channel = pluginData.guild.channels.cache.get(action.channel as Snowflake) as TextChannel; - if (!channel) { + const channel = pluginData.guild.channels.cache.get(action.channel as Snowflake); + if (!channel || channel.isThread() || !("guild" in channel)) { throw new ActionError(`Unknown channel: ${action.channel}`); } diff --git a/backend/src/plugins/CustomEvents/functions/runEvent.ts b/backend/src/plugins/CustomEvents/functions/runEvent.ts index 404774fd..063b0c26 100644 --- a/backend/src/plugins/CustomEvents/functions/runEvent.ts +++ b/backend/src/plugins/CustomEvents/functions/runEvent.ts @@ -1,4 +1,4 @@ -import { Message, TextChannel } from "discord.js"; +import { Message } from "discord.js"; import { GuildPluginData } from "knub"; import { sendErrorMessage } from "../../../pluginUtils"; import { ActionError } from "../ActionError"; @@ -39,7 +39,7 @@ export async function runEvent( } catch (e) { if (e instanceof ActionError) { if (event.trigger.type === "command") { - sendErrorMessage(pluginData, (eventData.msg as Message).channel as TextChannel, e.message); + sendErrorMessage(pluginData, (eventData.msg as Message).channel, e.message); } else { // TODO: Where to log action errors from other kinds of triggers? } diff --git a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts index 695486b2..f84ca1aa 100644 --- a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts +++ b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts @@ -1,5 +1,5 @@ import * as t from "io-ts"; -import { GuildPluginData, guildPluginEventListener } from "knub"; +import { guildPluginEventListener } from "knub"; import { AllowedGuilds } from "../../data/AllowedGuilds"; import { MINUTES } from "../../utils"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; diff --git a/backend/src/plugins/GuildInfoSaver/types.ts b/backend/src/plugins/GuildInfoSaver/types.ts index 29013186..4ff63cba 100644 --- a/backend/src/plugins/GuildInfoSaver/types.ts +++ b/backend/src/plugins/GuildInfoSaver/types.ts @@ -1,5 +1,4 @@ import { BasePluginType } from "knub"; -import { AllowedGuilds } from "../../data/AllowedGuilds"; export interface GuildInfoSaverPluginType extends BasePluginType { state: { diff --git a/backend/src/plugins/InternalPoster/InternalPosterPlugin.ts b/backend/src/plugins/InternalPoster/InternalPosterPlugin.ts index 12aeb62b..fb47b5a3 100644 --- a/backend/src/plugins/InternalPoster/InternalPosterPlugin.ts +++ b/backend/src/plugins/InternalPoster/InternalPosterPlugin.ts @@ -1,13 +1,6 @@ -import { PluginOptions, guildPluginMessageCommand } from "knub"; -import { GuildPingableRoles } from "../../data/GuildPingableRoles"; +import { PluginOptions } from "knub"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { ConfigSchema, InternalPosterPluginType } from "./types"; -import { - getPhishermanDomainInfo, - hasPhishermanMasterAPIKey, - phishermanApiKeyIsValid, - reportTrackedDomainsToPhisherman, -} from "../../data/Phisherman"; import { mapToPublicFn } from "../../pluginUtils"; import { Webhooks } from "../../data/Webhooks"; import { Queue } from "../../Queue"; diff --git a/backend/src/plugins/InternalPoster/functions/editMessage.ts b/backend/src/plugins/InternalPoster/functions/editMessage.ts index a0fc7169..0c11a579 100644 --- a/backend/src/plugins/InternalPoster/functions/editMessage.ts +++ b/backend/src/plugins/InternalPoster/functions/editMessage.ts @@ -1,11 +1,4 @@ -import { - Message, - MessageEditOptions, - NewsChannel, - TextChannel, - WebhookClient, - WebhookEditMessageOptions, -} from "discord.js"; +import { Message, MessageEditOptions, WebhookClient, WebhookMessageEditOptions } from "discord.js"; import { GuildPluginData } from "knub"; import { InternalPosterPluginType } from "../types"; import { isDiscordAPIError, noop } from "../../../utils"; @@ -16,14 +9,13 @@ import { isDiscordAPIError, noop } from "../../../utils"; export async function editMessage( pluginData: GuildPluginData, message: Message, - content: MessageEditOptions & WebhookEditMessageOptions, + content: MessageEditOptions & WebhookMessageEditOptions, ): Promise { - if (!(message.channel instanceof TextChannel || message.channel instanceof NewsChannel)) { + const channel = message.channel; + if (!channel.isTextBased()) { return; } - const channel = message.channel as TextChannel | NewsChannel; - await pluginData.state.queue.add(async () => { if (message.webhookId) { const webhook = await pluginData.state.webhooks.find(message.webhookId); diff --git a/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookForChannel.ts b/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookForChannel.ts index e95a7913..254a8ab7 100644 --- a/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookForChannel.ts +++ b/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookForChannel.ts @@ -1,13 +1,6 @@ import { GuildPluginData } from "knub"; import { InternalPosterPluginType } from "../types"; -import { - GuildBasedChannel, - GuildChannel, - MessageManager, - NewsChannel, - PermissionsBitField, - TextChannel, -} from "discord.js"; +import { GuildBasedChannel, PermissionsBitField } from "discord.js"; import { isDiscordAPIError } from "../../../utils"; type WebhookInfo = [id: string, token: string]; diff --git a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts index 6510540c..691afc3d 100644 --- a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts +++ b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import { locateUserEvt } from "../types"; import { sendAlerts } from "../utils/sendAlerts"; @@ -20,11 +20,13 @@ export const VoiceStateUpdateAlertEvt = locateUserEvt({ const voiceChannel = meta.args.oldState.channel!; triggeredAlerts.forEach((alert) => { - const txtChannel = meta.pluginData.guild.channels.resolve(alert.channel_id as Snowflake) as TextChannel; - txtChannel.send({ - content: `🔴 <@!${alert.requestor_id}> the user <@!${alert.user_id}> disconnected out of \`${voiceChannel.name}\``, - allowedMentions: { users: [alert.requestor_id as Snowflake] }, - }); + const txtChannel = meta.pluginData.guild.channels.resolve(alert.channel_id as Snowflake); + if (txtChannel?.isTextBased()) { + txtChannel.send({ + content: `🔴 <@!${alert.requestor_id}> the user <@!${alert.user_id}> disconnected out of \`${voiceChannel.name}\``, + allowedMentions: { users: [alert.requestor_id as Snowflake] }, + }); + } }); } }, diff --git a/backend/src/plugins/LocateUser/types.ts b/backend/src/plugins/LocateUser/types.ts index 574084bb..dedfd57b 100644 --- a/backend/src/plugins/LocateUser/types.ts +++ b/backend/src/plugins/LocateUser/types.ts @@ -1,7 +1,6 @@ import * as t from "io-ts"; import { BasePluginType, guildPluginMessageCommand, guildPluginEventListener } from "knub"; import { GuildVCAlerts } from "../../data/GuildVCAlerts"; -import Timeout = NodeJS.Timeout; export const ConfigSchema = t.type({ can_where: t.boolean, diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts index d3c85ecd..81d1d896 100644 --- a/backend/src/plugins/LocateUser/utils/moveMember.ts +++ b/backend/src/plugins/LocateUser/utils/moveMember.ts @@ -1,4 +1,4 @@ -import { GuildMember, Snowflake, TextChannel } from "discord.js"; +import { GuildMember, Snowflake, GuildTextBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { sendErrorMessage } from "../../../pluginUtils"; import { LocateUserPluginType } from "../types"; @@ -7,7 +7,7 @@ export async function moveMember( pluginData: GuildPluginData, toMoveID: string, target: GuildMember, - errorChannel: TextChannel, + errorChannel: GuildTextBasedChannel, ) { const modMember: GuildMember = await pluginData.guild.members.fetch(toMoveID as Snowflake); if (modMember.voice.channelId != null) { diff --git a/backend/src/plugins/LocateUser/utils/sendAlerts.ts b/backend/src/plugins/LocateUser/utils/sendAlerts.ts index d93bf47d..66e6a222 100644 --- a/backend/src/plugins/LocateUser/utils/sendAlerts.ts +++ b/backend/src/plugins/LocateUser/utils/sendAlerts.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { resolveMember } from "../../../utils"; import { LocateUserPluginType } from "../types"; @@ -12,10 +12,12 @@ export async function sendAlerts(pluginData: GuildPluginData { const prepend = `<@!${alert.requestor_id}>, an alert requested by you has triggered!\nReminder: \`${alert.body}\`\n`; - const txtChannel = pluginData.guild.channels.resolve(alert.channel_id as Snowflake) as TextChannel; - sendWhere(pluginData, member, txtChannel, prepend); - if (alert.active) { - moveMember(pluginData, alert.requestor_id, member, txtChannel); + const txtChannel = pluginData.guild.channels.resolve(alert.channel_id as Snowflake); + if (txtChannel?.isTextBased()) { + sendWhere(pluginData, member, txtChannel, prepend); + if (alert.active) { + moveMember(pluginData, alert.requestor_id, member, txtChannel); + } } }); } diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts index dd6ddd69..b6999a73 100644 --- a/backend/src/plugins/LocateUser/utils/sendWhere.ts +++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts @@ -1,4 +1,4 @@ -import { GuildMember, Invite, TextChannel, VoiceChannel } from "discord.js"; +import { GuildMember, GuildTextBasedChannel, Invite, VoiceChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { getInviteLink } from "knub/dist/helpers"; import { sendErrorMessage } from "../../../pluginUtils"; @@ -8,7 +8,7 @@ import { createOrReuseInvite } from "./createOrReuseInvite"; export async function sendWhere( pluginData: GuildPluginData, member: GuildMember, - channel: TextChannel, + channel: GuildTextBasedChannel, prepend: string, ) { const voice = member.voice.channelId diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts index 618d9f7c..5000f747 100644 --- a/backend/src/plugins/Logs/LogsPlugin.ts +++ b/backend/src/plugins/Logs/LogsPlugin.ts @@ -35,11 +35,7 @@ import { log } from "./util/log"; import { onMessageDelete } from "./util/onMessageDelete"; import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk"; import { onMessageUpdate } from "./util/onMessageUpdate"; -import { - createTypedTemplateSafeValueContainer, - TemplateSafeValueContainer, - TypedTemplateSafeValueContainer, -} from "../../templateFormatter"; +import { createTypedTemplateSafeValueContainer, TypedTemplateSafeValueContainer } from "../../templateFormatter"; import { mapToPublicFn } from "../../pluginUtils"; import { logAutomodAction } from "./logFunctions/logAutomodAction"; diff --git a/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts b/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts index 33bd7df9..2a2e2639 100644 --- a/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts @@ -1,6 +1,4 @@ -import { LogType } from "../../../data/LogType"; import { differenceToString, getScalarDifference } from "../../../utils"; -import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; import { logsEvt } from "../types"; import { logChannelCreate } from "../logFunctions/logChannelCreate"; import { logChannelDelete } from "../logFunctions/logChannelDelete"; diff --git a/backend/src/plugins/Logs/events/LogsEmojiAndStickerModifyEvts.ts b/backend/src/plugins/Logs/events/LogsEmojiAndStickerModifyEvts.ts index 29b8eb61..c253ca18 100644 --- a/backend/src/plugins/Logs/events/LogsEmojiAndStickerModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsEmojiAndStickerModifyEvts.ts @@ -6,7 +6,7 @@ import { logEmojiUpdate } from "../logFunctions/logEmojiUpdate"; import { logStickerCreate } from "../logFunctions/logStickerCreate"; import { logStickerDelete } from "../logFunctions/logStickerDelete"; import { logStickerUpdate } from "../logFunctions/logStickerUpdate"; -import { Emoji, GuildEmoji, Sticker, ThreadChannel } from "discord.js"; +import { GuildEmoji, Sticker } from "discord.js"; import { filterObject } from "../../../utils/filterObject"; export const LogsEmojiCreateEvt = logsEvt({ diff --git a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts index fcf84249..ce33cb6d 100644 --- a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts +++ b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts @@ -1,6 +1,5 @@ -import { GuildAuditLogs } from "discord.js"; +import { AuditLogEvent } from "discord.js"; import { LogType } from "../../../data/LogType"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { logsEvt } from "../types"; import { logMemberBan } from "../logFunctions/logMemberBan"; import { isLogIgnored } from "../util/isLogIgnored"; @@ -18,7 +17,11 @@ export const LogsGuildBanAddEvt = logsEvt({ return; } - const relevantAuditLogEntry = await findMatchingAuditLogEntry(pluginData.guild, "MEMBER_BAN_ADD", user.id); + const relevantAuditLogEntry = await findMatchingAuditLogEntry( + pluginData.guild, + AuditLogEvent.MemberBanAdd, + user.id, + ); const mod = relevantAuditLogEntry?.executor ?? null; logMemberBan(meta.pluginData, { mod, @@ -40,7 +43,11 @@ export const LogsGuildBanRemoveEvt = logsEvt({ return; } - const relevantAuditLogEntry = await findMatchingAuditLogEntry(pluginData.guild, "MEMBER_BAN_REMOVE", user.id); + const relevantAuditLogEntry = await findMatchingAuditLogEntry( + pluginData.guild, + AuditLogEvent.MemberBanRemove, + user.id, + ); const mod = relevantAuditLogEntry?.executor ?? null; logMemberUnban(pluginData, { diff --git a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts index c86a1fc3..fca30f99 100644 --- a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts +++ b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts @@ -1,10 +1,5 @@ -import humanizeDuration from "humanize-duration"; -import moment from "moment-timezone"; -import { LogType } from "../../../data/LogType"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; import { logsEvt } from "../types"; import { logMemberJoin } from "../logFunctions/logMemberJoin"; -import { logMemberJoinWithPriorRecords } from "../logFunctions/logMemberJoinWithPriorRecords"; export const LogsGuildMemberAddEvt = logsEvt({ event: "guildMemberAdd", diff --git a/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts b/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts index 289372e1..858d3bc8 100644 --- a/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts +++ b/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts @@ -1,5 +1,3 @@ -import { LogType } from "../../../data/LogType"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; import { logsEvt } from "../types"; import { logMemberLeave } from "../logFunctions/logMemberLeave"; diff --git a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts index 81d6e2bf..b865e10c 100644 --- a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts @@ -1,11 +1,9 @@ -import { LogType } from "../../../data/LogType"; import { differenceToString, getScalarDifference } from "../../../utils"; -import { roleToTemplateSafeRole } from "../../../utils/templateSafeObjects"; import { logsEvt } from "../types"; import { logRoleCreate } from "../logFunctions/logRoleCreate"; import { logRoleDelete } from "../logFunctions/logRoleDelete"; import { logRoleUpdate } from "../logFunctions/logRoleUpdate"; -import { GuildEmoji, Role } from "discord.js"; +import { Role } from "discord.js"; import { filterObject } from "../../../utils/filterObject"; export const LogsRoleCreateEvt = logsEvt({ diff --git a/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts b/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts index f9ddb54a..bcfeb62e 100644 --- a/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts @@ -1,9 +1,7 @@ -import { LogType } from "../../../data/LogType"; import { differenceToString, getScalarDifference } from "../../../utils"; -import { channelToTemplateSafeChannel, stageToTemplateSafeStage } from "../../../utils/templateSafeObjects"; import { logsEvt } from "../types"; import { logStageInstanceCreate } from "../logFunctions/logStageInstanceCreate"; -import { Role, StageChannel, StageInstance } from "discord.js"; +import { StageChannel, StageInstance } from "discord.js"; import { logStageInstanceDelete } from "../logFunctions/logStageInstanceDelete"; import { logStageInstanceUpdate } from "../logFunctions/logStageInstanceUpdate"; import { filterObject } from "../../../utils/filterObject"; diff --git a/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts b/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts index b760d21d..d3dba8d0 100644 --- a/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts @@ -1,11 +1,9 @@ -import { LogType } from "../../../data/LogType"; import { differenceToString, getScalarDifference } from "../../../utils"; -import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; import { logsEvt } from "../types"; import { logThreadCreate } from "../logFunctions/logThreadCreate"; import { logThreadDelete } from "../logFunctions/logThreadDelete"; import { logThreadUpdate } from "../logFunctions/logThreadUpdate"; -import { TextChannel, ThreadChannel, VoiceChannel } from "discord.js"; +import { ThreadChannel } from "discord.js"; import { filterObject } from "../../../utils/filterObject"; export const LogsThreadCreateEvt = logsEvt({ diff --git a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts index ac24a0fe..2ffe0f90 100644 --- a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts +++ b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts @@ -1,7 +1,5 @@ -import { GuildAuditLogs } from "discord.js"; import diff from "lodash.difference"; import isEqual from "lodash.isequal"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { LogType } from "../../../data/LogType"; import { logsEvt } from "../types"; import { logMemberNickChange } from "../logFunctions/logMemberNickChange"; diff --git a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts index 51e349e7..484650e9 100644 --- a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts +++ b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts @@ -1,5 +1,3 @@ -import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogType } from "../../../data/LogType"; import { logsEvt } from "../types"; import { logVoiceChannelLeave } from "../logFunctions/logVoiceChannelLeave"; import { logVoiceChannelJoin } from "../logFunctions/logVoiceChannelJoin"; diff --git a/backend/src/plugins/Logs/logFunctions/logCensor.ts b/backend/src/plugins/Logs/logFunctions/logCensor.ts index c5048730..b5106f45 100644 --- a/backend/src/plugins/Logs/logFunctions/logCensor.ts +++ b/backend/src/plugins/Logs/logFunctions/logCensor.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; +import { GuildTextBasedChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, savedMessageToTemplateSafeSavedMessage, diff --git a/backend/src/plugins/Logs/logFunctions/logChannelCreate.ts b/backend/src/plugins/Logs/logFunctions/logChannelCreate.ts index a95ffb48..0ccf81ad 100644 --- a/backend/src/plugins/Logs/logFunctions/logChannelCreate.ts +++ b/backend/src/plugins/Logs/logFunctions/logChannelCreate.ts @@ -3,12 +3,12 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { GuildChannel, NewsChannel } from "discord.js"; +import { GuildBasedChannel } from "discord.js"; import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogChannelCreateData { - channel: GuildChannel | NewsChannel; + channel: GuildBasedChannel; } export function logChannelCreate(pluginData: GuildPluginData, data: LogChannelCreateData) { diff --git a/backend/src/plugins/Logs/logFunctions/logChannelDelete.ts b/backend/src/plugins/Logs/logFunctions/logChannelDelete.ts index 25bd4374..c96a1a29 100644 --- a/backend/src/plugins/Logs/logFunctions/logChannelDelete.ts +++ b/backend/src/plugins/Logs/logFunctions/logChannelDelete.ts @@ -3,12 +3,12 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { GuildChannel, NewsChannel } from "discord.js"; +import { GuildBasedChannel } from "discord.js"; import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogChannelDeleteData { - channel: GuildChannel | NewsChannel; + channel: GuildBasedChannel; } export function logChannelDelete(pluginData: GuildPluginData, data: LogChannelDeleteData) { diff --git a/backend/src/plugins/Logs/logFunctions/logChannelUpdate.ts b/backend/src/plugins/Logs/logFunctions/logChannelUpdate.ts index 7942501e..0aa850ef 100644 --- a/backend/src/plugins/Logs/logFunctions/logChannelUpdate.ts +++ b/backend/src/plugins/Logs/logFunctions/logChannelUpdate.ts @@ -3,13 +3,13 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { GuildChannel, NewsChannel } from "discord.js"; +import { GuildBasedChannel } from "discord.js"; import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogChannelUpdateData { - oldChannel: GuildChannel | NewsChannel; - newChannel: GuildChannel | NewsChannel; + oldChannel: GuildBasedChannel; + newChannel: GuildBasedChannel; differenceString: string; } diff --git a/backend/src/plugins/Logs/logFunctions/logClean.ts b/backend/src/plugins/Logs/logFunctions/logClean.ts index 6486873f..be47b69f 100644 --- a/backend/src/plugins/Logs/logFunctions/logClean.ts +++ b/backend/src/plugins/Logs/logFunctions/logClean.ts @@ -3,13 +3,13 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, User } from "discord.js"; +import { User, GuildTextBasedChannel } from "discord.js"; import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogCleanData { mod: User; - channel: BaseGuildTextChannel; + channel: GuildTextBasedChannel; count: number; archiveUrl: string; } diff --git a/backend/src/plugins/Logs/logFunctions/logMemberBan.ts b/backend/src/plugins/Logs/logFunctions/logMemberBan.ts index 21777c2b..dd6184db 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberBan.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberBan.ts @@ -4,7 +4,7 @@ import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; import { User } from "discord.js"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { UnknownUser } from "../../../utils"; interface LogMemberBanData { diff --git a/backend/src/plugins/Logs/logFunctions/logMemberKick.ts b/backend/src/plugins/Logs/logFunctions/logMemberKick.ts index 704b8769..72d3bf37 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberKick.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberKick.ts @@ -3,8 +3,8 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { GuildMember, User } from "discord.js"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; +import { User } from "discord.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { UnknownUser } from "../../../utils"; interface LogMemberKickData { diff --git a/backend/src/plugins/Logs/logFunctions/logMemberMute.ts b/backend/src/plugins/Logs/logFunctions/logMemberMute.ts index c99fd300..a4366902 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberMute.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberMute.ts @@ -3,8 +3,8 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { GuildMember, User } from "discord.js"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; +import { User } from "discord.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { UnknownUser } from "../../../utils"; interface LogMemberMuteData { diff --git a/backend/src/plugins/Logs/logFunctions/logMemberUnban.ts b/backend/src/plugins/Logs/logFunctions/logMemberUnban.ts index d9702531..25b4c82e 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberUnban.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberUnban.ts @@ -3,8 +3,8 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { GuildMember, Snowflake, User } from "discord.js"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; +import { Snowflake, User } from "discord.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { UnknownUser } from "../../../utils"; interface LogMemberUnbanData { diff --git a/backend/src/plugins/Logs/logFunctions/logMemberUnmute.ts b/backend/src/plugins/Logs/logFunctions/logMemberUnmute.ts index ef2aca40..4af6dfc5 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberUnmute.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberUnmute.ts @@ -3,8 +3,8 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { GuildMember, User } from "discord.js"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; +import { User } from "discord.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { UnknownUser } from "../../../utils"; interface LogMemberUnmuteData { diff --git a/backend/src/plugins/Logs/logFunctions/logMessageDelete.ts b/backend/src/plugins/Logs/logFunctions/logMessageDelete.ts index e103b13b..2531030d 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageDelete.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageDelete.ts @@ -3,7 +3,7 @@ import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; +import { GuildTextBasedChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, savedMessageToTemplateSafeSavedMessage, diff --git a/backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts b/backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts index d4e66f28..aa9f92ae 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, User } from "discord.js"; +import { GuildTextBasedChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, savedMessageToTemplateSafeSavedMessage, @@ -16,7 +16,7 @@ import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogMessageDeleteAutoData { message: SavedMessage; user: User | UnknownUser; - channel: BaseGuildTextChannel; + channel: GuildTextBasedChannel; messageDate: string; } diff --git a/backend/src/plugins/Logs/logFunctions/logMessageDeleteBare.ts b/backend/src/plugins/Logs/logFunctions/logMessageDeleteBare.ts index ad9320e3..f9289f36 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageDeleteBare.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageDeleteBare.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel } from "discord.js"; +import { GuildTextBasedChannel } from "discord.js"; import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; diff --git a/backend/src/plugins/Logs/logFunctions/logMessageDeleteBulk.ts b/backend/src/plugins/Logs/logFunctions/logMessageDeleteBulk.ts index 2ffe36bf..c7f8af26 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageDeleteBulk.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageDeleteBulk.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel } from "discord.js"; +import { GuildTextBasedChannel } from "discord.js"; import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; diff --git a/backend/src/plugins/Logs/logFunctions/logMessageEdit.ts b/backend/src/plugins/Logs/logFunctions/logMessageEdit.ts index 64f12e8f..be2e8f27 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageEdit.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageEdit.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; +import { GuildTextBasedChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, savedMessageToTemplateSafeSavedMessage, diff --git a/backend/src/plugins/Logs/logFunctions/logMessageSpamDetected.ts b/backend/src/plugins/Logs/logFunctions/logMessageSpamDetected.ts index a18f197c..34244060 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageSpamDetected.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageSpamDetected.ts @@ -3,13 +3,13 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, GuildChannel, GuildMember, ThreadChannel } from "discord.js"; +import { GuildMember, GuildTextBasedChannel } from "discord.js"; import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogMessageSpamDetectedData { member: GuildMember; - channel: GuildChannel | ThreadChannel; + channel: GuildTextBasedChannel; description: string; limit: number; interval: number; diff --git a/backend/src/plugins/Logs/logFunctions/logPostedScheduledMessage.ts b/backend/src/plugins/Logs/logFunctions/logPostedScheduledMessage.ts index 38a8f668..98f7e171 100644 --- a/backend/src/plugins/Logs/logFunctions/logPostedScheduledMessage.ts +++ b/backend/src/plugins/Logs/logFunctions/logPostedScheduledMessage.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; +import { GuildTextBasedChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; diff --git a/backend/src/plugins/Logs/logFunctions/logRepeatedMessage.ts b/backend/src/plugins/Logs/logFunctions/logRepeatedMessage.ts index bc2cc31f..5fa1d39c 100644 --- a/backend/src/plugins/Logs/logFunctions/logRepeatedMessage.ts +++ b/backend/src/plugins/Logs/logFunctions/logRepeatedMessage.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; +import { GuildTextBasedChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; diff --git a/backend/src/plugins/Logs/logFunctions/logScheduledMessage.ts b/backend/src/plugins/Logs/logFunctions/logScheduledMessage.ts index 8067dd6a..dce8874c 100644 --- a/backend/src/plugins/Logs/logFunctions/logScheduledMessage.ts +++ b/backend/src/plugins/Logs/logFunctions/logScheduledMessage.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; +import { GuildTextBasedChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; diff --git a/backend/src/plugins/Logs/logFunctions/logScheduledRepeatedMessage.ts b/backend/src/plugins/Logs/logFunctions/logScheduledRepeatedMessage.ts index 849b1a4a..2a289e2a 100644 --- a/backend/src/plugins/Logs/logFunctions/logScheduledRepeatedMessage.ts +++ b/backend/src/plugins/Logs/logFunctions/logScheduledRepeatedMessage.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildTextChannel, GuildTextBasedChannel, ThreadChannel, User } from "discord.js"; +import { GuildTextBasedChannel, User } from "discord.js"; import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; diff --git a/backend/src/plugins/Logs/logFunctions/logStageInstanceUpdate.ts b/backend/src/plugins/Logs/logFunctions/logStageInstanceUpdate.ts index 8c68cf42..d84f0e52 100644 --- a/backend/src/plugins/Logs/logFunctions/logStageInstanceUpdate.ts +++ b/backend/src/plugins/Logs/logFunctions/logStageInstanceUpdate.ts @@ -8,7 +8,7 @@ import { channelToTemplateSafeChannel, stageToTemplateSafeStage } from "../../.. import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogStageInstanceUpdateData { - oldStageInstance: StageInstance; + oldStageInstance: StageInstance | null; newStageInstance: StageInstance; stageChannel: StageChannel; differenceString: string; @@ -19,7 +19,7 @@ export function logStageInstanceUpdate(pluginData: GuildPluginData, data: LogThreadCreateData) { diff --git a/backend/src/plugins/Logs/logFunctions/logThreadDelete.ts b/backend/src/plugins/Logs/logFunctions/logThreadDelete.ts index 04827083..fddb57f3 100644 --- a/backend/src/plugins/Logs/logFunctions/logThreadDelete.ts +++ b/backend/src/plugins/Logs/logFunctions/logThreadDelete.ts @@ -3,12 +3,12 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { ThreadChannel } from "discord.js"; +import { AnyThreadChannel } from "discord.js"; import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogThreadDeleteData { - thread: ThreadChannel; + thread: AnyThreadChannel; } export function logThreadDelete(pluginData: GuildPluginData, data: LogThreadDeleteData) { diff --git a/backend/src/plugins/Logs/logFunctions/logThreadUpdate.ts b/backend/src/plugins/Logs/logFunctions/logThreadUpdate.ts index c359a683..77a6f1ad 100644 --- a/backend/src/plugins/Logs/logFunctions/logThreadUpdate.ts +++ b/backend/src/plugins/Logs/logFunctions/logThreadUpdate.ts @@ -3,13 +3,13 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { ThreadChannel } from "discord.js"; +import { AnyThreadChannel } from "discord.js"; import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogThreadUpdateData { - oldThread: ThreadChannel; - newThread: ThreadChannel; + oldThread: AnyThreadChannel; + newThread: AnyThreadChannel; differenceString: string; } diff --git a/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceDisconnect.ts b/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceDisconnect.ts index 9940a1a3..37e7982a 100644 --- a/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceDisconnect.ts +++ b/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceDisconnect.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildVoiceChannel, GuildMember, User } from "discord.js"; +import { VoiceBasedChannel, GuildMember, User } from "discord.js"; import { channelToTemplateSafeChannel, memberToTemplateSafeMember, @@ -14,7 +14,7 @@ import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogVoiceChannelForceDisconnectData { mod: User; member: GuildMember; - oldChannel: BaseGuildVoiceChannel; + oldChannel: VoiceBasedChannel; } export function logVoiceChannelForceDisconnect( diff --git a/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceMove.ts b/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceMove.ts index 90b5478c..3045e4fb 100644 --- a/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceMove.ts +++ b/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceMove.ts @@ -3,7 +3,7 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildVoiceChannel, GuildMember, User } from "discord.js"; +import { VoiceBasedChannel, GuildMember, User } from "discord.js"; import { channelToTemplateSafeChannel, memberToTemplateSafeMember, @@ -14,8 +14,8 @@ import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogVoiceChannelForceMoveData { mod: User; member: GuildMember; - oldChannel: BaseGuildVoiceChannel; - newChannel: BaseGuildVoiceChannel; + oldChannel: VoiceBasedChannel; + newChannel: VoiceBasedChannel; } export function logVoiceChannelForceMove( diff --git a/backend/src/plugins/Logs/logFunctions/logVoiceChannelJoin.ts b/backend/src/plugins/Logs/logFunctions/logVoiceChannelJoin.ts index 71d5ea0c..50be9ec4 100644 --- a/backend/src/plugins/Logs/logFunctions/logVoiceChannelJoin.ts +++ b/backend/src/plugins/Logs/logFunctions/logVoiceChannelJoin.ts @@ -3,13 +3,13 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildVoiceChannel, GuildMember } from "discord.js"; +import { VoiceBasedChannel, GuildMember } from "discord.js"; import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogVoiceChannelJoinData { member: GuildMember; - channel: BaseGuildVoiceChannel; + channel: VoiceBasedChannel; } export function logVoiceChannelJoin(pluginData: GuildPluginData, data: LogVoiceChannelJoinData) { diff --git a/backend/src/plugins/Logs/logFunctions/logVoiceChannelLeave.ts b/backend/src/plugins/Logs/logFunctions/logVoiceChannelLeave.ts index 509494fc..bb9a5df2 100644 --- a/backend/src/plugins/Logs/logFunctions/logVoiceChannelLeave.ts +++ b/backend/src/plugins/Logs/logFunctions/logVoiceChannelLeave.ts @@ -3,13 +3,13 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildVoiceChannel, GuildMember } from "discord.js"; +import { VoiceBasedChannel, GuildMember } from "discord.js"; import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogVoiceChannelLeaveData { member: GuildMember; - channel: BaseGuildVoiceChannel; + channel: VoiceBasedChannel; } export function logVoiceChannelLeave(pluginData: GuildPluginData, data: LogVoiceChannelLeaveData) { diff --git a/backend/src/plugins/Logs/logFunctions/logVoiceChannelMove.ts b/backend/src/plugins/Logs/logFunctions/logVoiceChannelMove.ts index 56090907..f11a9673 100644 --- a/backend/src/plugins/Logs/logFunctions/logVoiceChannelMove.ts +++ b/backend/src/plugins/Logs/logFunctions/logVoiceChannelMove.ts @@ -3,14 +3,14 @@ import { LogsPluginType } from "../types"; import { LogType } from "../../../data/LogType"; import { log } from "../util/log"; import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { BaseGuildVoiceChannel, GuildMember } from "discord.js"; +import { VoiceBasedChannel, GuildMember } from "discord.js"; import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; import { resolveChannelIds } from "../../../utils/resolveChannelIds"; interface LogVoiceChannelMoveData { member: GuildMember; - oldChannel: BaseGuildVoiceChannel; - newChannel: BaseGuildVoiceChannel; + oldChannel: VoiceBasedChannel; + newChannel: VoiceBasedChannel; } export function logVoiceChannelMove(pluginData: GuildPluginData, data: LogVoiceChannelMoveData) { diff --git a/backend/src/plugins/Logs/types.ts b/backend/src/plugins/Logs/types.ts index f3417d4f..b10cfcb9 100644 --- a/backend/src/plugins/Logs/types.ts +++ b/backend/src/plugins/Logs/types.ts @@ -6,10 +6,9 @@ import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { RegExpRunner } from "../../RegExpRunner"; -import { StrictMessageContent, tMessageContent, tNullable } from "../../utils"; +import { tMessageContent, tNullable } from "../../utils"; import { TRegex } from "../../validatorUtils"; import { LogType } from "../../data/LogType"; -import { GuildMember } from "discord.js"; import { TemplateSafeCase, TemplateSafeChannel, @@ -23,11 +22,6 @@ import { TemplateSafeUnknownUser, TemplateSafeUser, } from "../../utils/templateSafeObjects"; -import { - TemplateSafeValue, - TemplateSafeValueContainer, - TypedTemplateSafeValueContainer, -} from "../../templateFormatter"; import { MessageBuffer } from "../../utils/MessageBuffer"; export const tLogFormats = t.record(t.string, t.union([t.string, tMessageContent])); @@ -280,7 +274,7 @@ export const LogTypeData = z.object({ }), [LogType.STAGE_INSTANCE_UPDATE]: z.object({ - oldStageInstance: z.instanceof(TemplateSafeStage), + oldStageInstance: z.instanceof(TemplateSafeStage).or(z.null()), newStageInstance: z.instanceof(TemplateSafeStage), stageChannel: z.instanceof(TemplateSafeChannel), differenceString: z.string(), diff --git a/backend/src/plugins/Logs/util/getLogMessage.ts b/backend/src/plugins/Logs/util/getLogMessage.ts index c69c7dbb..647ad67c 100644 --- a/backend/src/plugins/Logs/util/getLogMessage.ts +++ b/backend/src/plugins/Logs/util/getLogMessage.ts @@ -1,4 +1,4 @@ -import { MessageOptions } from "discord.js"; +import { MessageCreateOptions } from "discord.js"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; @@ -32,7 +32,7 @@ export async function getLogMessage( type: TLogType, data: TypedTemplateSafeValueContainer, opts?: Pick, -): Promise { +): Promise { const config = pluginData.config.get(); const format = opts?.format?.[LogType[type]] || config.format[LogType[type]] || ""; if (format === "" || format == null) return null; diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index 6df069e8..f532b3fe 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -1,4 +1,4 @@ -import { MessageCreateOptions, MessageMentionTypes, Snowflake, TextChannel } from "discord.js"; +import { EmbedData, MessageMentionTypes, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { allowTimeout } from "../../../RegExpRunner"; import { ILogTypeData, LogsPluginType, TLogChannel, TLogChannelMap } from "../types"; @@ -6,7 +6,7 @@ import { getLogMessage } from "./getLogMessage"; import { TypedTemplateSafeValueContainer } from "../../../templateFormatter"; import { LogType } from "../../../data/LogType"; import { MessageBuffer } from "../../../utils/MessageBuffer"; -import { createChunkedMessage, isDiscordAPIError, MINUTES } from "../../../utils"; +import { isDiscordAPIError, MINUTES } from "../../../utils"; import { InternalPosterPlugin } from "../../InternalPoster/InternalPosterPlugin"; const excludedUserProps = ["user", "member", "mod"]; @@ -141,7 +141,7 @@ export async function log( const buffer = pluginData.state.buffers.get(channelId)!; buffer.push({ content: typeof message === "string" ? message : message.content || "", - embeds: typeof message === "string" ? [] : ((message.embeds || []) as MessageCreateOptions[]), + embeds: typeof message === "string" ? [] : ((message.embeds || []) as EmbedData[]), }); } } diff --git a/backend/src/plugins/Logs/util/onMessageDelete.ts b/backend/src/plugins/Logs/util/onMessageDelete.ts index 0cbcc03a..3bc20312 100644 --- a/backend/src/plugins/Logs/util/onMessageDelete.ts +++ b/backend/src/plugins/Logs/util/onMessageDelete.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel, ThreadChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; @@ -10,12 +10,9 @@ import { logMessageDeleteBare } from "../logFunctions/logMessageDeleteBare"; export async function onMessageDelete(pluginData: GuildPluginData, savedMessage: SavedMessage) { const user = await resolveUser(pluginData.client, savedMessage.user_id); - const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake) as - | TextChannel - | ThreadChannel - | null; + const channel = pluginData.guild.channels.resolve(savedMessage.channel_id as Snowflake); - if (channel == null) { + if (!channel?.isTextBased()) { return; } diff --git a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts index 36ad96f1..0d077508 100644 --- a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts +++ b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts @@ -1,4 +1,4 @@ -import { BaseGuildTextChannel, GuildTextBasedChannel, Snowflake, ThreadChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; @@ -12,9 +12,11 @@ export async function onMessageDeleteBulk(pluginData: GuildPluginData `\`${item.user_id}\``))); diff --git a/backend/src/plugins/Logs/util/onMessageUpdate.ts b/backend/src/plugins/Logs/util/onMessageUpdate.ts index 13d611ed..72c2faca 100644 --- a/backend/src/plugins/Logs/util/onMessageUpdate.ts +++ b/backend/src/plugins/Logs/util/onMessageUpdate.ts @@ -1,9 +1,7 @@ -import { BaseGuildTextChannel, GuildTextBasedChannel, MessageEmbed, Snowflake, ThreadChannel } from "discord.js"; +import { GuildTextBasedChannel, MessageEmbed, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import cloneDeep from "lodash.clonedeep"; -import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { LogType } from "../../../data/LogType"; import { resolveUser } from "../../../utils"; import { LogsPluginType } from "../types"; import { logMessageEdit } from "../logFunctions/logMessageEdit"; diff --git a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts index c8a603e1..eb529ffa 100644 --- a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts +++ b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts @@ -5,7 +5,6 @@ import { SaveMessagesToDBCmd } from "./commands/SaveMessagesToDB"; import { SavePinsToDBCmd } from "./commands/SavePinsToDB"; import { MessageCreateEvt, MessageDeleteBulkEvt, MessageDeleteEvt, MessageUpdateEvt } from "./events/SaveMessagesEvts"; import { ConfigSchema, MessageSaverPluginType } from "./types"; -import { Queue } from "../../Queue"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts b/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts index 8b279129..594e2b53 100644 --- a/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts +++ b/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts @@ -1,9 +1,7 @@ -import { Constants, Message, MessageType, Snowflake } from "discord.js"; +import { Message, MessageType } from "discord.js"; import { messageSaverEvt } from "../types"; -import { SECONDS } from "../../../utils"; -import moment from "moment-timezone"; -const AFFECTED_MESSAGE_TYPES: MessageType[] = ["DEFAULT", "REPLY", "APPLICATION_COMMAND"]; +const AFFECTED_MESSAGE_TYPES: MessageType[] = [MessageType.Default, MessageType.Reply, MessageType.ChatInputCommand]; export const MessageCreateEvt = messageSaverEvt({ event: "messageCreate", diff --git a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts index e4206fce..750ab632 100644 --- a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts @@ -1,10 +1,10 @@ -import { Message, Snowflake, TextChannel, ThreadChannel } from "discord.js"; +import { GuildTextBasedChannel, Message } from "discord.js"; import { GuildPluginData } from "knub"; import { MessageSaverPluginType } from "./types"; export async function saveMessagesToDB( pluginData: GuildPluginData, - channel: TextChannel | ThreadChannel, + channel: GuildTextBasedChannel, ids: string[], ) { const failed: string[] = []; diff --git a/backend/src/plugins/MessageSaver/types.ts b/backend/src/plugins/MessageSaver/types.ts index d698be6f..588df88f 100644 --- a/backend/src/plugins/MessageSaver/types.ts +++ b/backend/src/plugins/MessageSaver/types.ts @@ -1,7 +1,6 @@ import * as t from "io-ts"; import { BasePluginType, guildPluginMessageCommand, guildPluginEventListener } from "knub"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { Queue } from "../../Queue"; export const ConfigSchema = t.type({ can_manage: t.boolean, diff --git a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts index b28b1eeb..b65f69a1 100644 --- a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts @@ -1,8 +1,6 @@ -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; -import { LogType } from "../../../data/LogType"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../utils"; diff --git a/backend/src/plugins/ModActions/commands/BanCmd.ts b/backend/src/plugins/ModActions/commands/BanCmd.ts index 0371a3df..03aa6d14 100644 --- a/backend/src/plugins/ModActions/commands/BanCmd.ts +++ b/backend/src/plugins/ModActions/commands/BanCmd.ts @@ -1,9 +1,7 @@ import humanizeDuration from "humanize-duration"; import { getMemberLevel } from "knub/dist/helpers"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../utils"; diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts index 60f11c29..5b0e3273 100644 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts @@ -1,4 +1,4 @@ -import { EmbedData, MessageCreateOptions, User } from "discord.js"; +import { APIEmbed, User } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { emptyEmbedValue, resolveUser, trimLines } from "../../../utils"; @@ -54,10 +54,10 @@ export const CasesModCmd = modActionsCmd({ const lastCaseNum = page * casesPerPage; const title = `Most recent cases ${firstCaseNum}-${lastCaseNum} of ${totalCases} by ${modName}`; - const embed: EmbedData = { + const embed = { author: { name: title, - iconURL: mod instanceof User ? mod.displayAvatarURL() : undefined, + icon_url: mod instanceof User ? mod.displayAvatarURL() : undefined, }, fields: [ ...getChunkedEmbedFields(emptyEmbedValue, lines.join("\n")), @@ -69,7 +69,7 @@ export const CasesModCmd = modActionsCmd({ `), }, ], - }; + } satisfies APIEmbed; return { embeds: [embed] }; }, diff --git a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts index 56777088..7a8aa89b 100644 --- a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts @@ -1,4 +1,4 @@ -import { EmbedData, User } from "discord.js"; +import { APIEmbed, User } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; @@ -116,19 +116,19 @@ export const CasesUserCmd = modActionsCmd({ const chunkStart = i * linesPerChunk + 1; const chunkEnd = Math.min((i + 1) * linesPerChunk, lines.length); - const embed: EmbedData = { + const embed = { author: { name: lineChunks.length === 1 ? `Cases for ${userName} (${lines.length} total)` : `Cases ${chunkStart}–${chunkEnd} of ${lines.length} for ${userName}`, - iconURL: user instanceof User ? user.displayAvatarURL() : undefined, + icon_url: user instanceof User ? user.displayAvatarURL() : undefined, }, fields: [ ...getChunkedEmbedFields(emptyEmbedValue, linesInChunk.join("\n")), ...(isLastChunk ? [footerField] : []), ], - }; + } satisfies APIEmbed; msg.channel.send({ embeds: [embed] }); } diff --git a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts index 352b6d00..823bc726 100644 --- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts @@ -1,11 +1,8 @@ -import { TextChannel } from "discord.js"; import { helpers } from "knub"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { Case } from "../../../data/entities/Case"; -import { LogType } from "../../../data/LogType"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { SECONDS, stripObjectToScalars, trimLines } from "../../../utils"; +import { SECONDS, trimLines } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; @@ -54,12 +51,7 @@ export const DeleteCaseCmd = modActionsCmd({ content: "Delete the following case? Answer 'Yes' to continue, 'No' to cancel.", }); - const reply = await helpers.waitForReply( - pluginData.client, - message.channel as TextChannel, - message.author.id, - 15 * SECONDS, - ); + const reply = await helpers.waitForReply(pluginData.client, message.channel, message.author.id, 15 * SECONDS); const normalizedReply = (reply?.content || "").toLowerCase().trim(); if (normalizedReply !== "yes" && normalizedReply !== "y") { message.channel.send("Cancelled. Case was not deleted."); diff --git a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts index 1df592b6..e323eb25 100644 --- a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts @@ -1,11 +1,10 @@ import { Snowflake } from "discord.js"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { resolveMember, resolveUser } from "../../../utils"; +import { DAYS, MINUTES, resolveMember, resolveUser } from "../../../utils"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { ignoreEvent } from "../functions/ignoreEvent"; import { isBanned } from "../functions/isBanned"; @@ -70,7 +69,7 @@ export const ForcebanCmd = modActionsCmd({ try { // FIXME: Use banUserId()? await pluginData.guild.bans.create(user.id as Snowflake, { - days: 1, + deleteMessageSeconds: (1 * DAYS) / MINUTES, reason: reason ?? undefined, }); } catch { diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts index 8f0482e9..d554bbba 100644 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts @@ -1,14 +1,13 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; import { performance } from "perf_hooks"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; import { humanizeDurationShort } from "../../../humanizeDurationShort"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { MINUTES, noop } from "../../../utils"; +import { DAYS, MINUTES, SECONDS, noop } from "../../../utils"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { ignoreEvent } from "../functions/ignoreEvent"; import { IgnoredEventType, modActionsCmd } from "../types"; @@ -34,7 +33,7 @@ export const MassbanCmd = modActionsCmd({ // Ask for ban reason (cleaner this way instead of trying to cram it into the args) msg.channel.send("Ban reason? `cancel` to cancel"); - const banReasonReply = await waitForReply(pluginData.client, msg.channel as TextChannel, msg.author.id); + const banReasonReply = await waitForReply(pluginData.client, msg.channel, msg.author.id); if (!banReasonReply || !banReasonReply.content || banReasonReply.content.toLowerCase().trim() === "cancel") { sendErrorMessage(pluginData, msg.channel, "Cancelled"); return; @@ -95,8 +94,8 @@ export const MassbanCmd = modActionsCmd({ pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, userId, 30 * MINUTES); await pluginData.guild.bans.create(userId as Snowflake, { - days: deleteDays, - reason: banReason ?? undefined, + deleteMessageSeconds: (deleteDays * DAYS) / SECONDS, + reason: banReason, }); await casesPlugin.createCase({ diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts index 83044c85..eb44f9c2 100644 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts @@ -1,6 +1,5 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; @@ -32,7 +31,7 @@ export const MassunbanCmd = modActionsCmd({ // Ask for unban reason (cleaner this way instead of trying to cram it into the args) msg.channel.send("Unban reason? `cancel` to cancel"); - const unbanReasonReply = await waitForReply(pluginData.client, msg.channel as TextChannel, msg.author.id); + const unbanReasonReply = await waitForReply(pluginData.client, msg.channel, msg.author.id); if (!unbanReasonReply || !unbanReasonReply.content || unbanReasonReply.content.toLowerCase().trim() === "cancel") { sendErrorMessage(pluginData, msg.channel, "Cancelled"); return; diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts index ecd696df..8146b069 100644 --- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts @@ -1,6 +1,5 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import { waitForReply } from "knub/dist/helpers"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; @@ -30,7 +29,7 @@ export const MassmuteCmd = modActionsCmd({ // Ask for mute reason msg.channel.send("Mute reason? `cancel` to cancel"); - const muteReasonReceived = await waitForReply(pluginData.client, msg.channel as TextChannel, msg.author.id); + const muteReasonReceived = await waitForReply(pluginData.client, msg.channel, msg.author.id); if ( !muteReasonReceived || !muteReasonReceived.content || diff --git a/backend/src/plugins/ModActions/commands/NoteCmd.ts b/backend/src/plugins/ModActions/commands/NoteCmd.ts index 569831a8..80bf63a9 100644 --- a/backend/src/plugins/ModActions/commands/NoteCmd.ts +++ b/backend/src/plugins/ModActions/commands/NoteCmd.ts @@ -1,7 +1,5 @@ -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { resolveUser } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; diff --git a/backend/src/plugins/ModActions/commands/UnbanCmd.ts b/backend/src/plugins/ModActions/commands/UnbanCmd.ts index 2c9bbfd3..f883ccd6 100644 --- a/backend/src/plugins/ModActions/commands/UnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnbanCmd.ts @@ -1,5 +1,4 @@ import { Snowflake } from "discord.js"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/ModActions/commands/WarnCmd.ts b/backend/src/plugins/ModActions/commands/WarnCmd.ts index 03d79b76..c15c82ca 100644 --- a/backend/src/plugins/ModActions/commands/WarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/WarnCmd.ts @@ -1,4 +1,3 @@ -import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CaseTypes } from "../../../data/CaseTypes"; import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; @@ -94,7 +93,7 @@ export const WarnCmd = modActionsCmd({ ppId: mod.id !== msg.author.id ? msg.author.id : undefined, reason, }, - retryPromptChannel: msg.channel as TextChannel, + retryPromptChannel: msg.channel, }); if (warnResult.status === "failed") { diff --git a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts index 148ebd5b..dc57f88f 100644 --- a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts @@ -1,8 +1,7 @@ -import { GuildAuditLogs, User } from "discord.js"; +import { AuditLogEvent, User } from "discord.js"; import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; -import { LogType } from "../../../data/LogType"; import { resolveUser, UnknownUser } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; @@ -24,7 +23,11 @@ export const CreateBanCaseOnManualBanEvt = modActionsEvt({ return; } - const relevantAuditLogEntry = await findMatchingAuditLogEntry(pluginData.guild, "MEMBER_BAN_ADD", user.id); + const relevantAuditLogEntry = await findMatchingAuditLogEntry( + pluginData.guild, + AuditLogEvent.MemberBanAdd, + user.id, + ); const casesPlugin = pluginData.getPlugin(CasesPlugin); diff --git a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts index b2a7f822..73d99ccf 100644 --- a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts @@ -1,8 +1,6 @@ -import { GuildAuditLogs, User } from "discord.js"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; +import { User } from "discord.js"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; -import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { resolveUser, UnknownUser } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; @@ -24,7 +22,7 @@ export const CreateKickCaseOnManualKickEvt = modActionsEvt({ return; } - const kickAuditLogEntry = await findMatchingAuditLogEntry(pluginData.guild, "MEMBER_KICK", member.id); + const kickAuditLogEntry = await findMatchingAuditLogEntry(pluginData.guild, AuditLogEvent.MemberKick, member.id); let mod: User | UnknownUser | null = null; let createdCase: Case | null = null; diff --git a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts index 3498f834..d6856d49 100644 --- a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts @@ -1,8 +1,6 @@ -import { GuildAuditLogs, User } from "discord.js"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; +import { AuditLogEvent, User } from "discord.js"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; -import { LogType } from "../../../data/LogType"; import { resolveUser, UnknownUser } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; @@ -24,7 +22,11 @@ export const CreateUnbanCaseOnManualUnbanEvt = modActionsEvt({ return; } - const relevantAuditLogEntry = await findMatchingAuditLogEntry(pluginData.guild, "MEMBER_BAN_REMOVE", user.id); + const relevantAuditLogEntry = await findMatchingAuditLogEntry( + pluginData.guild, + AuditLogEvent.MemberBanRemove, + user.id, + ); const casesPlugin = pluginData.getPlugin(CasesPlugin); diff --git a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts index 73a8b3ec..d64ec08b 100644 --- a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts +++ b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts @@ -1,5 +1,4 @@ import { PermissionsBitField, Snowflake, TextChannel } from "discord.js"; -import { LogType } from "../../../data/LogType"; import { resolveMember } from "../../../utils"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; import { LogsPlugin } from "../../Logs/LogsPlugin"; diff --git a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts index 92178edc..fdc28173 100644 --- a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts @@ -1,9 +1,9 @@ -import { GuildMember, TextChannel, ThreadChannel } from "discord.js"; +import { GuildMember, GuildTextBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { hasPermission } from "knub/dist/helpers"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { errorMessage, resolveMember, resolveUser } from "../../../utils"; +import { DAYS, SECONDS, errorMessage, resolveMember, resolveUser } from "../../../utils"; import { IgnoredEventType, ModActionsPluginType } from "../types"; import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; import { ignoreEvent } from "./ignoreEvent"; @@ -19,7 +19,7 @@ export async function actualKickMemberCmd( reason: string; mod: GuildMember; notify?: string; - "notify-channel"?: TextChannel | ThreadChannel; + "notify-channel"?: GuildTextBasedChannel; clean?: boolean; }, ) { @@ -82,7 +82,7 @@ export async function actualKickMemberCmd( ignoreEvent(pluginData, IgnoredEventType.Ban, memberToKick.id); try { - await memberToKick.ban({ days: 1, reason: "kick -clean" }); + await memberToKick.ban({ deleteMessageSeconds: (1 * DAYS) / SECONDS, reason: "kick -clean" }); } catch { sendErrorMessage(pluginData, msg.channel, "Failed to ban the user to clean messages (-clean)"); } diff --git a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts index 6a750fd5..fce169b7 100644 --- a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts @@ -1,4 +1,4 @@ -import { GuildMember, Message, TextChannel, ThreadChannel, User } from "discord.js"; +import { GuildMember, GuildTextBasedChannel, Message, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { logger } from "../../../logger"; @@ -24,7 +24,7 @@ export async function actualMuteUserCmd( reason?: string; mod: GuildMember; notify?: string; - "notify-channel"?: TextChannel | ThreadChannel; + "notify-channel"?: GuildTextBasedChannel; }, ) { // The moderator who did the action is the message author or, if used, the specified -mod @@ -33,7 +33,7 @@ export async function actualMuteUserCmd( if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "You don't have permission to use -mod"); + sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); return; } @@ -51,7 +51,7 @@ export async function actualMuteUserCmd( try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - sendErrorMessage(pluginData, msg.channel as TextChannel, e.message); + sendErrorMessage(pluginData, msg.channel, e.message); return; } @@ -65,9 +65,9 @@ export async function actualMuteUserCmd( }); } catch (e) { if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not mute the user: no mute role set in config"); + sendErrorMessage(pluginData, msg.channel, "Could not mute the user: no mute role set in config"); } else if (isDiscordAPIError(e) && e.code === 10007) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not mute the user: unknown member"); + sendErrorMessage(pluginData, msg.channel, "Could not mute the user: unknown member"); } else { logger.error(`Failed to mute user ${user.id}: ${e.stack}`); if (user.id == null) { @@ -75,14 +75,14 @@ export async function actualMuteUserCmd( // tslint:disable-next-line:no-console console.trace("[DEBUG] Null user.id for mute"); } - sendErrorMessage(pluginData, msg.channel as TextChannel, "Could not mute the user"); + sendErrorMessage(pluginData, msg.channel, "Could not mute the user"); } return; } // Confirm the action to the moderator - let response; + let response: string; if (args.time) { if (muteResult.updatedExistingMute) { response = asSingleLine(` @@ -110,5 +110,5 @@ export async function actualMuteUserCmd( } if (muteResult.notifyResult.text) response += ` (${muteResult.notifyResult.text})`; - sendSuccessMessage(pluginData, msg.channel as TextChannel, response); + sendSuccessMessage(pluginData, msg.channel, response); } diff --git a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts index 46ab7be6..ee1557eb 100644 --- a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts @@ -1,4 +1,4 @@ -import { GuildMember, Message, TextChannel, User } from "discord.js"; +import { GuildMember, Message, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; @@ -19,7 +19,7 @@ export async function actualUnmuteCmd( if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg, channelId: msg.channel.id }))) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "You don't have permission to use -mod"); + sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); return; } @@ -37,7 +37,7 @@ export async function actualUnmuteCmd( }); if (!result) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "User is not muted!"); + sendErrorMessage(pluginData, msg.channel, "User is not muted!"); return; } @@ -46,7 +46,7 @@ export async function actualUnmuteCmd( const timeUntilUnmute = args.time && humanizeDuration(args.time); sendSuccessMessage( pluginData, - msg.channel as TextChannel, + msg.channel, asSingleLine(` Unmuting **${user.tag}** in ${timeUntilUnmute} (Case #${result.case.case_number}) @@ -55,7 +55,7 @@ export async function actualUnmuteCmd( } else { sendSuccessMessage( pluginData, - msg.channel as TextChannel, + msg.channel, asSingleLine(` Unmuted **${user.tag}** (Case #${result.case.case_number}) diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts index 9833ce2c..364c43a8 100644 --- a/backend/src/plugins/ModActions/functions/banUserId.ts +++ b/backend/src/plugins/ModActions/functions/banUserId.ts @@ -8,9 +8,10 @@ import { logger } from "../../../logger"; import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter"; import { createUserNotificationError, + DAYS, notifyUser, resolveUser, - stripObjectToScalars, + SECONDS, ucfirst, UserNotificationResult, } from "../../../utils"; @@ -87,7 +88,7 @@ export async function banUserId( try { const deleteMessageDays = Math.min(7, Math.max(0, banOptions.deleteMessageDays ?? 1)); await pluginData.guild.bans.create(userId as Snowflake, { - days: deleteMessageDays, + deleteMessageSeconds: (deleteMessageDays * DAYS) / SECONDS, reason: reason ?? undefined, }); } catch (e) { diff --git a/backend/src/plugins/ModActions/functions/clearTempban.ts b/backend/src/plugins/ModActions/functions/clearTempban.ts index 00ef5849..c6ab0ad1 100644 --- a/backend/src/plugins/ModActions/functions/clearTempban.ts +++ b/backend/src/plugins/ModActions/functions/clearTempban.ts @@ -5,7 +5,7 @@ import moment from "moment-timezone"; import { LogType } from "src/data/LogType"; import { logger } from "src/logger"; import { CaseTypes } from "../../../data/CaseTypes"; -import { resolveUser, SECONDS } from "../../../utils"; +import { resolveUser } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../types"; import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; diff --git a/backend/src/plugins/ModActions/functions/isBanned.ts b/backend/src/plugins/ModActions/functions/isBanned.ts index 819c3a85..839adf8d 100644 --- a/backend/src/plugins/ModActions/functions/isBanned.ts +++ b/backend/src/plugins/ModActions/functions/isBanned.ts @@ -1,6 +1,5 @@ import { PermissionsBitField, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; import { isDiscordAPIError, isDiscordHTTPError, SECONDS, sleep } from "../../../utils"; import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; import { LogsPlugin } from "../../Logs/LogsPlugin"; diff --git a/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts b/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts index 7d601508..a9503333 100644 --- a/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts +++ b/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts @@ -1,9 +1,9 @@ -import { TextChannel, ThreadChannel } from "discord.js"; +import { GuildTextBasedChannel } from "discord.js"; import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils"; export function readContactMethodsFromArgs(args: { notify?: string; - "notify-channel"?: TextChannel | ThreadChannel; + "notify-channel"?: GuildTextBasedChannel; }): null | UserNotificationMethod[] { if (args.notify) { if (args.notify === "dm") { diff --git a/backend/src/plugins/ModActions/functions/updateCase.ts b/backend/src/plugins/ModActions/functions/updateCase.ts index 2a1974be..4c1c48a2 100644 --- a/backend/src/plugins/ModActions/functions/updateCase.ts +++ b/backend/src/plugins/ModActions/functions/updateCase.ts @@ -1,7 +1,6 @@ -import { Message, TextChannel } from "discord.js"; +import { Message } from "discord.js"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; -import { LogType } from "../../../data/LogType"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; @@ -16,12 +15,12 @@ export async function updateCase(pluginData, msg: Message, args) { } if (!theCase) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Case not found"); + sendErrorMessage(pluginData, msg.channel, "Case not found"); return; } if (!args.note && msg.attachments.size === 0) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Text or attachment required"); + sendErrorMessage(pluginData, msg.channel, "Text or attachment required"); return; } @@ -41,5 +40,5 @@ export async function updateCase(pluginData, msg: Message, args) { note, }); - sendSuccessMessage(pluginData, msg.channel as TextChannel, `Case \`#${theCase.case_number}\` updated`); + sendSuccessMessage(pluginData, msg.channel, `Case \`#${theCase.case_number}\` updated`); } diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts index e0f22c8f..515651fb 100644 --- a/backend/src/plugins/ModActions/functions/warnMember.ts +++ b/backend/src/plugins/ModActions/functions/warnMember.ts @@ -1,8 +1,7 @@ import { GuildMember, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter"; import { createUserNotificationError, notifyUser, resolveUser, ucfirst, UserNotificationResult } from "../../../utils"; import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index cf7ce81b..b2e10338 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -1,4 +1,4 @@ -import { TextChannel } from "discord.js"; +import { GuildTextBasedChannel } from "discord.js"; import { EventEmitter } from "events"; import * as t from "io-ts"; import { BasePluginType, guildPluginMessageCommand, guildPluginEventListener } from "knub"; @@ -11,8 +11,6 @@ import { Queue } from "../../Queue"; import { tNullable, UserNotificationMethod, UserNotificationResult } from "../../utils"; import { CaseArgs } from "../Cases/types"; -import Timeout = NodeJS.Timeout; - export const ConfigSchema = t.type({ dm_on_warn: t.boolean, dm_on_kick: t.boolean, @@ -129,7 +127,7 @@ export type WarnMemberNotifyRetryCallback = () => boolean | Promise; export interface WarnOptions { caseArgs?: Partial | null; contactMethods?: UserNotificationMethod[] | null; - retryPromptChannel?: TextChannel | null; + retryPromptChannel?: GuildTextBasedChannel | null; isAutomodAction?: boolean; } diff --git a/backend/src/plugins/Mutes/MutesPlugin.ts b/backend/src/plugins/Mutes/MutesPlugin.ts index eba6b40f..3df08168 100644 --- a/backend/src/plugins/Mutes/MutesPlugin.ts +++ b/backend/src/plugins/Mutes/MutesPlugin.ts @@ -13,7 +13,6 @@ import { ClearMutesCmd } from "./commands/ClearMutesCmd"; import { ClearMutesWithoutRoleCmd } from "./commands/ClearMutesWithoutRoleCmd"; import { MutesCmd } from "./commands/MutesCmd"; import { ClearActiveMuteOnMemberBanEvt } from "./events/ClearActiveMuteOnMemberBanEvt"; -import { ClearActiveMuteOnRoleRemovalEvt } from "./events/ClearActiveMuteOnRoleRemovalEvt"; import { ReapplyActiveMuteOnJoinEvt } from "./events/ReapplyActiveMuteOnJoinEvt"; import { muteUser } from "./functions/muteUser"; import { offMutesEvent } from "./functions/offMutesEvent"; diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts index cd18bf0f..29f9dc28 100644 --- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts @@ -1,4 +1,4 @@ -import { Snowflake, User } from "discord.js"; +import { Snowflake } from "discord.js"; import { sendSuccessMessage } from "../../../pluginUtils"; import { mutesCmd } from "../types"; diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 5c4e9d3a..fa11ba54 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -1,4 +1,11 @@ -import { GuildMember, MessageActionRow, MessageButton, MessageComponentInteraction, Snowflake } from "discord.js"; +import { + GuildMember, + MessageComponentInteraction, + Snowflake, + ButtonBuilder, + ButtonStyle, + ActionRowBuilder, +} from "discord.js"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { humanizeDurationShort } from "../../../humanizeDurationShort"; @@ -192,13 +199,12 @@ export const MutesCmd = mutesCmd({ if (totalPages > 1) { const idMod = `${listMessage.id}:muteList`; - const buttons: MessageButton[] = []; + const buttons = [ + new ButtonBuilder().setStyle(ButtonStyle.Secondary).setEmoji("⬅").setCustomId(`previousButton:${idMod}`), + new ButtonBuilder().setStyle(ButtonStyle.Secondary).setEmoji("➡").setCustomId(`nextButton:${idMod}`), + ] satisfies ButtonBuilder[]; - buttons.push(new MessageButton().setStyle("SECONDARY").setEmoji("⬅").setCustomId(`previousButton:${idMod}`)); - - buttons.push(new MessageButton().setStyle("SECONDARY").setEmoji("➡").setCustomId(`nextButton:${idMod}`)); - - const row = new MessageActionRow().addComponents(buttons); + const row = new ActionRowBuilder().addComponents(buttons); await listMessage.edit({ components: [row] }); const collector = listMessage.createMessageComponentCollector({ time: stopCollectionDebounce }); diff --git a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts index 20611e45..86605905 100644 --- a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts +++ b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts @@ -1,6 +1,4 @@ import { Snowflake } from "discord.js"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogType } from "../../../data/LogType"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; import { mutesEvt } from "../types"; import { LogsPlugin } from "../../Logs/LogsPlugin"; diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index a6293db1..fd836e9e 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel, User } from "discord.js"; +import { Snowflake, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; diff --git a/backend/src/plugins/Mutes/functions/unmuteUser.ts b/backend/src/plugins/Mutes/functions/unmuteUser.ts index a3c55b08..48bad17b 100644 --- a/backend/src/plugins/Mutes/functions/unmuteUser.ts +++ b/backend/src/plugins/Mutes/functions/unmuteUser.ts @@ -1,11 +1,8 @@ import { Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; import { resolveMember, resolveUser } from "../../../utils"; -import { memberRolesLock } from "../../../utils/lockNameHelpers"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { CaseArgs } from "../../Cases/types"; import { MutesPluginType, UnmuteResult } from "../types"; diff --git a/backend/src/plugins/Mutes/types.ts b/backend/src/plugins/Mutes/types.ts index a447300e..e634adec 100644 --- a/backend/src/plugins/Mutes/types.ts +++ b/backend/src/plugins/Mutes/types.ts @@ -11,8 +11,6 @@ import { GuildMutes } from "../../data/GuildMutes"; import { tNullable, UserNotificationMethod, UserNotificationResult } from "../../utils"; import { CaseArgs } from "../Cases/types"; -import Timeout = NodeJS.Timeout; - export const ConfigSchema = t.type({ mute_role: tNullable(t.string), move_to_voice_channel: tNullable(t.string), diff --git a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts index 0efb5fe3..e59bea50 100644 --- a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts +++ b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts @@ -4,7 +4,6 @@ import { UsernameHistory } from "../../data/UsernameHistory"; import { Queue } from "../../Queue"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { NamesCmd } from "./commands/NamesCmd"; -import { ChannelJoinEvt, MessageCreateEvt } from "./events/UpdateNameEvts"; import { ConfigSchema, NameHistoryPluginType } from "./types"; const defaultOptions: PluginOptions = { diff --git a/backend/src/plugins/Persist/events/LoadDataEvt.ts b/backend/src/plugins/Persist/events/LoadDataEvt.ts index 7052f74b..002771ad 100644 --- a/backend/src/plugins/Persist/events/LoadDataEvt.ts +++ b/backend/src/plugins/Persist/events/LoadDataEvt.ts @@ -1,7 +1,5 @@ -import { GuildMemberEditData, PermissionsBitField } from "discord.js"; +import { PermissionFlagsBits, GuildMemberEditOptions } from "discord.js"; import intersection from "lodash.intersection"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogType } from "../../../data/LogType"; import { canAssignRole } from "../../../utils/canAssignRole"; import { getMissingPermissions } from "../../../utils/getMissingPermissions"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; @@ -9,7 +7,7 @@ import { missingPermissionError } from "../../../utils/missingPermissionError"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { persistEvt } from "../types"; -const p = PermissionsBitField.Flags; +const p = PermissionFlagsBits; export const LoadDataEvt = persistEvt({ event: "guildMemberAdd", @@ -26,7 +24,9 @@ export const LoadDataEvt = persistEvt({ return; } - const toRestore: GuildMemberEditData = {}; + const toRestore: GuildMemberEditOptions = { + reason: "Restored upon rejoin", + }; const config = await pluginData.config.getForMember(member); const restoredData: string[] = []; @@ -73,7 +73,7 @@ export const LoadDataEvt = persistEvt({ } if (restoredData.length) { - await member.edit(toRestore, "Restored upon rejoin"); + await member.edit(toRestore); await pluginData.state.persistedData.clear(member.id); pluginData.getPlugin(LogsPlugin).logMemberRestore({ diff --git a/backend/src/plugins/Phisherman/PhishermanPlugin.ts b/backend/src/plugins/Phisherman/PhishermanPlugin.ts index 7ed9a255..f9b3de3f 100644 --- a/backend/src/plugins/Phisherman/PhishermanPlugin.ts +++ b/backend/src/plugins/Phisherman/PhishermanPlugin.ts @@ -1,13 +1,7 @@ -import { PluginOptions, guildPluginMessageCommand } from "knub"; -import { GuildPingableRoles } from "../../data/GuildPingableRoles"; +import { PluginOptions } from "knub"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { ConfigSchema, PhishermanPluginType } from "./types"; -import { - getPhishermanDomainInfo, - hasPhishermanMasterAPIKey, - phishermanApiKeyIsValid, - reportTrackedDomainsToPhisherman, -} from "../../data/Phisherman"; +import { hasPhishermanMasterAPIKey, phishermanApiKeyIsValid } from "../../data/Phisherman"; import { mapToPublicFn } from "../../pluginUtils"; import { getDomainInfo } from "./functions/getDomainInfo"; import { pluginInfo } from "./info"; diff --git a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts index e1492f9e..56794474 100644 --- a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts +++ b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts @@ -3,7 +3,6 @@ import { GuildPingableRoles } from "../../data/GuildPingableRoles"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { PingableRoleDisableCmd } from "./commands/PingableRoleDisableCmd"; import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd"; -import { MessageCreateDisablePingableEvt, TypingEnablePingableEvt } from "./events/ChangePingableEvts"; import { ConfigSchema, PingableRolesPluginType } from "./types"; const defaultOptions: PluginOptions = { diff --git a/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts b/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts index 8153f094..f91b7264 100644 --- a/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts +++ b/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts @@ -10,7 +10,7 @@ export const TypingEnablePingableEvt = pingableRolesEvt({ async listener(meta) { const pluginData = meta.pluginData; - const channel = meta.args.channel; + const channel = meta.args.typing.channel; const pingableRoles = await getPingableRolesForChannel(pluginData, channel.id); if (pingableRoles.length === 0) return; diff --git a/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts b/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts index 8730b588..b417ecdf 100644 --- a/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts +++ b/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts @@ -11,11 +11,6 @@ export function disablePingableRoles( const role = pluginData.guild.roles.cache.get(pingableRole.role_id as Snowflake); if (!role) continue; - role.edit( - { - mentionable: false, - }, - "Disable pingable role", - ); + role.setMentionable(false, "Disable pingable role"); } } diff --git a/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts b/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts index a7c40e78..7aec4df4 100644 --- a/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts +++ b/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts @@ -11,11 +11,6 @@ export function enablePingableRoles( const role = pluginData.guild.roles.cache.get(pingableRole.role_id as Snowflake); if (!role) continue; - role.edit( - { - mentionable: true, - }, - "Enable pingable role", - ); + role.setMentionable(true, "Enable pingable role"); } } diff --git a/backend/src/plugins/Post/commands/EditCmd.ts b/backend/src/plugins/Post/commands/EditCmd.ts index 317bb1ec..47ae07d7 100644 --- a/backend/src/plugins/Post/commands/EditCmd.ts +++ b/backend/src/plugins/Post/commands/EditCmd.ts @@ -1,4 +1,3 @@ -import { Snowflake, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { postCmd } from "../types"; diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts index c0d1d30e..7e446c69 100644 --- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts @@ -1,4 +1,4 @@ -import { MessageEmbed, Snowflake, TextChannel } from "discord.js"; +import { APIEmbed } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { trimLines } from "../../../utils"; @@ -42,7 +42,7 @@ export const EditEmbedCmd = postCmd({ return; } - const embed = (targetMessage.embeds![0] ?? { fields: [] }) as MessageEmbed; + const embed = (targetMessage.embeds![0] ?? { fields: [] }) as APIEmbed; if (args.title) embed.title = args.title; if (content) embed.description = formatContent(content); if (color) embed.color = color; diff --git a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts index c1a92510..990bfbae 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts @@ -1,4 +1,3 @@ -import { TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { sorter } from "../../../utils"; @@ -22,6 +21,6 @@ export const ScheduledPostsShowCmd = postCmd({ return; } - postMessage(pluginData, msg.channel as TextChannel, post.content, post.attachments, post.enable_mentions); + postMessage(pluginData, msg.channel, post.content, post.attachments, post.enable_mentions); }, }); diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index ba6e668b..6604a317 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -1,9 +1,7 @@ -import { Channel, GuildTextBasedChannel, Message, NewsChannel, TextChannel, ThreadChannel } from "discord.js"; +import { GuildTextBasedChannel, Message } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogType } from "../../../data/LogType"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { DBDateFormat, errorMessage, MINUTES, StrictMessageContent } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; @@ -42,19 +40,11 @@ export async function actualPostCmd( if (opts.repeat) { if (opts.repeat < MIN_REPEAT_TIME) { - sendErrorMessage( - pluginData, - msg.channel as TextChannel, - `Minimum time for -repeat is ${humanizeDuration(MIN_REPEAT_TIME)}`, - ); + sendErrorMessage(pluginData, msg.channel, `Minimum time for -repeat is ${humanizeDuration(MIN_REPEAT_TIME)}`); return; } if (opts.repeat > MAX_REPEAT_TIME) { - sendErrorMessage( - pluginData, - msg.channel as TextChannel, - `Max time for -repeat is ${humanizeDuration(MAX_REPEAT_TIME)}`, - ); + sendErrorMessage(pluginData, msg.channel, `Max time for -repeat is ${humanizeDuration(MAX_REPEAT_TIME)}`); return; } } @@ -65,7 +55,7 @@ export async function actualPostCmd( // Schedule the post to be posted later postAt = await parseScheduleTime(pluginData, msg.author.id, opts.schedule); if (!postAt) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Invalid schedule time"); + sendErrorMessage(pluginData, msg.channel, "Invalid schedule time"); return; } } else if (opts.repeat) { @@ -82,17 +72,17 @@ export async function actualPostCmd( // Invalid time if (!repeatUntil) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Invalid time specified for -repeat-until"); + sendErrorMessage(pluginData, msg.channel, "Invalid time specified for -repeat-until"); return; } if (repeatUntil.isBefore(moment.utc())) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "You can't set -repeat-until in the past"); + sendErrorMessage(pluginData, msg.channel, "You can't set -repeat-until in the past"); return; } if (repeatUntil.isAfter(MAX_REPEAT_UNTIL)) { sendErrorMessage( pluginData, - msg.channel as TextChannel, + msg.channel, "Unfortunately, -repeat-until can only be at most 100 years into the future. Maybe 99 years would be enough?", ); return; @@ -100,26 +90,18 @@ export async function actualPostCmd( } else if (opts["repeat-times"]) { repeatTimes = opts["repeat-times"]; if (repeatTimes <= 0) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "-repeat-times must be 1 or more"); + sendErrorMessage(pluginData, msg.channel, "-repeat-times must be 1 or more"); return; } } if (repeatUntil && repeatTimes) { - sendErrorMessage( - pluginData, - msg.channel as TextChannel, - "You can only use one of -repeat-until or -repeat-times at once", - ); + sendErrorMessage(pluginData, msg.channel, "You can only use one of -repeat-until or -repeat-times at once"); return; } if (opts.repeat && !repeatUntil && !repeatTimes) { - sendErrorMessage( - pluginData, - msg.channel as TextChannel, - "You must specify -repeat-until or -repeat-times for repeated messages", - ); + sendErrorMessage(pluginData, msg.channel, "You must specify -repeat-until or -repeat-times for repeated messages"); return; } @@ -134,7 +116,7 @@ export async function actualPostCmd( // Save schedule/repeat information in DB if (postAt) { if (postAt < moment.utc()) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Post can't be scheduled to be posted in the past"); + sendErrorMessage(pluginData, msg.channel, "Post can't be scheduled to be posted in the past"); return; } @@ -210,6 +192,6 @@ export async function actualPostCmd( } if (targetChannel.id !== msg.channel.id || opts.schedule || opts.repeat) { - sendSuccessMessage(pluginData, msg.channel as TextChannel, successMessage); + sendSuccessMessage(pluginData, msg.channel, successMessage); } } diff --git a/backend/src/plugins/Post/util/postMessage.ts b/backend/src/plugins/Post/util/postMessage.ts index dd5cca03..8fb5ad8c 100644 --- a/backend/src/plugins/Post/util/postMessage.ts +++ b/backend/src/plugins/Post/util/postMessage.ts @@ -1,12 +1,4 @@ -import { - Attachment, - GuildTextBasedChannel, - Message, - MessageOptions, - NewsChannel, - TextChannel, - ThreadChannel, -} from "discord.js"; +import { Attachment, GuildTextBasedChannel, Message, MessageCreateOptions } from "discord.js"; import fs from "fs"; import { GuildPluginData } from "knub"; import { downloadFile } from "../../../utils"; @@ -18,7 +10,7 @@ const fsp = fs.promises; export async function postMessage( pluginData: GuildPluginData, channel: GuildTextBasedChannel, - content: MessageOptions, + content: MessageCreateOptions, attachments: Attachment[] = [], enableMentions: boolean = false, ): Promise { diff --git a/backend/src/plugins/Post/util/postScheduledPost.ts b/backend/src/plugins/Post/util/postScheduledPost.ts index 94959043..4b8d244d 100644 --- a/backend/src/plugins/Post/util/postScheduledPost.ts +++ b/backend/src/plugins/Post/util/postScheduledPost.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel, User } from "discord.js"; +import { Snowflake, User } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { logger } from "../../../logger"; @@ -57,6 +57,7 @@ export async function postScheduledPost(pluginData: GuildPluginData { - const channel = pluginData.guild.channels.cache.get(channelId as Snowflake) as TextChannel; - if (!channel) return; + const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); + if (!channel?.isTextBased()) return; const errors: string[] = []; const logs = pluginData.getPlugin(LogsPlugin); let targetMessage; try { - targetMessage = await channel.messages.fetch(messageId, { force: true }); + targetMessage = await channel.messages.fetch({ message: messageId, force: true }); } catch (e) { if (isDiscordAPIError(e)) { if (e.code === 10008) { diff --git a/backend/src/plugins/Reminders/functions/postReminder.ts b/backend/src/plugins/Reminders/functions/postReminder.ts index b69a073b..6f6c741c 100644 --- a/backend/src/plugins/Reminders/functions/postReminder.ts +++ b/backend/src/plugins/Reminders/functions/postReminder.ts @@ -1,11 +1,10 @@ import { GuildPluginData } from "knub"; import { RemindersPluginType } from "../types"; import { Reminder } from "../../../data/entities/Reminder"; -import { DiscordAPIError, HTTPError, Snowflake, TextChannel } from "discord.js"; +import { HTTPError, Snowflake } from "discord.js"; import moment from "moment-timezone"; import { disableLinkPreviews } from "knub/dist/helpers"; -import { DBDateFormat, isDiscordHTTPError, SECONDS } from "../../../utils"; -import humanizeDuration from "humanize-duration"; +import { DBDateFormat } from "../../../utils"; export async function postReminder(pluginData: GuildPluginData, reminder: Reminder) { const channel = pluginData.guild.channels.cache.get(reminder.channel_id as Snowflake); @@ -34,7 +33,7 @@ export async function postReminder(pluginData: GuildPluginData= 500) { + if (err instanceof HTTPError && err.status >= 500) { // If we get a server error, try again later return; } diff --git a/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts b/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts index f7fc72ea..3eaa4cd1 100644 --- a/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts +++ b/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts @@ -1,6 +1,5 @@ import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { ConfigSchema, RoleButtonsPluginType } from "./types"; -import { mapToPublicFn } from "../../pluginUtils"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { applyAllRoleButtons } from "./functions/applyAllRoleButtons"; import { GuildRoleButtons } from "../../data/GuildRoleButtons"; diff --git a/backend/src/plugins/RoleButtons/functions/applyRoleButtons.ts b/backend/src/plugins/RoleButtons/functions/applyRoleButtons.ts index e8c86f2f..45af1c18 100644 --- a/backend/src/plugins/RoleButtons/functions/applyRoleButtons.ts +++ b/backend/src/plugins/RoleButtons/functions/applyRoleButtons.ts @@ -1,14 +1,10 @@ import { GuildPluginData } from "knub"; import { RoleButtonsPluginType, TRoleButtonsConfigItem } from "../types"; -import { isSnowflake, snowflakeRegex } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { Message, MessageButton, MessageEditOptions, MessageOptions, Snowflake } from "discord.js"; +import { Message, MessageEditOptions, MessageCreateOptions } from "discord.js"; import { RoleButtonsItem } from "../../../data/entities/RoleButtonsItem"; -import { buildCustomId } from "../../../utils/buildCustomId"; import { createButtonComponents } from "./createButtonComponents"; -const channelMessageRegex = new RegExp(`^(${snowflakeRegex.source})-(${snowflakeRegex.source})$`); - export async function applyRoleButtons( pluginData: GuildPluginData, configItem: TRoleButtonsConfigItem, @@ -88,7 +84,7 @@ export async function applyRoleButtons( if (!candidateMessage) { try { - candidateMessage = await channel.send(configItem.message.content as string | MessageOptions); + candidateMessage = await channel.send(configItem.message.content as string | MessageCreateOptions); } catch (err) { pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Error while posting message for role_buttons/${configItem.name}: ${String(err)}`, diff --git a/backend/src/plugins/RoleButtons/functions/convertButtonStyleStringToEnum.ts b/backend/src/plugins/RoleButtons/functions/convertButtonStyleStringToEnum.ts new file mode 100644 index 00000000..18486372 --- /dev/null +++ b/backend/src/plugins/RoleButtons/functions/convertButtonStyleStringToEnum.ts @@ -0,0 +1,17 @@ +import { ButtonStyle } from "discord.js"; +import { TRoleButtonOption } from "../types.js"; + +export function convertButtonStyleStringToEnum(input: TRoleButtonOption["style"]): ButtonStyle | null | undefined { + switch (input) { + case "PRIMARY": + return ButtonStyle.Primary; + case "SECONDARY": + return ButtonStyle.Secondary; + case "SUCCESS": + return ButtonStyle.Success; + case "DANGER": + return ButtonStyle.Danger; + default: + return input; + } +} diff --git a/backend/src/plugins/RoleButtons/functions/createButtonComponents.ts b/backend/src/plugins/RoleButtons/functions/createButtonComponents.ts index 05736484..bd6e0276 100644 --- a/backend/src/plugins/RoleButtons/functions/createButtonComponents.ts +++ b/backend/src/plugins/RoleButtons/functions/createButtonComponents.ts @@ -1,23 +1,22 @@ -import { MessageActionRow, MessageButton, Snowflake } from "discord.js"; -import { chunkArray } from "../../../utils"; -import { RoleButtonsPluginType, TRoleButtonOption, TRoleButtonsConfigItem } from "../types"; +import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js"; +import { TRoleButtonsConfigItem } from "../types"; import { buildCustomId } from "../../../utils/buildCustomId"; -import { GuildPluginData } from "knub"; import { TooManyComponentsError } from "./TooManyComponentsError"; +import { convertButtonStyleStringToEnum } from "./convertButtonStyleStringToEnum.js"; -export function createButtonComponents(configItem: TRoleButtonsConfigItem): MessageActionRow[] { - const rows: MessageActionRow[] = []; +export function createButtonComponents(configItem: TRoleButtonsConfigItem): Array> { + const rows: Array> = []; - let currentRow = new MessageActionRow(); + let currentRow = new ActionRowBuilder(); for (const [index, option] of configItem.options.entries()) { if (currentRow.components.length === 5 || (currentRow.components.length > 0 && option.start_new_row)) { rows.push(currentRow); - currentRow = new MessageActionRow(); + currentRow = new ActionRowBuilder(); } - const button = new MessageButton() + const button = new ButtonBuilder() .setLabel(option.label ?? "") - .setStyle(option.style ?? "PRIMARY") + .setStyle(convertButtonStyleStringToEnum(option.style) ?? ButtonStyle.Primary) .setCustomId(buildCustomId("roleButtons", { name: configItem.name, index })); if (option.emoji) { diff --git a/backend/src/plugins/RoleButtons/types.ts b/backend/src/plugins/RoleButtons/types.ts index e7b4096d..f8bcfcd5 100644 --- a/backend/src/plugins/RoleButtons/types.ts +++ b/backend/src/plugins/RoleButtons/types.ts @@ -2,6 +2,7 @@ import * as t from "io-ts"; import { BasePluginType } from "knub"; import { tMessageContent, tNullable } from "../../utils"; import { GuildRoleButtons } from "../../data/GuildRoleButtons"; +import { ButtonStyle } from "discord.js"; const RoleButtonOption = t.type({ role_id: t.string, @@ -10,6 +11,12 @@ const RoleButtonOption = t.type({ // https://discord.js.org/#/docs/discord.js/v13/typedef/MessageButtonStyle style: tNullable( t.union([ + t.literal(ButtonStyle.Primary), + t.literal(ButtonStyle.Secondary), + t.literal(ButtonStyle.Success), + t.literal(ButtonStyle.Danger), + + // The following are deprecated t.literal("PRIMARY"), t.literal("SECONDARY"), t.literal("SUCCESS"), diff --git a/backend/src/plugins/RoleManager/types.ts b/backend/src/plugins/RoleManager/types.ts index 3494b1ea..54f5033a 100644 --- a/backend/src/plugins/RoleManager/types.ts +++ b/backend/src/plugins/RoleManager/types.ts @@ -1,6 +1,5 @@ import * as t from "io-ts"; -import { BasePluginType, guildPluginMessageCommand } from "knub"; -import { GuildLogs } from "../../data/GuildLogs"; +import { BasePluginType } from "knub"; import { GuildRoleQueue } from "../../data/GuildRoleQueue"; export const ConfigSchema = t.type({}); diff --git a/backend/src/plugins/Roles/commands/AddRoleCmd.ts b/backend/src/plugins/Roles/commands/AddRoleCmd.ts index 23229ca5..708f140b 100644 --- a/backend/src/plugins/Roles/commands/AddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/AddRoleCmd.ts @@ -1,5 +1,4 @@ import { GuildChannel } from "discord.js"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; diff --git a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts index 0b09535c..c5193ce6 100644 --- a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts @@ -1,5 +1,4 @@ import { GuildMember } from "discord.js"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; diff --git a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts index e5cedc42..02931f10 100644 --- a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts @@ -1,5 +1,4 @@ import { GuildMember } from "discord.js"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; diff --git a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts index 63a843c8..0251a4eb 100644 --- a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts @@ -1,5 +1,4 @@ import { GuildChannel } from "discord.js"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts index e1302464..9583d433 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts @@ -1,4 +1,3 @@ -import { TextChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { slowmodeCmd } from "../types"; @@ -13,7 +12,7 @@ export const SlowmodeGetCmd = slowmodeCmd({ }, async run({ message: msg, args, pluginData }) { - const channel = args.channel || (msg.channel as TextChannel); + const channel = args.channel || msg.channel; let currentSlowmode = channel.rateLimitPerUser; let isNative = true; diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index 70f20fbd..44d5c111 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -1,11 +1,4 @@ -import { - ChannelType, - escapeInlineCode, - GuildTextBasedChannel, - PermissionsBitField, - TextChannel, - ThreadChannel, -} from "discord.js"; +import { escapeInlineCode, PermissionsBitField } from "discord.js"; import humanizeDuration from "humanize-duration"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; @@ -29,7 +22,6 @@ export const SlowmodeSetCmd = slowmodeCmd({ permission: "can_manage", source: "guild", - // prettier-ignore signature: [ { time: ct.delay(), @@ -41,11 +33,16 @@ export const SlowmodeSetCmd = slowmodeCmd({ time: ct.delay(), mode: ct.string({ option: true, shortcut: "m" }), - } + }, ], async run({ message: msg, args, pluginData }) { - const channel: GuildTextBasedChannel = args.channel || msg.channel; + const channel = args.channel || msg.channel; + + if (!channel.isTextBased() || channel.isThread()) { + sendErrorMessage(pluginData, msg.channel, "Slowmode can only be set on non-thread text-based channels"); + return; + } if (args.time === 0) { // Workaround until we can call SlowmodeDisableCmd from here @@ -135,9 +132,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ // Set native slowmode try { - await channel.edit({ - rateLimitPerUser: rateLimitSeconds, - }); + await channel.setRateLimitPerUser(rateLimitSeconds); } catch (e) { sendErrorMessage(pluginData, msg.channel, `Failed to set native slowmode: ${escapeInlineCode(e.message)}`); return; @@ -145,9 +140,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ } else { // If there is an existing native slowmode, disable that first if (channel.rateLimitPerUser) { - await channel.edit({ - rateLimitPerUser: 0, - }); + await channel.setRateLimitPerUser(0); } // Set bot-maintained slowmode @@ -155,7 +148,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ // Update cache const slowmode = await pluginData.state.slowmodes.getChannelSlowmode(channel.id); - await pluginData.state.channelSlowmodeCache.set(channel.id, slowmode ?? null); + pluginData.state.channelSlowmodeCache.set(channel.id, slowmode ?? null); } const humanizedSlowmodeTime = humanizeDuration(args.time); diff --git a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts index 09565bae..2bc00bed 100644 --- a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts +++ b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts @@ -1,4 +1,4 @@ -import { Message, TextChannel } from "discord.js"; +import { Message } from "discord.js"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { noop } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; @@ -11,7 +11,7 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { const hasNativeSlowmode = args.channel.rateLimitPerUser; if (!botSlowmode && hasNativeSlowmode === 0) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "Channel is not on slowmode!"); + sendErrorMessage(pluginData, msg.channel, "Channel is not on slowmode!"); return; } @@ -20,7 +20,7 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { if (missingPermissions) { sendErrorMessage( pluginData, - msg.channel as TextChannel, + msg.channel, `Unable to disable slowmode. ${missingPermissionError(missingPermissions)}`, ); return; @@ -43,11 +43,11 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { if (failedUsers.length) { sendSuccessMessage( pluginData, - msg.channel as TextChannel, + msg.channel, `Slowmode disabled! Failed to clear slowmode from the following users:\n\n<@!${failedUsers.join(">\n<@!")}>`, ); } else { - sendSuccessMessage(pluginData, msg.channel as TextChannel, "Slowmode disabled!"); + sendSuccessMessage(pluginData, msg.channel, "Slowmode disabled!"); initMsg.delete().catch(noop); } } diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index 3f4f0c45..85e05016 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -1,6 +1,5 @@ import { GuildChannel, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { isDiscordAPIError, UnknownUser, verboseChannelMention, verboseUserMention } from "../../../utils"; @@ -17,9 +16,9 @@ export async function applyBotSlowmodeToUserId( try { pluginData.state.serverLogs.ignoreLog(LogType.CHANNEL_UPDATE, channel.id, 5 * 1000); if (existingOverride) { - await existingOverride.edit({ SEND_MESSAGES: false }); + await existingOverride.edit({ SendMessages: false }); } else { - await channel.permissionOverwrites?.create(userId as Snowflake, { SEND_MESSAGES: false }, { type: 1 }); + await channel.permissionOverwrites?.create(userId as Snowflake, { SendMessages: false }, { type: 1 }); } } catch (e) { const user = await pluginData.client.users.fetch(userId as Snowflake).catch(() => new UnknownUser({ id: userId })); diff --git a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts index b86862ae..f76c924a 100644 --- a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts +++ b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts @@ -1,11 +1,11 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { AnyThreadChannel, GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../data/LogType"; import { SlowmodePluginType } from "../types"; export async function clearBotSlowmodeFromUserId( pluginData: GuildPluginData, - channel: TextChannel, + channel: Exclude, userId: string, force = false, ) { diff --git a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts index 4dcfe634..fc736528 100644 --- a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts +++ b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts @@ -1,7 +1,5 @@ import { GuildChannel, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogType } from "../../../data/LogType"; import { logger } from "../../../logger"; import { UnknownUser, verboseChannelMention, verboseUserMention } from "../../../utils"; import { SlowmodePluginType } from "../types"; diff --git a/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts b/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts index 7b273c1a..d3292901 100644 --- a/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts +++ b/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts @@ -1,11 +1,11 @@ -import { TextChannel } from "discord.js"; +import { AnyThreadChannel, GuildTextBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { SlowmodePluginType } from "../types"; import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId"; export async function disableBotSlowmodeForChannel( pluginData: GuildPluginData, - channel: TextChannel, + channel: Exclude, ) { // Disable channel slowmode await pluginData.state.slowmodes.deleteChannelSlowmode(channel.id); diff --git a/backend/src/plugins/Slowmode/util/onMessageCreate.ts b/backend/src/plugins/Slowmode/util/onMessageCreate.ts index cfe1af95..b2721ab5 100644 --- a/backend/src/plugins/Slowmode/util/onMessageCreate.ts +++ b/backend/src/plugins/Slowmode/util/onMessageCreate.ts @@ -1,4 +1,4 @@ -import { Snowflake, TextChannel } from "discord.js"; +import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { hasPermission } from "../../../pluginUtils"; @@ -15,8 +15,8 @@ import { SlowmodeChannel } from "../../../data/entities/SlowmodeChannel"; export async function onMessageCreate(pluginData: GuildPluginData, msg: SavedMessage) { if (msg.is_bot) return; - const channel = pluginData.guild.channels.cache.get(msg.channel_id as Snowflake) as TextChannel; - if (!channel) return; + const channel = pluginData.guild.channels.cache.get(msg.channel_id as Snowflake); + if (!channel?.isTextBased()) return; // Don't apply slowmode if the lock was interrupted earlier (e.g. the message was caught by word filters) const thisMsgLock = await pluginData.locks.acquire(messageLock(msg)); diff --git a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts index ab95f5b3..13484855 100644 --- a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts @@ -1,7 +1,6 @@ import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; import { CaseTypes } from "../../../data/CaseTypes"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { LogType } from "../../../data/LogType"; diff --git a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts index 4a1256d1..7bda3cc6 100644 --- a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts @@ -1,7 +1,5 @@ import { GuildPluginData } from "knub"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; diff --git a/backend/src/plugins/Starboard/StarboardPlugin.ts b/backend/src/plugins/Starboard/StarboardPlugin.ts index d6a60a11..c0070791 100644 --- a/backend/src/plugins/Starboard/StarboardPlugin.ts +++ b/backend/src/plugins/Starboard/StarboardPlugin.ts @@ -42,13 +42,13 @@ export const StarboardPlugin = zeppelinGuildPlugin()({ ### Note on emojis 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>" ### Basic starboard Any message on the server that gets 5 star reactions will be posted into the starboard channel (604342689038729226). - + ~~~yml starboard: config: @@ -57,10 +57,10 @@ export const StarboardPlugin = zeppelinGuildPlugin()({ channel_id: "604342689038729226" stars_required: 5 ~~~ - + ### Basic starboard with custom color Any message on the server that gets 5 star reactions will be posted into the starboard channel (604342689038729226), with the given color (0x87CEEB). - + ~~~yml starboard: config: @@ -70,10 +70,10 @@ export const StarboardPlugin = zeppelinGuildPlugin()({ stars_required: 5 color: 0x87CEEB ~~~ - + ### Custom star emoji This is identical to the basic starboard above, but accepts two emoji: the regular star and a custom :mrvnSmile: emoji - + ~~~yml starboard: config: @@ -83,10 +83,10 @@ export const StarboardPlugin = zeppelinGuildPlugin()({ star_emoji: ["⭐", "<:mrvnSmile:543000534102310933>"] stars_required: 5 ~~~ - + ### Limit starboard to a specific channel This is identical to the basic starboard above, but only works from a specific channel (473087035574321152). - + ~~~yml starboard: config: @@ -105,7 +105,7 @@ export const StarboardPlugin = zeppelinGuildPlugin()({ ### Limit starboard to a specific level (and above) This is identical to the basic starboard above, but only works for a specific level (>=50). - + ~~~yml starboard: config: @@ -136,14 +136,14 @@ export const StarboardPlugin = zeppelinGuildPlugin()({ // prettier-ignore commands: [ - MigratePinsCmd, + MigratePinsCmd, ], // prettier-ignore events: [ - StarboardReactionAddEvt, - StarboardReactionRemoveEvt, - StarboardReactionRemoveAllEvt, + StarboardReactionAddEvt, + StarboardReactionRemoveEvt, + StarboardReactionRemoveAllEvt, ], beforeLoad(pluginData) { diff --git a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts index 6b0d768c..84e338f4 100644 --- a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts @@ -21,14 +21,14 @@ export function createStarboardEmbedFromMessage( name: msg.author.tag, }, fields: [], - timestamp: msg.createdTimestamp, + timestamp: msg.createdAt.toISOString(), }; if (color != null) { embed.color = color; } - embed.author.iconURL = msg.author.displayAvatarURL(); + embed.author.icon_url = msg.author.displayAvatarURL(); // The second condition here checks for messages with only an image link that is then embedded. // The message content in that case is hidden by the Discord client, so we hide it here too. diff --git a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts index 039ed2a0..af614705 100644 --- a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts +++ b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts @@ -1,4 +1,4 @@ -import { EmbedData, Message, Snowflake, TextChannel } from "discord.js"; +import { APIEmbed, Message, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { StarboardPluginType, TStarboardOpts } from "../types"; import { createStarboardEmbedFromMessage } from "./createStarboardEmbedFromMessage"; @@ -10,12 +10,12 @@ export async function saveMessageToStarboard( starboard: TStarboardOpts, ) { const channel = pluginData.guild.channels.cache.get(starboard.channel_id as Snowflake); - if (!channel) return; + if (!channel?.isTextBased()) return; const starCount = (await pluginData.state.starboardReactions.getAllReactionsForMessageId(msg.id)).length; const embed = createStarboardEmbedFromMessage(msg, Boolean(starboard.copy_full_embed), starboard.color); embed.fields!.push(createStarboardPseudoFooterForMessage(starboard, msg, starboard.star_emoji![0], starCount)); - const starboardMessage = await (channel as TextChannel).send({ embeds: [embed as EmbedData] }); + const starboardMessage = await channel.send({ embeds: [embed as APIEmbed] }); await pluginData.state.starboardMessages.createStarboardMessage(channel.id, msg.id, starboardMessage.id); } diff --git a/backend/src/plugins/Tags/commands/TagEvalCmd.ts b/backend/src/plugins/Tags/commands/TagEvalCmd.ts index bf9c3f1f..3c5e7f24 100644 --- a/backend/src/plugins/Tags/commands/TagEvalCmd.ts +++ b/backend/src/plugins/Tags/commands/TagEvalCmd.ts @@ -4,6 +4,7 @@ import { sendErrorMessage } from "../../../pluginUtils"; import { TemplateParseError } from "../../../templateFormatter"; import { tagsCmd } from "../types"; import { renderTagBody } from "../util/renderTagBody"; +import { MessageCreateOptions } from "discord.js"; export const TagEvalCmd = tagsCmd({ trigger: "tag eval", @@ -15,7 +16,7 @@ export const TagEvalCmd = tagsCmd({ async run({ message: msg, args, pluginData }) { try { - const rendered = await renderTagBody( + const rendered = (await renderTagBody( pluginData, args.body, [], @@ -24,7 +25,7 @@ export const TagEvalCmd = tagsCmd({ user: userToTemplateSafeUser(msg.member.user), }, { member: msg.member }, - ); + )) as MessageCreateOptions; if (!rendered.content && !rendered.embeds?.length) { sendErrorMessage(pluginData, msg.channel, "Evaluation resulted in an empty text"); diff --git a/backend/src/plugins/Tags/util/onMessageCreate.ts b/backend/src/plugins/Tags/util/onMessageCreate.ts index 052c6395..b0e7c419 100644 --- a/backend/src/plugins/Tags/util/onMessageCreate.ts +++ b/backend/src/plugins/Tags/util/onMessageCreate.ts @@ -2,7 +2,6 @@ import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { erisAllowedMentionsToDjsMentionOptions } from "src/utils/erisAllowedMentionsToDjsMentionOptions"; import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { LogType } from "../../../data/LogType"; import { convertDelayStringToMS, resolveMember, tStrictMessageContent } from "../../../utils"; import { messageIsEmpty } from "../../../utils/messageIsEmpty"; import { validate } from "../../../validatorUtils"; @@ -17,8 +16,8 @@ export async function onMessageCreate(pluginData: GuildPluginData delete the response as well const commandMsgResponse = await pluginData.state.tags.findResponseByCommandMessageId(msg.id); if (commandMsgResponse) { - const channel = pluginData.guild.channels.cache.get(msg.channelId) as TextChannel; - if (!channel) return; - await pluginData.state.tags.deleteResponseByCommandMessageId(msg.id); await channel.messages.delete(commandMsgResponse.response_message_id).catch(noop); return; @@ -21,9 +18,6 @@ export const onMessageDelete = guildPluginEventListener({ // Response was deleted -> delete the command message as well const responseMsgResponse = await pluginData.state.tags.findResponseByResponseMessageId(msg.id); if (responseMsgResponse) { - const channel = pluginData.guild.channels.cache.get(msg.channelId) as TextChannel; - if (!channel) return; - await pluginData.state.tags.deleteResponseByResponseMessageId(msg.id); await channel.messages.delete(responseMsgResponse.command_message_id).catch(noop); return; diff --git a/backend/src/plugins/Utility/UtilityPlugin.ts b/backend/src/plugins/Utility/UtilityPlugin.ts index 5a3e6636..26528c82 100644 --- a/backend/src/plugins/Utility/UtilityPlugin.ts +++ b/backend/src/plugins/Utility/UtilityPlugin.ts @@ -1,4 +1,4 @@ -import { GuildMember, MessageEmbedOptions, Snowflake } from "discord.js"; +import { GuildMember, Snowflake } from "discord.js"; import { PluginOptions } from "knub"; import { GuildArchives } from "../../data/GuildArchives"; import { GuildCases } from "../../data/GuildCases"; diff --git a/backend/src/plugins/Utility/commands/AboutCmd.ts b/backend/src/plugins/Utility/commands/AboutCmd.ts index 369c1201..41015e35 100644 --- a/backend/src/plugins/Utility/commands/AboutCmd.ts +++ b/backend/src/plugins/Utility/commands/AboutCmd.ts @@ -1,10 +1,10 @@ -import { GuildChannel, MessageOptions } from "discord.js"; +import { APIEmbed, GuildChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import LCL from "last-commit-log"; import moment from "moment-timezone"; import { rootDir } from "../../../paths"; import { getCurrentUptime } from "../../../uptime"; -import { multiSorter, resolveMember, sorter } from "../../../utils"; +import { resolveMember, sorter } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { utilityCmd } from "../types"; import { shuffle } from "lodash"; @@ -59,20 +59,16 @@ export const AboutCmd = utilityCmd({ ); loadedPlugins.sort(); - const aboutContent: MessageOptions = { - embeds: [ + const aboutEmbed: APIEmbed = { + title: `About ${pluginData.client.user!.username}`, + fields: [ { - title: `About ${pluginData.client.user!.username}`, - fields: [ - { - name: "Status", - value: basicInfoRows.map(([label, value]) => `${label}: **${value}**`).join("\n"), - }, - { - name: `Loaded plugins on this server (${loadedPlugins.length})`, - value: loadedPlugins.join(", "), - }, - ], + name: "Status", + value: basicInfoRows.map(([label, value]) => `${label}: **${value}**`).join("\n"), + }, + { + name: `Loaded plugins on this server (${loadedPlugins.length})`, + value: loadedPlugins.join(", "), }, ], }; @@ -86,7 +82,7 @@ export const AboutCmd = utilityCmd({ .map((s, i) => (i % 2 === 0 ? `**${s.name}**` : `__${s.name}__`)) .join(" "); - aboutContent.embeds![0].fields!.push({ + aboutEmbed.fields!.push({ name: "Zeppelin supporters 🎉", value: "These amazing people have supported Zeppelin development by pledging on [Patreon](https://www.patreon.com/zeppelinbot):\n\n" + @@ -102,14 +98,14 @@ export const AboutCmd = utilityCmd({ botRoles = botRoles.filter((r) => r.color); // Filter to those with a color botRoles.sort(sorter("position", "DESC")); // Sort by position (highest first) if (botRoles.length) { - aboutContent.embeds![0].color = botRoles[0].color; + aboutEmbed.color = botRoles[0].color; } // Use the bot avatar as the embed image if (pluginData.client.user!.avatarURL()) { - aboutContent.embeds![0].thumbnail = { url: pluginData.client.user!.avatarURL()! }; + aboutEmbed.thumbnail = { url: pluginData.client.user!.avatarURL()! }; } - msg.channel.send(aboutContent); + msg.channel.send({ embeds: [aboutEmbed] }); }, }); diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index d503bc97..e1518ca0 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -1,4 +1,4 @@ -import { MessageEmbedOptions } from "discord.js"; +import { ImageFormat, APIEmbed } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage } from "../../../pluginUtils"; import { UnknownUser } from "../../../utils"; @@ -16,9 +16,9 @@ export const AvatarCmd = utilityCmd({ async run({ message: msg, args, pluginData }) { const user = args.user || msg.author; if (!(user instanceof UnknownUser)) { - const embed: MessageEmbedOptions = { + const embed: APIEmbed = { image: { - url: user.displayAvatarURL({ dynamic: true, format: "png", size: 2048 }), + url: user.displayAvatarURL({ extension: ImageFormat.PNG, size: 2048 }), }, title: `Avatar of ${user.tag}:`, }; diff --git a/backend/src/plugins/Utility/commands/JumboCmd.ts b/backend/src/plugins/Utility/commands/JumboCmd.ts index 867ac321..e60acf5b 100644 --- a/backend/src/plugins/Utility/commands/JumboCmd.ts +++ b/backend/src/plugins/Utility/commands/JumboCmd.ts @@ -1,4 +1,4 @@ -import { Attachment, AttachmentBuilder } from "discord.js"; +import { AttachmentBuilder } from "discord.js"; import fs from "fs"; import photon from "@silvia-odwyer/photon-node"; import twemoji from "twemoji"; diff --git a/backend/src/plugins/Utility/commands/SourceCmd.ts b/backend/src/plugins/Utility/commands/SourceCmd.ts index b5e4e802..54c24647 100644 --- a/backend/src/plugins/Utility/commands/SourceCmd.ts +++ b/backend/src/plugins/Utility/commands/SourceCmd.ts @@ -1,4 +1,3 @@ -import { Snowflake } from "discord.js"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { getBaseUrl, sendErrorMessage } from "../../../pluginUtils"; diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index def3201c..cbe476aa 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -1,11 +1,5 @@ import { VoiceChannel } from "discord.js"; -import { - channelToTemplateSafeChannel, - memberToTemplateSafeMember, - userToTemplateSafeUser, -} from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { utilityCmd } from "../types"; import { LogsPlugin } from "../../Logs/LogsPlugin"; diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index e74afe71..798a5120 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -1,11 +1,5 @@ import { ChannelType, Snowflake, VoiceChannel } from "discord.js"; -import { - channelToTemplateSafeChannel, - memberToTemplateSafeMember, - userToTemplateSafeUser, -} from "../../../utils/templateSafeObjects"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { LogType } from "../../../data/LogType"; import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { channelMentionRegex, isSnowflake, simpleClosestStringMatch } from "../../../utils"; import { utilityCmd } from "../types"; diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index bc17c51f..a7397dfd 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -1,4 +1,4 @@ -import { ChannelType, MessageEmbedOptions, Snowflake, StageChannel, ThreadChannel, VoiceChannel } from "discord.js"; +import { APIEmbed, ChannelType, Snowflake, StageChannel, VoiceChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; @@ -16,14 +16,14 @@ const STAGE_CHANNEL_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/839930647711186995/stage-channel.png"; const PUBLIC_THREAD_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/870343055855738921/public-thread.png"; -const PRIVATE_THREAD_UCON = +const PRIVATE_THREAD_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/870343402447839242/private-thread.png"; export async function getChannelInfoEmbed( pluginData: GuildPluginData, channelId: string, requestMemberId?: string, -): Promise { +): Promise { const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!channel) { return null; @@ -39,8 +39,8 @@ export async function getChannelInfoEmbed( [ChannelType.GuildAnnouncement]: ANNOUNCEMENT_CHANNEL_ICON, [ChannelType.GuildStageVoice]: STAGE_CHANNEL_ICON, [ChannelType.PublicThread]: PUBLIC_THREAD_ICON, - [ChannelType.PrivateThread]: PRIVATE_THREAD_UCON, - }[channel.type] || TEXT_CHANNEL_ICON; + [ChannelType.PrivateThread]: PRIVATE_THREAD_ICON, + }[channel.type] ?? TEXT_CHANNEL_ICON; const channelType = { @@ -54,19 +54,18 @@ export async function getChannelInfoEmbed( [ChannelType.AnnouncementThread]: "News Thread channel", [ChannelType.GuildDirectory]: "Hub channel", [ChannelType.GuildForum]: "Forum channel", - }[channel.type] || "Channel"; + }[channel.type] ?? "Channel"; embed.author = { name: `${channelType}: ${channel.name}`, - iconURL: icon, + icon_url: icon, }; let channelName = `#${channel.name}`; if ( channel.type === ChannelType.GuildVoice || channel.type === ChannelType.GuildCategory || - channel.type === ChannelType.GuildStageVoice || - channel.type === ChannelType.GuildDirectory + channel.type === ChannelType.GuildStageVoice ) { channelName = channel.name; } @@ -129,14 +128,13 @@ export async function getChannelInfoEmbed( }); } - if (channel.type === ChannelType.PrivateThread || channel.type === ChannelType.PublicThread) { - const thread = channel as ThreadChannel; - const parentChannelName = thread.parent?.name ?? `<#${thread.parentId}>`; - const memberCount = thread.memberCount ?? thread.members.cache.size; - const owner = await thread.fetchOwner().catch(() => null); + if (channel.isThread()) { + const parentChannelName = channel.parent?.name ?? `<#${channel.parentId}>`; + const memberCount = channel.memberCount ?? channel.members.cache.size; + const owner = await channel.fetchOwner().catch(() => null); const ownerMention = owner?.user ? verboseUserMention(owner.user) : "Unknown#0000"; const humanizedArchiveTime = `Archive duration: **${humanizeDuration( - (thread.autoArchiveDuration ?? 0) * MINUTES, + (channel.autoArchiveDuration ?? 0) * MINUTES, )}**`; embed.fields.push({ @@ -145,7 +143,7 @@ export async function getChannelInfoEmbed( Parent channel: **#${parentChannelName}** Member count: **${memberCount}** Thread creator: ${ownerMention} - ${thread.archived ? "Archived: **True**" : humanizedArchiveTime}`), + ${channel.archived ? "Archived: **True**" : humanizedArchiveTime}`), }); } diff --git a/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts b/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts index a97d5310..01001e2d 100644 --- a/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts @@ -1,4 +1,4 @@ -import { MessageEmbedOptions } from "discord.js"; +import { APIEmbed } from "discord.js"; import { GuildPluginData } from "knub"; import { EmbedWith, preEmbedPadding, trimLines } from "../../../utils"; import { UtilityPluginType } from "../types"; @@ -6,22 +6,21 @@ import { UtilityPluginType } from "../types"; export async function getEmojiInfoEmbed( pluginData: GuildPluginData, emojiId: string, -): Promise { +): Promise { const emoji = pluginData.guild.emojis.cache.find((e) => e.id === emojiId); if (!emoji) { return null; } - const embed: EmbedWith<"fields"> = { + const embed: EmbedWith<"fields" | "author"> = { fields: [], + author: { + name: `Emoji: ${emoji.name}`, + icon_url: emoji.url, + }, }; - embed.author = { - name: `Emoji: ${emoji.name}`, - icon_url: `https://cdn.discordapp.com/emojis/${emoji.id}.${emoji.animated ? "gif" : "png"}?v=1`, - }; - - embed.fields.push({ + embed.fields!.push({ name: preEmbedPadding + "Emoji information", value: trimLines(` Name: **${emoji.name}** diff --git a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts index c0241b0b..1c8fb80c 100644 --- a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts @@ -1,7 +1,6 @@ -import { ChannelType, EmbedData } from "discord.js"; +import { APIEmbed, ChannelType } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import moment from "moment-timezone"; import { EmbedWith, formatNumber, @@ -19,7 +18,7 @@ import { UtilityPluginType } from "../types"; export async function getInviteInfoEmbed( pluginData: GuildPluginData, inviteCode: string, -): Promise { +): Promise { let invite = await resolveInvite(pluginData.client, inviteCode, true); if (!invite) { return null; @@ -36,7 +35,7 @@ export async function getInviteInfoEmbed( }; if (invite.guild.icon) { - embed.author.iconURL = `https://cdn.discordapp.com/icons/${invite.guild.id}/${invite.guild.icon}.png?size=256`; + embed.author.icon_url = `https://cdn.discordapp.com/icons/${invite.guild.id}/${invite.guild.icon}.png?size=256`; } if (invite.guild.description) { @@ -44,7 +43,6 @@ export async function getInviteInfoEmbed( } const serverCreatedAtTimestamp = snowflakeToTimestamp(invite.guild.id); - const serverCreatedAt = moment.utc(serverCreatedAtTimestamp, "x"); const serverAge = humanizeDuration(Date.now() - serverCreatedAtTimestamp, { largest: 2, round: true, @@ -69,7 +67,6 @@ export async function getInviteInfoEmbed( invite.channel.type === ChannelType.GuildVoice ? `🔉 ${invite.channel.name}` : `#${invite.channel.name}`; const channelCreatedAtTimestamp = snowflakeToTimestamp(invite.channel.id); - const channelCreatedAt = moment.utc(channelCreatedAtTimestamp, "x"); const channelAge = humanizeDuration(Date.now() - channelCreatedAtTimestamp, { largest: 2, round: true, @@ -119,8 +116,9 @@ export async function getInviteInfoEmbed( /*if (invite.channel.icon) { embed.author.icon_url = `https://cdn.discordapp.com/channel-icons/${invite.channel.id}/${invite.channel.icon}.png?size=256`; - }*/ const channelCreatedAtTimestamp = snowflakeToTimestamp(invite.channel!.id); - const channelCreatedAt = moment.utc(channelCreatedAtTimestamp, "x"); + }*/ + + const channelCreatedAtTimestamp = snowflakeToTimestamp(invite.channel!.id); const channelAge = humanizeDuration(Date.now() - channelCreatedAtTimestamp, { largest: 2, round: true, diff --git a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts index 35140759..056aae2c 100644 --- a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts @@ -1,9 +1,8 @@ -import { MessageEmbedOptions, Snowflake, TextChannel } from "discord.js"; +import { APIEmbed, MessageType, Snowflake, TextChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { getDefaultPrefix } from "knub/dist/commands/commandUtils"; import moment from "moment-timezone"; -import { MessageTypeStrings } from "src/types"; import { chunkMessageLines, EmbedWith, messageLink, preEmbedPadding, trimEmptyLines, trimLines } from "../../../utils"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; @@ -15,7 +14,7 @@ export async function getMessageInfoEmbed( channelId: string, messageId: string, requestMemberId?: string, -): Promise { +): Promise { const message = await (pluginData.guild.channels.resolve(channelId as Snowflake) as TextChannel).messages .fetch(messageId as Snowflake) .catch(() => null); @@ -25,13 +24,12 @@ export async function getMessageInfoEmbed( const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); - const embed: EmbedWith<"fields"> = { + const embed: EmbedWith<"fields" | "author"> = { fields: [], - }; - - embed.author = { - name: `Message: ${message.id}`, - iconURL: MESSAGE_ICON, + author: { + name: `Message: ${message.id}`, + icon_url: MESSAGE_ICON, + }, }; const createdAt = moment.utc(message.createdAt, "x"); @@ -58,17 +56,17 @@ export async function getMessageInfoEmbed( const type = { - [MessageTypeStrings.DEFAULT]: "Regular message", - [MessageTypeStrings.PINS_ADD]: "System message", - [MessageTypeStrings.GUILD_MEMBER_JOIN]: "System message", - [MessageTypeStrings.USER_PREMIUM_GUILD_SUBSCRIPTION]: "System message", - [MessageTypeStrings.USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1]: "System message", - [MessageTypeStrings.USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2]: "System message", - [MessageTypeStrings.USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3]: "System message", - [MessageTypeStrings.CHANNEL_FOLLOW_ADD]: "System message", - [MessageTypeStrings.GUILD_DISCOVERY_DISQUALIFIED]: "System message", - [MessageTypeStrings.GUILD_DISCOVERY_REQUALIFIED]: "System message", - }[message.type] || "Unknown"; + [MessageType.Default]: "Regular message", + [MessageType.ChannelPinnedMessage]: "System message", + [MessageType.UserJoin]: "System message", + [MessageType.GuildBoost]: "System message", + [MessageType.GuildBoostTier1]: "System message", + [MessageType.GuildBoostTier2]: "System message", + [MessageType.GuildBoostTier3]: "System message", + [MessageType.ChannelFollowAdd]: "System message", + [MessageType.GuildDiscoveryDisqualified]: "System message", + [MessageType.GuildDiscoveryRequalified]: "System message", + }[message.type] ?? "Unknown"; embed.fields.push({ name: preEmbedPadding + "Message information", diff --git a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts index 2a12d1f3..5acd8c72 100644 --- a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts @@ -1,4 +1,4 @@ -import { MessageEmbedOptions, PermissionsBitField, Role } from "discord.js"; +import { APIEmbed, PermissionFlagsBits, Role } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; @@ -13,18 +13,16 @@ export async function getRoleInfoEmbed( pluginData: GuildPluginData, role: Role, requestMemberId?: string, -): Promise { - const embed: EmbedWith<"fields"> = { +): Promise { + const embed: EmbedWith<"fields" | "author" | "color"> = { fields: [], + author: { + name: `Role: ${role.name}`, + icon_url: MENTION_ICON, + }, + color: role.color, }; - embed.author = { - name: `Role: ${role.name}`, - iconURL: MENTION_ICON, - }; - - embed.color = role.color; - const createdAt = moment.utc(role.createdAt, "x"); const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); const tzCreatedAt = requestMemberId @@ -36,7 +34,7 @@ export async function getRoleInfoEmbed( round: true, }); - const rolePerms = role.permissions.has(PermissionsBitField.Flags.Administrator) + const rolePerms = role.permissions.has(PermissionFlagsBits.Administrator) ? [PERMISSION_NAMES.Administrator] : role.permissions.toArray().map((p) => PERMISSION_NAMES[p]); diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index 2cb62e2e..c6b7bbd3 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -1,8 +1,7 @@ -import { ChannelType, MessageEmbedOptions, PremiumTier, Snowflake } from "discord.js"; +import { APIEmbed, ChannelType, GuildPremiumTier, Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; - import { EmbedWith, formatNumber, @@ -19,18 +18,11 @@ import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; import { getGuildPreview } from "./getGuildPreview"; -const PremiumTiers: Record = { - NONE: 0, - TIER_1: 1, - TIER_2: 2, - TIER_3: 3, -}; - export async function getServerInfoEmbed( pluginData: GuildPluginData, serverId: string, requestMemberId?: string, -): Promise { +): Promise { const thisServer = serverId === pluginData.guild.id ? pluginData.guild : null; const [restGuild, guildPreview] = await Promise.all([ thisServer @@ -54,7 +46,7 @@ export async function getServerInfoEmbed( embed.author = { name: `Server: ${(guildPreview || restGuild)!.name}`, - iconURL: (guildPreview || restGuild)!.iconURL() ?? undefined, + icon_url: (guildPreview || restGuild)!.iconURL() ?? undefined, }; // BASIC INFORMATION @@ -165,12 +157,7 @@ export async function getServerInfoEmbed( const categories = thisServer.channels.cache.filter((channel) => channel.type === ChannelType.GuildCategory); const textChannels = thisServer.channels.cache.filter((channel) => channel.type === ChannelType.GuildText); const voiceChannels = thisServer.channels.cache.filter((channel) => channel.type === ChannelType.GuildVoice); - const threadChannels = thisServer.channels.cache.filter( - (channel) => - channel.type === ChannelType.PublicThread || - channel.type === ChannelType.PrivateThread || - channel.type === ChannelType.AnnouncementThread, - ); + const threadChannels = thisServer.channels.cache.filter((channel) => channel.isThread()); const announcementChannels = thisServer.channels.cache.filter( (channel) => channel.type === ChannelType.GuildAnnouncement, ); @@ -198,22 +185,20 @@ export async function getServerInfoEmbed( } if (restGuild) { - const premiumTierValue = PremiumTiers[restGuild.premiumTier]; - const maxEmojis = { - 0: 50, - 1: 100, - 2: 150, - 3: 250, - }[premiumTierValue] ?? 50; + [GuildPremiumTier.None]: 50, + [GuildPremiumTier.Tier1]: 100, + [GuildPremiumTier.Tier2]: 150, + [GuildPremiumTier.Tier3]: 250, + }[restGuild.premiumTier] ?? 50; const maxStickers = { - 0: 0, - 1: 15, - 2: 30, - 3: 60, - }[premiumTierValue] ?? 0; + [GuildPremiumTier.None]: 0, + [GuildPremiumTier.Tier1]: 15, + [GuildPremiumTier.Tier2]: 30, + [GuildPremiumTier.Tier3]: 60, + }[restGuild.premiumTier] ?? 0; otherStats.push(`Emojis: **${restGuild.emojis.cache.size}** / ${maxEmojis * 2}`); otherStats.push(`Stickers: **${restGuild.stickers.cache.size}** / ${maxStickers}`); @@ -223,9 +208,7 @@ export async function getServerInfoEmbed( } if (thisServer) { - otherStats.push( - `Boosts: **${thisServer.premiumSubscriptionCount ?? 0}** (level ${PremiumTiers[thisServer.premiumTier]})`, - ); + otherStats.push(`Boosts: **${thisServer.premiumSubscriptionCount ?? 0}** (level ${thisServer.premiumTier})`); } embed.fields.push({ diff --git a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts index 6ffb454f..901df722 100644 --- a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts @@ -1,4 +1,4 @@ -import { MessageEmbedOptions } from "discord.js"; +import { APIEmbed } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; @@ -14,14 +14,13 @@ export async function getSnowflakeInfoEmbed( snowflake: string, showUnknownWarning = false, requestMemberId?: string, -): Promise { - const embed: EmbedWith<"fields"> = { +): Promise { + const embed: EmbedWith<"fields" | "author"> = { fields: [], - }; - - embed.author = { - name: `Snowflake: ${snowflake}`, - iconURL: SNOWFLAKE_ICON, + author: { + name: `Snowflake: ${snowflake}`, + icon_url: SNOWFLAKE_ICON, + }, }; if (showUnknownWarning) { diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts index 27fb274e..4b9e2724 100644 --- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts @@ -1,4 +1,4 @@ -import { MessageEmbedOptions } from "discord.js"; +import { APIEmbed } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; @@ -28,7 +28,7 @@ export async function getUserInfoEmbed( userId: string, compact = false, requestMemberId?: string, -): Promise { +): Promise { const user = await resolveUser(pluginData.client, userId); if (!user || user instanceof UnknownUser) { return null; @@ -47,7 +47,7 @@ export async function getUserInfoEmbed( }; const avatarURL = user.displayAvatarURL(); - embed.author.iconURL = avatarURL; + embed.author.icon_url = avatarURL; const createdAt = moment.utc(user.createdAt, "x"); const tzCreatedAt = requestMemberId diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index ac98f3f3..cf709706 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -4,12 +4,9 @@ import { ButtonStyle, GuildMember, Message, - MessageActionRowComponent, - MessageActionRowComponentBuilder, MessageComponentInteraction, PermissionsBitField, Snowflake, - TextChannel, User, } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; @@ -119,12 +116,12 @@ export async function displaySearch( } } catch (e) { if (e instanceof SearchError) { - sendErrorMessage(pluginData, msg.channel as TextChannel, e.message); + sendErrorMessage(pluginData, msg.channel, e.message); return; } if (e instanceof InvalidRegexError) { - sendErrorMessage(pluginData, msg.channel as TextChannel, e.message); + sendErrorMessage(pluginData, msg.channel, e.message); return; } @@ -132,7 +129,7 @@ export async function displaySearch( } if (searchResult.totalResults === 0) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "No results found"); + sendErrorMessage(pluginData, msg.channel, "No results found"); return; } @@ -172,9 +169,7 @@ export async function displaySearch( // Set up pagination reactions if needed. The reactions are cleared after a timeout. if (searchResult.totalResults > perPage) { const idMod = `${searchMsg.id}:${moment.utc().valueOf()}`; - const buttons: ButtonBuilder[] = []; - - buttons.push( + const buttons: ButtonBuilder[] = [ new ButtonBuilder() .setStyle(ButtonStyle.Secondary) .setEmoji("⬅") @@ -186,9 +181,9 @@ export async function displaySearch( .setCustomId(`nextButton:${idMod}`) .setDisabled(currentPage === searchResult.lastPage), new ButtonBuilder().setStyle(ButtonStyle.Secondary).setEmoji("🔄").setCustomId(`reloadButton:${idMod}`), - ); + ]; - const row = new ActionRowBuilder().addComponents(buttons); + const row = new ActionRowBuilder().addComponents(buttons); await searchMsg.edit({ content: result, components: [row] }); const collector = searchMsg.createMessageComponentCollector({ time: 2 * MINUTES }); @@ -264,12 +259,12 @@ export async function archiveSearch( } } catch (e) { if (e instanceof SearchError) { - sendErrorMessage(pluginData, msg.channel as TextChannel, e.message); + sendErrorMessage(pluginData, msg.channel, e.message); return; } if (e instanceof InvalidRegexError) { - sendErrorMessage(pluginData, msg.channel as TextChannel, e.message); + sendErrorMessage(pluginData, msg.channel, e.message); return; } @@ -277,7 +272,7 @@ export async function archiveSearch( } if (results.totalResults === 0) { - sendErrorMessage(pluginData, msg.channel as TextChannel, "No results found"); + sendErrorMessage(pluginData, msg.channel, "No results found"); return; } diff --git a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts index 772f27a9..c74fd04f 100644 --- a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts +++ b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts @@ -1,13 +1,11 @@ import { Snowflake, TextChannel } from "discord.js"; import { - channelToTemplateSafeChannel, guildToTemplateSafeGuild, memberToTemplateSafeMember, userToTemplateSafeUser, } from "../../../utils/templateSafeObjects"; -import { LogType } from "../../../data/LogType"; import { renderTemplate, TemplateParseError, TemplateSafeValueContainer } from "../../../templateFormatter"; -import { createChunkedMessage, stripObjectToScalars, verboseChannelMention, verboseUserMention } from "../../../utils"; +import { createChunkedMessage, verboseChannelMention, verboseUserMention } from "../../../utils"; import { sendDM } from "../../../utils/sendDM"; import { welcomeMessageEvt } from "../types"; import { LogsPlugin } from "../../Logs/LogsPlugin"; diff --git a/backend/src/types.ts b/backend/src/types.ts index 4c5d141e..45974aee 100644 --- a/backend/src/types.ts +++ b/backend/src/types.ts @@ -64,25 +64,3 @@ export interface CommandInfo { [key: string]: TMarkdown; }; } - -export enum MessageTypeStrings { - "DEFAULT", - "RECIPIENT_ADD", - "RECIPIENT_REMOVE", - "CALL", - "CHANNEL_NAME_CHANGE", - "CHANNEL_ICON_CHANGE", - "PINS_ADD", - "GUILD_MEMBER_JOIN", - "USER_PREMIUM_GUILD_SUBSCRIPTION", - "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1", - "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2", - "USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3", - "CHANNEL_FOLLOW_ADD", - "GUILD_DISCOVERY_DISQUALIFIED", - "GUILD_DISCOVERY_REQUALIFIED", - "GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING", - "GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING", - "REPLY", - "APPLICATION_COMMAND", -} diff --git a/backend/src/utils.ts b/backend/src/utils.ts index ac44706b..c621511f 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -1,16 +1,13 @@ import { + APIEmbed, ChannelType, Client, - Constants, DiscordAPIError, - Embed, EmbedData, EmbedType, Emoji, escapeCodeBlock, Guild, - GuildAuditLogs, - GuildAuditLogsEntry, GuildBasedChannel, GuildChannel, GuildMember, @@ -25,8 +22,7 @@ import { PartialMessage, Snowflake, Sticker, - TextChannel, - ThreadChannel, + TextBasedChannel, User, } from "discord.js"; import emojiRegex from "emoji-regex"; @@ -179,7 +175,7 @@ function tDeepPartialProp(prop: any) { } } -export function getScalarDifference( +export function getScalarDifference( base: T, object: T, ignoreKeys: string[] = [], @@ -392,7 +388,7 @@ export const zEmbedInput = z.object({ .nullable(), }); -export type EmbedWith = EmbedData & Pick, T>; +export type EmbedWith = APIEmbed & Pick, T>; export const zStrictMessageContent = z.object({ content: z.string().optional(), @@ -952,7 +948,7 @@ export function chunkMessageLines(str: string, maxChunkLength = 1990): string[] } export async function createChunkedMessage( - channel: GuildTextBasedChannel | User, + channel: TextBasedChannel | User, messageText: string, allowedMentions?: MessageMentionOptions, ) { @@ -1445,7 +1441,7 @@ export function verboseUserName(user: User | UnknownUser): string { return `**${user.tag}** (\`${user.id}\`)`; } -export function verboseChannelMention(channel: GuildTextBasedChannel): string { +export function verboseChannelMention(channel: GuildBasedChannel): string { const plainTextName = channel.type === ChannelType.GuildVoice || channel.type === ChannelType.GuildStageVoice ? channel.name diff --git a/backend/src/utils/calculateEmbedSize.ts b/backend/src/utils/calculateEmbedSize.ts index fd40c2d4..4a9cd1a0 100644 --- a/backend/src/utils/calculateEmbedSize.ts +++ b/backend/src/utils/calculateEmbedSize.ts @@ -1,4 +1,4 @@ -import { EmbedData } from "discord.js"; +import { APIEmbed, EmbedData } from "discord.js"; function sumStringLengthsRecursively(obj: any): number { if (obj == null) return 0; @@ -12,6 +12,6 @@ function sumStringLengthsRecursively(obj: any): number { return 0; } -export function calculateEmbedSize(embed: EmbedData): number { +export function calculateEmbedSize(embed: APIEmbed | EmbedData): number { return sumStringLengthsRecursively(embed); } diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index 74a77c19..b3c7d7ec 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -1,6 +1,5 @@ import { Client, - GuildTextBasedChannel, Message, MessageCreateOptions, MessageEditOptions, @@ -8,7 +7,6 @@ import { PartialMessageReaction, PartialUser, TextBasedChannel, - TextChannel, User, } from "discord.js"; import { Awaitable } from "knub/dist/utils"; diff --git a/backend/src/utils/crypt.ts b/backend/src/utils/crypt.ts index d6208f1c..2b602bc7 100644 --- a/backend/src/utils/crypt.ts +++ b/backend/src/utils/crypt.ts @@ -1,5 +1,4 @@ import { spawn, Worker, Pool } from "threads"; -import type { CryptFns } from "./cryptWorker"; import { MINUTES } from "../utils"; import { env } from "../env"; diff --git a/backend/src/utils/filterObject.ts b/backend/src/utils/filterObject.ts index 0456ebcb..6cea499c 100644 --- a/backend/src/utils/filterObject.ts +++ b/backend/src/utils/filterObject.ts @@ -6,7 +6,7 @@ type FilterResult = { * Filter an object's properties based on its values and keys * @return New object with filtered properties */ -export function filterObject( +export function filterObject( object: T, filterFn: (value: T[K], key: K) => boolean, ): FilterResult { diff --git a/backend/src/utils/findMatchingAuditLogEntry.ts b/backend/src/utils/findMatchingAuditLogEntry.ts index fcce7a76..70e8e426 100644 --- a/backend/src/utils/findMatchingAuditLogEntry.ts +++ b/backend/src/utils/findMatchingAuditLogEntry.ts @@ -1,4 +1,4 @@ -import { Guild, GuildAuditLogsAction, GuildAuditLogsEntry } from "discord.js"; +import { AuditLogEvent, Guild, GuildAuditLogsEntry } from "discord.js"; import { SECONDS, sleep } from "../utils"; const BATCH_DEBOUNCE_TIME = 2 * SECONDS; @@ -19,7 +19,7 @@ const batches = new Map(); */ export async function findMatchingAuditLogEntry( guild: Guild, - action?: GuildAuditLogsAction, + action?: AuditLogEvent, targetId?: string, ): Promise { let candidates: GuildAuditLogsEntry[]; @@ -49,7 +49,8 @@ export async function findMatchingAuditLogEntry( const _candidates = Array.from(result?.entries.values() ?? []); batches.delete(guild.id); - resolve(_candidates); + // TODO: Figure out the type + resolve(_candidates as any); }), join() { batch._waitUntil = Date.now() + BATCH_DEBOUNCE_TIME; diff --git a/backend/src/utils/getGuildPrefix.ts b/backend/src/utils/getGuildPrefix.ts index 763a5032..6eb51494 100644 --- a/backend/src/utils/getGuildPrefix.ts +++ b/backend/src/utils/getGuildPrefix.ts @@ -2,5 +2,6 @@ import { GuildPluginData } from "knub"; import { getDefaultPrefix } from "knub/dist/commands/commandUtils"; export function getGuildPrefix(pluginData: GuildPluginData) { + // @ts-expect-error: discord.js version mismatch return pluginData.fullConfig.prefix || getDefaultPrefix(pluginData.client); } diff --git a/backend/src/utils/isDmChannel.ts b/backend/src/utils/isDmChannel.ts index 8c263761..089c5058 100644 --- a/backend/src/utils/isDmChannel.ts +++ b/backend/src/utils/isDmChannel.ts @@ -1,4 +1,4 @@ -import { Channel, ChannelType, DMChannel } from "discord.js"; +import type { Channel, DMChannel } from "discord.js"; export function isDmChannel(channel: Channel): channel is DMChannel { return channel.isDMBased(); diff --git a/backend/src/utils/isGuildChannel.ts b/backend/src/utils/isGuildChannel.ts index 8761944d..b2b224bc 100644 --- a/backend/src/utils/isGuildChannel.ts +++ b/backend/src/utils/isGuildChannel.ts @@ -1,5 +1,5 @@ -import { Channel, GuildBasedChannel, GuildChannel } from "discord.js"; +import type { Channel, GuildBasedChannel } from "discord.js"; export function isGuildChannel(channel: Channel): channel is GuildBasedChannel { - return channel.type.toString().startsWith("GUILD_"); + return "guild" in channel && channel.guild !== null; } diff --git a/backend/src/utils/isThreadChannel.ts b/backend/src/utils/isThreadChannel.ts index f1a9cc04..b0829d77 100644 --- a/backend/src/utils/isThreadChannel.ts +++ b/backend/src/utils/isThreadChannel.ts @@ -1,4 +1,4 @@ -import { AnyThreadChannel, Channel, ChannelType } from "discord.js"; +import type { AnyThreadChannel, Channel } from "discord.js"; export function isThreadChannel(channel: Channel): channel is AnyThreadChannel { return channel.isThread(); diff --git a/backend/src/utils/messageHasContent.ts b/backend/src/utils/messageHasContent.ts index f5eeb72e..0db5931e 100644 --- a/backend/src/utils/messageHasContent.ts +++ b/backend/src/utils/messageHasContent.ts @@ -1,5 +1,5 @@ -import { MessageOptions } from "child_process"; -import { MessageCreateOptions, MessagePayload } from "discord.js"; +import { MessageCreateOptions } from "discord.js"; +import { StrictMessageContent } from "../utils.js"; function embedHasContent(embed: any) { for (const [key, value] of Object.entries(embed)) { @@ -19,7 +19,7 @@ function embedHasContent(embed: any) { return false; } -export function messageHasContent(content: string | MessageCreateOptions): boolean { +export function messageHasContent(content: string | MessageCreateOptions | StrictMessageContent): boolean { if (typeof content === "string") { return content.trim() !== ""; } diff --git a/backend/src/utils/messageIsEmpty.ts b/backend/src/utils/messageIsEmpty.ts index e2c0ef3a..8b4a80b9 100644 --- a/backend/src/utils/messageIsEmpty.ts +++ b/backend/src/utils/messageIsEmpty.ts @@ -1,6 +1,7 @@ import { MessageCreateOptions } from "discord.js"; import { messageHasContent } from "./messageHasContent"; +import { StrictMessageContent } from "../utils.js"; -export function messageIsEmpty(content: string | MessageCreateOptions): boolean { +export function messageIsEmpty(content: string | MessageCreateOptions | StrictMessageContent): boolean { return !messageHasContent(content); } diff --git a/backend/src/utils/permissionNames.ts b/backend/src/utils/permissionNames.ts index 09a494b9..43e39291 100644 --- a/backend/src/utils/permissionNames.ts +++ b/backend/src/utils/permissionNames.ts @@ -1,7 +1,7 @@ -import { PermissionFlags } from "discord.js"; +import type { PermissionFlagsBits } from "discord.js"; import { EMPTY_CHAR } from "../utils"; -export const PERMISSION_NAMES: Record = { +export const PERMISSION_NAMES = { AddReactions: "Add Reactions", Administrator: "Administrator", AttachFiles: "Attach Files", @@ -43,4 +43,4 @@ export const PERMISSION_NAMES: Record = { ViewGuildInsights: "View Guild Insights", ModerateMembers: "Moderate Members", ManageEvents: "Manage Events", -}; +} as const satisfies Record; diff --git a/backend/src/utils/resolveMessageTarget.ts b/backend/src/utils/resolveMessageTarget.ts index 2d39873a..1c7e7c3c 100644 --- a/backend/src/utils/resolveMessageTarget.ts +++ b/backend/src/utils/resolveMessageTarget.ts @@ -1,4 +1,4 @@ -import { GuildTextBasedChannel, Snowflake, TextChannel } from "discord.js"; +import { GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { getChannelIdFromMessageId } from "../data/getChannelIdFromMessageId"; import { isSnowflake } from "../utils"; diff --git a/backend/src/utils/typeUtils.ts b/backend/src/utils/typeUtils.ts index 26bc121e..40c69b1a 100644 --- a/backend/src/utils/typeUtils.ts +++ b/backend/src/utils/typeUtils.ts @@ -8,3 +8,7 @@ export declare type WithRequiredProps = T & { // https://devblogs.microsoft.com/typescript/announcing-typescript-4-1/ export type Awaited = T extends PromiseLike ? Awaited : T; + +export type DeepMutable = { + -readonly [P in keyof T]: DeepMutable; +}; diff --git a/backend/src/utils/validateNoObjectAliases.ts b/backend/src/utils/validateNoObjectAliases.ts index 3666274d..76039d6e 100644 --- a/backend/src/utils/validateNoObjectAliases.ts +++ b/backend/src/utils/validateNoObjectAliases.ts @@ -1,5 +1,3 @@ -import { Not } from "../utils"; - const scalarTypes = ["string", "number", "boolean", "bigint"]; export class ObjectAliasError extends Error {} diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index ff0c90c6..f7917819 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -1,16 +1,11 @@ import { - ActionRow, ActionRowBuilder, ButtonBuilder, - ButtonComponent, ButtonStyle, GuildTextBasedChannel, - Message, MessageActionRowComponentBuilder, MessageComponentInteraction, MessageCreateOptions, - MessagePayloadOption, - TextChannel, } from "discord.js"; import { noop } from "knub/dist/utils"; import moment from "moment"; diff --git a/package-lock.json b/package-lock.json index ee34321e..734f757c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,10 +13,10 @@ "devDependencies": { "husky": "^3.0.9", "lint-staged": "^9.4.2", - "prettier": "^2.4.0", + "prettier": "^2.8.4", "tslint": "^5.13.1", "tslint-config-prettier": "^1.18.0", - "typescript": "4.9" + "typescript": "~4.9.5" } }, "node_modules/@babel/code-frame": { @@ -1794,15 +1794,18 @@ } }, "node_modules/prettier": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.0.tgz", - "integrity": "sha512-DsEPLY1dE5HF3BxCRBmD4uYZ+5DCbvatnolqTqcxEgKVZnL2kUfyu7b8pPQ5+hTBkdhU9SLUmK0/pHb07RE4WQ==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", "dev": true, "bin": { "prettier": "bin-prettier.js" }, "engines": { "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/pump": { @@ -3747,9 +3750,9 @@ } }, "prettier": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.0.tgz", - "integrity": "sha512-DsEPLY1dE5HF3BxCRBmD4uYZ+5DCbvatnolqTqcxEgKVZnL2kUfyu7b8pPQ5+hTBkdhU9SLUmK0/pHb07RE4WQ==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", "dev": true }, "pump": { diff --git a/package.json b/package.json index 6040663f..165561ec 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,10 @@ "devDependencies": { "husky": "^3.0.9", "lint-staged": "^9.4.2", - "prettier": "^2.4.0", + "prettier": "^2.8.4", "tslint": "^5.13.1", "tslint-config-prettier": "^1.18.0", - "typescript": "4.9" + "typescript": "~4.9.5" }, "husky": { "hooks": {