From 771ed76f64e0c330259dbce3a8c6d4c3a7fc14db Mon Sep 17 00:00:00 2001 From: Obliie Date: Sat, 15 Jul 2023 21:34:26 +0100 Subject: [PATCH 01/30] feat: Context menu mod menu command --- backend/src/data/GuildCases.ts | 15 + .../plugins/ContextMenus/ContextMenuPlugin.ts | 40 ++- .../src/plugins/ContextMenus/actions/ban.ts | 97 ++++++ .../src/plugins/ContextMenus/actions/clean.ts | 66 ++-- .../src/plugins/ContextMenus/actions/mute.ts | 78 ++++- .../src/plugins/ContextMenus/actions/note.ts | 88 +++++ .../plugins/ContextMenus/actions/userInfo.ts | 28 -- .../src/plugins/ContextMenus/actions/warn.ts | 80 +++++ .../ContextMenus/commands/ModMenuCmd.ts | 319 ++++++++++++++++++ .../ContextMenus/events/ContextClickedEvt.ts | 12 - backend/src/plugins/ContextMenus/types.ts | 49 ++- .../ContextMenus/utils/contextRouter.ts | 13 - .../utils/hardcodedContextOptions.ts | 23 -- .../ContextMenus/utils/loadAllCommands.ts | 39 --- .../plugins/ModActions/ModActionsPlugin.ts | 29 +- .../ModActions/functions/hasModActionPerm.ts | 35 ++ .../ModActions/functions/hasMutePerm.ts | 11 - 17 files changed, 818 insertions(+), 204 deletions(-) create mode 100644 backend/src/plugins/ContextMenus/actions/ban.ts create mode 100644 backend/src/plugins/ContextMenus/actions/note.ts delete mode 100644 backend/src/plugins/ContextMenus/actions/userInfo.ts create mode 100644 backend/src/plugins/ContextMenus/actions/warn.ts create mode 100644 backend/src/plugins/ContextMenus/commands/ModMenuCmd.ts delete mode 100644 backend/src/plugins/ContextMenus/events/ContextClickedEvt.ts delete mode 100644 backend/src/plugins/ContextMenus/utils/contextRouter.ts delete mode 100644 backend/src/plugins/ContextMenus/utils/hardcodedContextOptions.ts delete mode 100644 backend/src/plugins/ContextMenus/utils/loadAllCommands.ts create mode 100644 backend/src/plugins/ModActions/functions/hasModActionPerm.ts delete mode 100644 backend/src/plugins/ModActions/functions/hasMutePerm.ts diff --git a/backend/src/data/GuildCases.ts b/backend/src/data/GuildCases.ts index d0e7778a..eb5ed6b7 100644 --- a/backend/src/data/GuildCases.ts +++ b/backend/src/data/GuildCases.ts @@ -83,6 +83,21 @@ export class GuildCases extends BaseGuildRepository { }); } + async getRecentByUserId(userId: string, count: number, skip = 0): Promise { + return this.cases.find({ + relations: this.getRelations(), + where: { + guild_id: this.guildId, + user_id: userId, + }, + skip, + take: count, + order: { + case_number: "DESC", + }, + }); + } + async getTotalCasesByModId(modId: string): Promise { return this.cases.count({ where: { diff --git a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts index c41e8c09..dc08389e 100644 --- a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts +++ b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts @@ -1,32 +1,30 @@ import { PluginOptions } from "knub"; -import { GuildContextMenuLinks } from "../../data/GuildContextMenuLinks"; +import { GuildCases } from "../../data/GuildCases"; import { makeIoTsConfigParser } from "../../pluginUtils"; +import { trimPluginDescription } from "../../utils"; +import { CasesPlugin } from "../Cases/CasesPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { MutesPlugin } from "../Mutes/MutesPlugin"; import { UtilityPlugin } from "../Utility/UtilityPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { ContextClickedEvt } from "./events/ContextClickedEvt"; +import { ModMenuCmd } from "./commands/ModMenuCmd"; import { ConfigSchema, ContextMenuPluginType } from "./types"; -import { loadAllCommands } from "./utils/loadAllCommands"; const defaultOptions: PluginOptions = { config: { can_use: false, - user_muteindef: false, - user_mute1d: false, - user_mute1h: false, - user_info: false, + can_open_mod_menu: false, - message_clean10: false, - message_clean25: false, - message_clean50: false, + log_channel: null, }, overrides: [ { level: ">=50", config: { can_use: true, + + can_open_mod_menu: true, }, }, ], @@ -34,24 +32,24 @@ const defaultOptions: PluginOptions = { export const ContextMenuPlugin = zeppelinGuildPlugin()({ name: "context_menu", - showInDocs: false, + showInDocs: true, + info: { + prettyName: "Context Menus", + description: trimPluginDescription(` + This plugin provides command shortcuts via context menus + `), + configSchema: ConfigSchema, + }, - dependencies: () => [MutesPlugin, LogsPlugin, UtilityPlugin], + dependencies: () => [CasesPlugin, MutesPlugin, LogsPlugin, UtilityPlugin], configParser: makeIoTsConfigParser(ConfigSchema), defaultOptions, - // prettier-ignore - events: [ - ContextClickedEvt, - ], + contextMenuCommands: [ModMenuCmd], beforeLoad(pluginData) { const { state, guild } = pluginData; - state.contextMenuLinks = new GuildContextMenuLinks(guild.id); - }, - - afterLoad(pluginData) { - loadAllCommands(pluginData); + state.cases = GuildCases.getGuildInstance(guild.id); }, }); diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts new file mode 100644 index 00000000..38ec91a1 --- /dev/null +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -0,0 +1,97 @@ +import { + ActionRowBuilder, + ButtonInteraction, + ModalBuilder, + ModalSubmitInteraction, + TextInputBuilder, + TextInputStyle, +} from "discord.js"; +import humanizeDuration from "humanize-duration"; +import { GuildPluginData } from "knub"; +import { canActOn } from "src/pluginUtils"; +import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { convertDelayStringToMS, renderUserUsername } from "../../../utils"; +import { CaseArgs } from "../../Cases/types"; +import { MODAL_TIMEOUT } from "../commands/ModMenuCmd"; +import { ContextMenuPluginType } from "../types"; + +async function banAction( + pluginData: GuildPluginData, + duration: string | undefined, + reason: string | undefined, + target: string, + interaction: ButtonInteraction, +) { + const executingMember = await pluginData.guild.members.fetch(interaction.user.id); + const userCfg = await pluginData.config.getMatchingConfig({ + channelId: interaction.channelId, + member: executingMember, + }); + + const modactions = pluginData.getPlugin(ModActionsPlugin); + if (!userCfg.can_use || !(await modactions.hasBanPermission(executingMember, interaction.channelId))) { + await interaction.editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }); + return; + } + + const targetMember = await pluginData.guild.members.fetch(target); + if (!canActOn(pluginData, executingMember, targetMember)) { + await interaction.editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }); + return; + } + + const caseArgs: Partial = { + modId: executingMember.id, + }; + + const durationMs = duration ? convertDelayStringToMS(duration)! : undefined; + const result = await modactions.banUserId(target, reason, { caseArgs }, durationMs); + if (result.status === "failed") { + await interaction.editReply({ content: "ERROR: Failed to ban user", embeds: [], components: [] }); + return; + } + + const userName = renderUserUsername(targetMember.user); + const messageResultText = result.notifyResult.text ? ` (${result.notifyResult.text})` : ""; + const banMessage = `Banned **${userName}** ${ + durationMs ? `for ${humanizeDuration(durationMs)}` : "indefinitely" + } (Case #${result.case.case_number})${messageResultText}`; + + await interaction.editReply({ content: banMessage, embeds: [], components: [] }); +} + +export async function launchBanActionModal( + pluginData: GuildPluginData, + interaction: ButtonInteraction, + target: string, +) { + const modal = new ModalBuilder().setCustomId("ban").setTitle("Ban"); + + const durationIn = new TextInputBuilder() + .setCustomId("duration") + .setLabel("Duration (Optional)") + .setRequired(false) + .setStyle(TextInputStyle.Short); + + const reasonIn = new TextInputBuilder() + .setCustomId("reason") + .setLabel("Reason (Optional)") + .setRequired(false) + .setStyle(TextInputStyle.Paragraph); + + const durationRow = new ActionRowBuilder().addComponents(durationIn); + const reasonRow = new ActionRowBuilder().addComponents(reasonIn); + + modal.addComponents(durationRow, reasonRow); + + await interaction.showModal(modal); + const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); + if (submitted) { + await submitted.deferUpdate(); + + const duration = submitted.fields.getTextInputValue("duration"); + const reason = submitted.fields.getTextInputValue("reason"); + + await banAction(pluginData, duration, reason, target, interaction); + } +} diff --git a/backend/src/plugins/ContextMenus/actions/clean.ts b/backend/src/plugins/ContextMenus/actions/clean.ts index a9d2384b..6274f230 100644 --- a/backend/src/plugins/ContextMenus/actions/clean.ts +++ b/backend/src/plugins/ContextMenus/actions/clean.ts @@ -1,16 +1,22 @@ -import { ContextMenuCommandInteraction, TextChannel } from "discord.js"; +import { + ActionRowBuilder, + ButtonInteraction, + ModalBuilder, + ModalSubmitInteraction, + TextInputBuilder, + TextInputStyle, +} from "discord.js"; import { GuildPluginData } from "knub"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; import { UtilityPlugin } from "../../../plugins/Utility/UtilityPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { MODAL_TIMEOUT } from "../commands/ModMenuCmd"; import { ContextMenuPluginType } from "../types"; export async function cleanAction( pluginData: GuildPluginData, amount: number, - interaction: ContextMenuCommandInteraction, + target: string, + interaction: ButtonInteraction, ) { - await interaction.deferReply({ ephemeral: true }); const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -19,32 +25,42 @@ export async function cleanAction( const utility = pluginData.getPlugin(UtilityPlugin); if (!userCfg.can_use || !(await utility.hasPermission(executingMember, interaction.channelId, "can_clean"))) { - await interaction.followUp({ content: "Cannot clean: insufficient permissions" }); + await interaction.editReply({ content: "Cannot clean: insufficient permissions", embeds: [], components: [] }); return; } - const targetMessage = interaction.channel - ? await interaction.channel.messages.fetch(interaction.targetId) - : await (pluginData.guild.channels.resolve(interaction.channelId) as TextChannel).messages.fetch( - interaction.targetId, - ); + // TODO: Implement message cleaning + await interaction.editReply({ + content: `TODO: Implementation incomplete`, + embeds: [], + components: [], + }); +} - const targetUserOnly = false; - const deletePins = false; - const user = undefined; +export async function launchCleanActionModal( + pluginData: GuildPluginData, + interaction: ButtonInteraction, + target: string, +) { + const modal = new ModalBuilder().setCustomId("clean").setTitle("Clean"); - try { - await interaction.followUp(`Cleaning... Amount: ${amount}, User Only: ${targetUserOnly}, Pins: ${deletePins}`); - utility.clean({ count: amount, user, channel: targetMessage.channel.id, "delete-pins": deletePins }, targetMessage); - } catch (e) { - await interaction.followUp({ ephemeral: true, content: "Plugin error, please check your BOT_ALERTs" }); + const amountIn = new TextInputBuilder().setCustomId("amount").setLabel("Amount").setStyle(TextInputStyle.Short); - if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { - pluginData.getPlugin(LogsPlugin).logBotAlert({ - body: `Failed to clean in <#${interaction.channelId}> in ContextMenu action \`clean\`:_ ${e}`, - }); - } else { - throw e; + const amountRow = new ActionRowBuilder().addComponents(amountIn); + + modal.addComponents(amountRow); + + await interaction.showModal(modal); + const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); + if (submitted) { + await submitted.deferUpdate(); + + const amount = submitted.fields.getTextInputValue("amount"); + if (isNaN(Number(amount))) { + interaction.editReply({ content: `ERROR: Amount ${amount} is invalid`, embeds: [], components: [] }); + return; } + + await cleanAction(pluginData, Number(amount), target, interaction); } } diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index 7fe2f5d5..a86a5ddd 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -1,4 +1,11 @@ -import { ContextMenuCommandInteraction } from "discord.js"; +import { + ActionRowBuilder, + ButtonInteraction, + ModalBuilder, + ModalSubmitInteraction, + TextInputBuilder, + TextInputStyle, +} from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { canActOn } from "src/pluginUtils"; @@ -8,14 +15,16 @@ import { convertDelayStringToMS } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { MutesPlugin } from "../../Mutes/MutesPlugin"; +import { MODAL_TIMEOUT } from "../commands/ModMenuCmd"; import { ContextMenuPluginType } from "../types"; -export async function muteAction( +async function muteAction( pluginData: GuildPluginData, duration: string | undefined, - interaction: ContextMenuCommandInteraction, + reason: string | undefined, + target: string, + interaction: ButtonInteraction, ) { - await interaction.deferReply({ ephemeral: true }); const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -24,43 +33,76 @@ export async function muteAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasMutePermission(executingMember, interaction.channelId))) { - await interaction.followUp({ content: "Cannot mute: insufficient permissions" }); + await interaction.editReply({ content: "Cannot mute: insufficient permissions", embeds: [], components: [] }); return; } - const durationMs = duration ? convertDelayStringToMS(duration)! : undefined; - const mutes = pluginData.getPlugin(MutesPlugin); - const userId = interaction.targetId; - const targetMember = await pluginData.guild.members.fetch(interaction.targetId); - + const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interaction.followUp({ ephemeral: true, content: "Cannot mute: insufficient permissions" }); + await interaction.editReply({ content: "Cannot mute: insufficient permissions", embeds: [], components: [] }); return; } const caseArgs: Partial = { modId: executingMember.id, }; + const mutes = pluginData.getPlugin(MutesPlugin); + const durationMs = duration ? convertDelayStringToMS(duration)! : undefined; try { - const result = await mutes.muteUser(userId, durationMs, "Context Menu Action", { caseArgs }); + const result = await mutes.muteUser(target, durationMs, reason, { caseArgs }); + const messageResultText = result.notifyResult.text ? ` (${result.notifyResult.text})` : ""; const muteMessage = `Muted **${result.case.user_name}** ${ durationMs ? `for ${humanizeDuration(durationMs)}` : "indefinitely" - } (Case #${result.case.case_number}) (user notified via ${ - result.notifyResult.method ?? "dm" - })\nPlease update the new case with the \`update\` command`; + } (Case #${result.case.case_number})${messageResultText}`; - await interaction.followUp({ ephemeral: true, content: muteMessage }); + await interaction.editReply({ content: muteMessage, embeds: [], components: [] }); } catch (e) { - await interaction.followUp({ ephemeral: true, content: "Plugin error, please check your BOT_ALERTs" }); + await interaction.editReply({ content: "Plugin error, please check your BOT_ALERTs", embeds: [], components: [] }); if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { pluginData.getPlugin(LogsPlugin).logBotAlert({ - body: `Failed to mute <@!${userId}> in ContextMenu action \`mute\` because a mute role has not been specified in server config`, + body: `Failed to mute <@!${target}> in ContextMenu action \`mute\` because a mute role has not been specified in server config`, }); } else { throw e; } } } + +export async function launchMuteActionModal( + pluginData: GuildPluginData, + interaction: ButtonInteraction, + target: string, +) { + const modal = new ModalBuilder().setCustomId("mute").setTitle("Mute"); + + const durationIn = new TextInputBuilder() + .setCustomId("duration") + .setLabel("Duration (Optional)") + .setRequired(false) + .setStyle(TextInputStyle.Short); + + const reasonIn = new TextInputBuilder() + .setCustomId("reason") + .setLabel("Reason (Optional)") + .setRequired(false) + .setStyle(TextInputStyle.Paragraph); + + const durationRow = new ActionRowBuilder().addComponents(durationIn); + const reasonRow = new ActionRowBuilder().addComponents(reasonIn); + + modal.addComponents(durationRow, reasonRow); + + await interaction.showModal(modal); + const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); + if (submitted) { + await submitted.deferUpdate(); + + const duration = submitted.fields.getTextInputValue("duration"); + const reason = submitted.fields.getTextInputValue("reason"); + + await muteAction(pluginData, duration, reason, target, interaction); + } +} diff --git a/backend/src/plugins/ContextMenus/actions/note.ts b/backend/src/plugins/ContextMenus/actions/note.ts new file mode 100644 index 00000000..13d855d5 --- /dev/null +++ b/backend/src/plugins/ContextMenus/actions/note.ts @@ -0,0 +1,88 @@ +import { + ActionRowBuilder, + ButtonInteraction, + ModalBuilder, + ModalSubmitInteraction, + TextInputBuilder, + TextInputStyle, +} from "discord.js"; +import { GuildPluginData } from "knub"; +import { canActOn } from "src/pluginUtils"; +import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { renderUserUsername } from "../../../utils"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { MODAL_TIMEOUT } from "../commands/ModMenuCmd"; +import { ContextMenuPluginType } from "../types"; + +async function noteAction( + pluginData: GuildPluginData, + reason: string, + target: string, + interaction: ButtonInteraction, +) { + const executingMember = await pluginData.guild.members.fetch(interaction.user.id); + const userCfg = await pluginData.config.getMatchingConfig({ + channelId: interaction.channelId, + member: executingMember, + }); + + const modactions = pluginData.getPlugin(ModActionsPlugin); + if (!userCfg.can_use || !(await modactions.hasNotePermission(executingMember, interaction.channelId))) { + await interaction.editReply({ content: "Cannot note: insufficient permissions", embeds: [], components: [] }); + return; + } + + const targetMember = await pluginData.guild.members.fetch(target); + if (!canActOn(pluginData, executingMember, targetMember)) { + await interaction.editReply({ content: "Cannot mute: insufficient permissions", embeds: [], components: [] }); + return; + } + + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const createdCase = await casesPlugin.createCase({ + userId: target, + modId: executingMember.id, + type: CaseTypes.Note, + reason, + }); + + pluginData.getPlugin(LogsPlugin).logMemberNote({ + mod: interaction.user, + user: targetMember.user, + caseNumber: createdCase.case_number, + reason, + }); + + const userName = renderUserUsername(targetMember.user); + await interaction.editReply({ + content: `Note added on **${userName}** (Case #${createdCase.case_number})`, + embeds: [], + components: [], + }); +} + +export async function launchNoteActionModal( + pluginData: GuildPluginData, + interaction: ButtonInteraction, + target: string, +) { + const modal = new ModalBuilder().setCustomId("note").setTitle("Note"); + + const reasonIn = new TextInputBuilder().setCustomId("reason").setLabel("Note").setStyle(TextInputStyle.Paragraph); + + const reasonRow = new ActionRowBuilder().addComponents(reasonIn); + + modal.addComponents(reasonRow); + + await interaction.showModal(modal); + const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); + if (submitted) { + await submitted.deferUpdate(); + + const reason = submitted.fields.getTextInputValue("reason"); + + await noteAction(pluginData, reason, target, interaction); + } +} diff --git a/backend/src/plugins/ContextMenus/actions/userInfo.ts b/backend/src/plugins/ContextMenus/actions/userInfo.ts deleted file mode 100644 index e445e1c8..00000000 --- a/backend/src/plugins/ContextMenus/actions/userInfo.ts +++ /dev/null @@ -1,28 +0,0 @@ -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: ContextMenuCommandInteraction, -) { - await interaction.deferReply({ ephemeral: true }); - const executingMember = await pluginData.guild.members.fetch(interaction.user.id); - const userCfg = await pluginData.config.getMatchingConfig({ - channelId: interaction.channelId, - member: executingMember, - }); - const utility = pluginData.getPlugin(UtilityPlugin); - - if (userCfg.can_use && (await utility.hasPermission(executingMember, interaction.channelId, "can_userinfo"))) { - const embed = await utility.userInfo(interaction.targetId, interaction.user.id); - if (!embed) { - await interaction.followUp({ content: "Cannot info: internal error" }); - return; - } - await interaction.followUp({ embeds: [embed] }); - } else { - await interaction.followUp({ content: "Cannot info: insufficient permissions" }); - } -} diff --git a/backend/src/plugins/ContextMenus/actions/warn.ts b/backend/src/plugins/ContextMenus/actions/warn.ts new file mode 100644 index 00000000..bbfa66c5 --- /dev/null +++ b/backend/src/plugins/ContextMenus/actions/warn.ts @@ -0,0 +1,80 @@ +import { + ActionRowBuilder, + ButtonInteraction, + ModalBuilder, + ModalSubmitInteraction, + TextInputBuilder, + TextInputStyle, +} from "discord.js"; +import { GuildPluginData } from "knub"; +import { canActOn } from "src/pluginUtils"; +import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { renderUserUsername } from "../../../utils"; +import { CaseArgs } from "../../Cases/types"; +import { MODAL_TIMEOUT } from "../commands/ModMenuCmd"; +import { ContextMenuPluginType } from "../types"; + +async function warnAction( + pluginData: GuildPluginData, + reason: string, + target: string, + interaction: ButtonInteraction, +) { + const executingMember = await pluginData.guild.members.fetch(interaction.user.id); + const userCfg = await pluginData.config.getMatchingConfig({ + channelId: interaction.channelId, + member: executingMember, + }); + + const modactions = pluginData.getPlugin(ModActionsPlugin); + if (!userCfg.can_use || !(await modactions.hasWarnPermission(executingMember, interaction.channelId))) { + await interaction.editReply({ content: "Cannot warn: insufficient permissions", embeds: [], components: [] }); + return; + } + + const targetMember = await pluginData.guild.members.fetch(target); + if (!canActOn(pluginData, executingMember, targetMember)) { + await interaction.editReply({ content: "Cannot mute: insufficient permissions", embeds: [], components: [] }); + return; + } + + const caseArgs: Partial = { + modId: executingMember.id, + }; + + const result = await modactions.warnMember(targetMember, reason, { caseArgs }); + if (result.status === "failed") { + await interaction.editReply({ content: "Failed to warn user", embeds: [], components: [] }); + return; + } + + const userName = renderUserUsername(targetMember.user); + const messageResultText = result.notifyResult.text ? ` (${result.notifyResult.text})` : ""; + const muteMessage = `Warned **${userName}** (Case #${result.case.case_number})${messageResultText}`; + + await interaction.editReply({ content: muteMessage, embeds: [], components: [] }); +} + +export async function launchWarnActionModal( + pluginData: GuildPluginData, + interaction: ButtonInteraction, + target: string, +) { + const modal = new ModalBuilder().setCustomId("warn").setTitle("Warn"); + + const reasonIn = new TextInputBuilder().setCustomId("reason").setLabel("Reason").setStyle(TextInputStyle.Paragraph); + + const reasonRow = new ActionRowBuilder().addComponents(reasonIn); + + modal.addComponents(reasonRow); + + await interaction.showModal(modal); + const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); + if (submitted) { + await submitted.deferUpdate(); + + const reason = submitted.fields.getTextInputValue("reason"); + + await warnAction(pluginData, reason, target, interaction); + } +} diff --git a/backend/src/plugins/ContextMenus/commands/ModMenuCmd.ts b/backend/src/plugins/ContextMenus/commands/ModMenuCmd.ts new file mode 100644 index 00000000..faf9bd2f --- /dev/null +++ b/backend/src/plugins/ContextMenus/commands/ModMenuCmd.ts @@ -0,0 +1,319 @@ +import { + APIEmbed, + ActionRowBuilder, + ButtonBuilder, + ButtonInteraction, + ButtonStyle, + ContextMenuCommandInteraction, + User, +} from "discord.js"; +import { GuildPluginData, guildPluginUserContextMenuCommand } from "knub"; +import { Case } from "../../../data/entities/Case"; +import { getUserInfoEmbed } from "../../../plugins/Utility/functions/getUserInfoEmbed"; +import { SECONDS, UnknownUser, emptyEmbedValue, renderUserUsername, resolveUser, trimLines } from "../../../utils"; +import { asyncMap } from "../../../utils/async"; +import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; +import { getGuildPrefix } from "../../../utils/getGuildPrefix"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { UtilityPlugin } from "../../Utility/UtilityPlugin"; +import { launchBanActionModal } from "../actions/ban"; +import { launchCleanActionModal } from "../actions/clean"; +import { launchMuteActionModal } from "../actions/mute"; +import { launchNoteActionModal } from "../actions/note"; +import { launchWarnActionModal } from "../actions/warn"; +import { + ContextMenuPluginType, + LoadModMenuPageFn, + ModMenuActionOpts, + ModMenuActionType, + ModMenuNavigationType, +} from "../types"; + +export const MODAL_TIMEOUT = 60 * SECONDS; +const MOD_MENU_TIMEOUT = 60 * SECONDS; +const CASES_PER_PAGE = 10; + +export const ModMenuCmd = guildPluginUserContextMenuCommand({ + name: "Mod Menu", + async run({ pluginData, interaction }) { + await interaction.deferReply({ ephemeral: true }); + + // Run permission checks for executing user. + const executingMember = await pluginData.guild.members.fetch(interaction.user.id); + const userCfg = await pluginData.config.getMatchingConfig({ + channelId: interaction.channelId, + member: executingMember, + }); + const utility = pluginData.getPlugin(UtilityPlugin); + if ( + !userCfg.can_use || + (await !utility.hasPermission(executingMember, interaction.channelId, "can_open_mod_menu")) + ) { + await interaction.followUp({ content: "Error: Insufficient Permissions" }); + return; + } + + const user = await resolveUser(pluginData.client, interaction.targetId); + if (!user.id) { + await interaction.followUp("Error: User not found"); + return; + } + + // Load cases and display mod menu + const cases: Case[] = await pluginData.state.cases.with("notes").getByUserId(user.id); + const userName = + user instanceof UnknownUser && cases.length ? cases[cases.length - 1].user_name : renderUserUsername(user); + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const totalCases = cases.length; + const totalPages: number = Math.max(Math.ceil(totalCases / CASES_PER_PAGE), 1); + const prefix = getGuildPrefix(pluginData); + const infoEmbed = await getUserInfoEmbed(pluginData, user.id, false); + displayModMenu( + pluginData, + interaction, + totalPages, + async (page) => { + const pageCases: Case[] = await pluginData.state.cases + .with("notes") + .getRecentByUserId(user.id, CASES_PER_PAGE, (page - 1) * CASES_PER_PAGE); + const lines = await asyncMap(pageCases, (c) => casesPlugin.getCaseSummary(c, true, interaction.targetId)); + + const firstCaseNum = (page - 1) * CASES_PER_PAGE + 1; + const lastCaseNum = Math.min(page * CASES_PER_PAGE, totalCases); + const title = + lines.length == 0 + ? `${userName}` + : `Most recent cases for ${userName} | ${firstCaseNum}-${lastCaseNum} of ${totalCases}`; + const embedFields = + lines.length == 0 + ? [ + { + name: `**No cases found**`, + value: "", + }, + ] + : [ + ...getChunkedEmbedFields( + emptyEmbedValue, + lines.length == 0 ? `No cases found for **${userName}**` : lines.join("\n"), + ), + { + name: emptyEmbedValue, + value: trimLines(` + Use \`${prefix}case \` to see more information about an individual case + `), + }, + ]; + + const embed = { + author: { + name: title, + icon_url: user instanceof User ? user.displayAvatarURL() : undefined, + }, + fields: embedFields, + footer: { text: `Page ${page}/${totalPages}` }, + } satisfies APIEmbed; + + return embed; + }, + infoEmbed, + ); + }, +}); + +async function displayModMenu( + pluginData: GuildPluginData, + interaction: ContextMenuCommandInteraction, + totalPages: number, + loadPage: LoadModMenuPageFn, + infoEmbed: APIEmbed | null, +) { + if (interaction.deferred == false) { + await interaction.deferReply(); + } + + const firstButton = new ButtonBuilder() + .setStyle(ButtonStyle.Primary) + .setLabel("<<") + .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.FIRST })) + .setDisabled(true); + const prevButton = new ButtonBuilder() + .setStyle(ButtonStyle.Primary) + .setLabel("<") + .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.PREV })) + .setDisabled(true); + const infoButton = new ButtonBuilder() + .setStyle(ButtonStyle.Primary) + .setLabel("Info") + .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.INFO })) + .setDisabled(infoEmbed != null ? false : true); + const nextButton = new ButtonBuilder() + .setStyle(ButtonStyle.Primary) + .setLabel(">") + .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.NEXT })) + .setDisabled(totalPages > 1 ? false : true); + const lastButton = new ButtonBuilder() + .setStyle(ButtonStyle.Primary) + .setLabel(">>") + .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.LAST })) + .setDisabled(totalPages > 1 ? false : true); + const navigationButtons = [firstButton, prevButton, infoButton, nextButton, lastButton] satisfies ButtonBuilder[]; + + const moderationButtons = [ + new ButtonBuilder() + .setStyle(ButtonStyle.Secondary) + .setLabel("Note") + .setCustomId(serializeCustomId({ action: ModMenuActionType.NOTE, target: interaction.targetId })), + new ButtonBuilder() + .setStyle(ButtonStyle.Secondary) + .setLabel("Warn") + .setCustomId(serializeCustomId({ action: ModMenuActionType.WARN, target: interaction.targetId })), + new ButtonBuilder() + .setStyle(ButtonStyle.Secondary) + .setLabel("Clean") + .setCustomId(serializeCustomId({ action: ModMenuActionType.CLEAN, target: interaction.targetId })), + new ButtonBuilder() + .setStyle(ButtonStyle.Secondary) + .setLabel("Mute") + .setCustomId(serializeCustomId({ action: ModMenuActionType.MUTE, target: interaction.targetId })), + new ButtonBuilder() + .setStyle(ButtonStyle.Secondary) + .setLabel("Ban") + .setCustomId(serializeCustomId({ action: ModMenuActionType.BAN, target: interaction.targetId })), + ] satisfies ButtonBuilder[]; + + const navigationRow = new ActionRowBuilder().addComponents(navigationButtons); + const moderationRow = new ActionRowBuilder().addComponents(moderationButtons); + + let page = 1; + const currentPage = await interaction.editReply({ + embeds: [await loadPage(page)], + components: [navigationRow, moderationRow], + }); + + const collector = await currentPage.createMessageComponentCollector({ + time: MOD_MENU_TIMEOUT, + }); + + collector.on("collect", async (i) => { + const opts = deserializeCustomId(i.customId); + if (opts.action == ModMenuActionType.PAGE) { + await i.deferUpdate(); + } + + // Update displayed embed if any navigation buttons were used + if (opts.action == ModMenuActionType.PAGE && opts.target == ModMenuNavigationType.INFO && infoEmbed != null) { + infoButton + .setLabel("Cases") + .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.CASES })); + firstButton.setDisabled(true); + prevButton.setDisabled(true); + nextButton.setDisabled(true); + lastButton.setDisabled(true); + + await i.editReply({ + embeds: [infoEmbed], + components: [navigationRow, moderationRow], + }); + } else if (opts.action == ModMenuActionType.PAGE && opts.target == ModMenuNavigationType.CASES) { + infoButton + .setLabel("Info") + .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.INFO })); + updateNavButtonState(firstButton, prevButton, nextButton, lastButton, page, totalPages); + + await i.editReply({ + embeds: [await loadPage(page)], + components: [navigationRow, moderationRow], + }); + } else if (opts.action == ModMenuActionType.PAGE) { + let pageDelta = 0; + switch (opts.target) { + case ModMenuNavigationType.PREV: + pageDelta = -1; + break; + case ModMenuNavigationType.NEXT: + pageDelta = 1; + break; + } + + let newPage = 1; + if (opts.target == ModMenuNavigationType.PREV || opts.target == ModMenuNavigationType.NEXT) { + newPage = Math.max(Math.min(page + pageDelta, totalPages), 1); + } else if (opts.target == ModMenuNavigationType.FIRST) { + newPage = 1; + } else if (opts.target == ModMenuNavigationType.LAST) { + newPage = totalPages; + } + + if (newPage != page) { + updateNavButtonState(firstButton, prevButton, nextButton, lastButton, newPage, totalPages); + + await i.editReply({ + embeds: [await loadPage(newPage)], + components: [navigationRow, moderationRow], + }); + + page = newPage; + } + } else if (opts.action == ModMenuActionType.NOTE) { + await launchNoteActionModal(pluginData, i as ButtonInteraction, opts.target); + } else if (opts.action == ModMenuActionType.WARN) { + await launchWarnActionModal(pluginData, i as ButtonInteraction, opts.target); + } else if (opts.action == ModMenuActionType.CLEAN) { + await launchCleanActionModal(pluginData, i as ButtonInteraction, opts.target); + } else if (opts.action == ModMenuActionType.MUTE) { + await launchMuteActionModal(pluginData, i as ButtonInteraction, opts.target); + } else if (opts.action == ModMenuActionType.BAN) { + await launchBanActionModal(pluginData, i as ButtonInteraction, opts.target); + } + + collector.resetTimer(); + }); + + // Remove components on timeout. + collector.on("end", async (_, reason) => { + if (reason !== "messageDelete") { + interaction.editReply({ + components: [], + }); + } + }); +} + +function serializeCustomId(opts: ModMenuActionOpts) { + return `${opts.action}:${opts.target}`; +} + +function deserializeCustomId(customId: string): ModMenuActionOpts { + const opts: ModMenuActionOpts = { + action: customId.split(":")[0] as ModMenuActionType, + target: customId.split(":")[1], + }; + + return opts; +} + +function updateNavButtonState( + firstButton: ButtonBuilder, + prevButton: ButtonBuilder, + nextButton: ButtonBuilder, + lastButton: ButtonBuilder, + currentPage: number, + totalPages: number, +) { + if (currentPage > 1) { + firstButton.setDisabled(false); + prevButton.setDisabled(false); + } else { + firstButton.setDisabled(true); + prevButton.setDisabled(true); + } + + if (currentPage == totalPages) { + nextButton.setDisabled(true); + lastButton.setDisabled(true); + } else { + nextButton.setDisabled(false); + lastButton.setDisabled(false); + } +} diff --git a/backend/src/plugins/ContextMenus/events/ContextClickedEvt.ts b/backend/src/plugins/ContextMenus/events/ContextClickedEvt.ts deleted file mode 100644 index 98e6ab1f..00000000 --- a/backend/src/plugins/ContextMenus/events/ContextClickedEvt.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { contextMenuEvt } from "../types"; -import { routeContextAction } from "../utils/contextRouter"; - -export const ContextClickedEvt = contextMenuEvt({ - event: "interactionCreate", - - async listener(meta) { - if (!meta.args.interaction.isContextMenuCommand()) return; - const inter = meta.args.interaction; - await routeContextAction(meta.pluginData, inter); - }, -}); diff --git a/backend/src/plugins/ContextMenus/types.ts b/backend/src/plugins/ContextMenus/types.ts index 02c4a29c..b4340b1b 100644 --- a/backend/src/plugins/ContextMenus/types.ts +++ b/backend/src/plugins/ContextMenus/types.ts @@ -1,25 +1,52 @@ +import { APIEmbed, Awaitable } from "discord.js"; import * as t from "io-ts"; -import { BasePluginType, guildPluginEventListener } from "knub"; -import { GuildContextMenuLinks } from "../../data/GuildContextMenuLinks"; +import { BasePluginType } from "knub"; +import { GuildCases } from "../../data/GuildCases"; +import { GuildLogs } from "../../data/GuildLogs"; +import { GuildMutes } from "../../data/GuildMutes"; +import { GuildTempbans } from "../../data/GuildTempbans"; +import { tNullable } from "../../utils"; export const ConfigSchema = t.type({ can_use: t.boolean, - user_muteindef: t.boolean, - user_mute1d: t.boolean, - user_mute1h: t.boolean, - user_info: t.boolean, - message_clean10: t.boolean, - message_clean25: t.boolean, - message_clean50: t.boolean, + can_open_mod_menu: t.boolean, + + log_channel: tNullable(t.string), }); export type TConfigSchema = t.TypeOf; export interface ContextMenuPluginType extends BasePluginType { config: TConfigSchema; state: { - contextMenuLinks: GuildContextMenuLinks; + mutes: GuildMutes; + cases: GuildCases; + tempbans: GuildTempbans; + serverLogs: GuildLogs; }; } -export const contextMenuEvt = guildPluginEventListener(); +export const enum ModMenuActionType { + PAGE = "page", + NOTE = "note", + WARN = "warn", + CLEAN = "clean", + MUTE = "mute", + BAN = "ban", +} + +export const enum ModMenuNavigationType { + FIRST = "first", + PREV = "prev", + NEXT = "next", + LAST = "last", + INFO = "info", + CASES = "cases", +} + +export interface ModMenuActionOpts { + action: ModMenuActionType; + target: string; +} + +export type LoadModMenuPageFn = (page: number) => Awaitable; diff --git a/backend/src/plugins/ContextMenus/utils/contextRouter.ts b/backend/src/plugins/ContextMenus/utils/contextRouter.ts deleted file mode 100644 index 18b7b064..00000000 --- a/backend/src/plugins/ContextMenus/utils/contextRouter.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ContextMenuCommandInteraction } from "discord.js"; -import { GuildPluginData } from "knub"; -import { ContextMenuPluginType } from "../types"; -import { hardcodedActions } from "./hardcodedContextOptions"; - -export async function routeContextAction( - pluginData: GuildPluginData, - interaction: ContextMenuCommandInteraction, -) { - const contextLink = await pluginData.state.contextMenuLinks.get(interaction.commandId); - if (!contextLink) return; - hardcodedActions[contextLink.action_name](pluginData, interaction); -} diff --git a/backend/src/plugins/ContextMenus/utils/hardcodedContextOptions.ts b/backend/src/plugins/ContextMenus/utils/hardcodedContextOptions.ts deleted file mode 100644 index 84593ace..00000000 --- a/backend/src/plugins/ContextMenus/utils/hardcodedContextOptions.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { cleanAction } from "../actions/clean"; -import { muteAction } from "../actions/mute"; -import { userInfoAction } from "../actions/userInfo"; - -export const hardcodedContext: Record = { - user_muteindef: "Mute Indefinitely", - user_mute1d: "Mute for 1 day", - user_mute1h: "Mute for 1 hour", - user_info: "Get Info", - message_clean10: "Clean 10 messages", - message_clean25: "Clean 25 messages", - message_clean50: "Clean 50 messages", -}; - -export const hardcodedActions = { - user_muteindef: (pluginData, interaction) => muteAction(pluginData, undefined, interaction), - user_mute1d: (pluginData, interaction) => muteAction(pluginData, "1d", interaction), - user_mute1h: (pluginData, interaction) => muteAction(pluginData, "1h", interaction), - user_info: (pluginData, interaction) => userInfoAction(pluginData, interaction), - message_clean10: (pluginData, interaction) => cleanAction(pluginData, 10, interaction), - message_clean25: (pluginData, interaction) => cleanAction(pluginData, 25, interaction), - message_clean50: (pluginData, interaction) => cleanAction(pluginData, 50, interaction), -}; diff --git a/backend/src/plugins/ContextMenus/utils/loadAllCommands.ts b/backend/src/plugins/ContextMenus/utils/loadAllCommands.ts deleted file mode 100644 index 97d73dfb..00000000 --- a/backend/src/plugins/ContextMenus/utils/loadAllCommands.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { ApplicationCommandData, ApplicationCommandType } from "discord.js"; -import { GuildPluginData } from "knub"; -import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; -import { ContextMenuPluginType } from "../types"; -import { hardcodedContext } from "./hardcodedContextOptions"; - -export async function loadAllCommands(pluginData: GuildPluginData) { - const comms = await pluginData.client.application!.commands; - const cfg = pluginData.config.get(); - const newCommands: ApplicationCommandData[] = []; - const addedNames: string[] = []; - - for (const [name, label] of Object.entries(hardcodedContext)) { - if (!cfg[name]) continue; - - const type = name.startsWith("user") ? ApplicationCommandType.User : ApplicationCommandType.Message; - const data: ApplicationCommandData = { - type, - name: label, - }; - - addedNames.push(name); - newCommands.push(data); - } - - const setCommands = await comms.set(newCommands, pluginData.guild.id).catch((e) => { - pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unable to overwrite context menus: ${e}` }); - return undefined; - }); - if (!setCommands) return; - - const setCommandsArray = [...setCommands.values()]; - await pluginData.state.contextMenuLinks.deleteAll(); - - for (let i = 0; i < setCommandsArray.length; i++) { - const command = setCommandsArray[i]; - pluginData.state.contextMenuLinks.create(command.id, addedNames[i]); - } -} diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index bf83b13e..9b7d3404 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -41,7 +41,12 @@ import { CreateUnbanCaseOnManualUnbanEvt } from "./events/CreateUnbanCaseOnManua import { PostAlertOnMemberJoinEvt } from "./events/PostAlertOnMemberJoinEvt"; import { banUserId } from "./functions/banUserId"; import { clearTempban } from "./functions/clearTempban"; -import { hasMutePermission } from "./functions/hasMutePerm"; +import { + hasBanPermission, + hasMutePermission, + hasNotePermission, + hasWarnPermission, +} from "./functions/hasModActionPerm"; import { kickMember } from "./functions/kickMember"; import { offModActionsEvent } from "./functions/offModActionsEvent"; import { onModActionsEvent } from "./functions/onModActionsEvent"; @@ -158,7 +163,7 @@ export const ModActionsPlugin = zeppelinGuildPlugin()({ public: { warnMember(pluginData) { return (member: GuildMember, reason: string, warnOptions?: WarnOptions) => { - warnMember(pluginData, member, reason, warnOptions); + return warnMember(pluginData, member, reason, warnOptions); }; }, @@ -170,7 +175,7 @@ export const ModActionsPlugin = zeppelinGuildPlugin()({ banUserId(pluginData) { return (userId: string, reason?: string, banOptions?: BanOptions, banTime?: number) => { - banUserId(pluginData, userId, reason, banOptions, banTime); + return banUserId(pluginData, userId, reason, banOptions, banTime); }; }, @@ -180,12 +185,30 @@ export const ModActionsPlugin = zeppelinGuildPlugin()({ }; }, + hasNotePermission(pluginData) { + return (member: GuildMember, channelId: Snowflake) => { + return hasNotePermission(pluginData, member, channelId); + }; + }, + + hasWarnPermission(pluginData) { + return (member: GuildMember, channelId: Snowflake) => { + return hasWarnPermission(pluginData, member, channelId); + }; + }, + hasMutePermission(pluginData) { return (member: GuildMember, channelId: Snowflake) => { return hasMutePermission(pluginData, member, channelId); }; }, + hasBanPermission(pluginData) { + return (member: GuildMember, channelId: Snowflake) => { + return hasBanPermission(pluginData, member, channelId); + }; + }, + on: mapToPublicFn(onModActionsEvent), off: mapToPublicFn(offModActionsEvent), getEventEmitter(pluginData) { diff --git a/backend/src/plugins/ModActions/functions/hasModActionPerm.ts b/backend/src/plugins/ModActions/functions/hasModActionPerm.ts new file mode 100644 index 00000000..6e28768d --- /dev/null +++ b/backend/src/plugins/ModActions/functions/hasModActionPerm.ts @@ -0,0 +1,35 @@ +import { GuildMember, Snowflake } from "discord.js"; +import { GuildPluginData } from "knub"; +import { ModActionsPluginType } from "../types"; + +export async function hasNotePermission( + pluginData: GuildPluginData, + member: GuildMember, + channelId: Snowflake, +) { + return (await pluginData.config.getMatchingConfig({ member, channelId })).can_note; +} + +export async function hasWarnPermission( + pluginData: GuildPluginData, + member: GuildMember, + channelId: Snowflake, +) { + return (await pluginData.config.getMatchingConfig({ member, channelId })).can_warn; +} + +export async function hasMutePermission( + pluginData: GuildPluginData, + member: GuildMember, + channelId: Snowflake, +) { + return (await pluginData.config.getMatchingConfig({ member, channelId })).can_mute; +} + +export async function hasBanPermission( + pluginData: GuildPluginData, + member: GuildMember, + channelId: Snowflake, +) { + return (await pluginData.config.getMatchingConfig({ member, channelId })).can_ban; +} diff --git a/backend/src/plugins/ModActions/functions/hasMutePerm.ts b/backend/src/plugins/ModActions/functions/hasMutePerm.ts deleted file mode 100644 index b26edd4d..00000000 --- a/backend/src/plugins/ModActions/functions/hasMutePerm.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { GuildMember, Snowflake } from "discord.js"; -import { GuildPluginData } from "knub"; -import { ModActionsPluginType } from "../types"; - -export async function hasMutePermission( - pluginData: GuildPluginData, - member: GuildMember, - channelId: Snowflake, -) { - return (await pluginData.config.getMatchingConfig({ member, channelId })).can_mute; -} From 24b11800f550b9b7584ab705603d6c7ca9fc71cd Mon Sep 17 00:00:00 2001 From: Obliie Date: Sat, 15 Jul 2023 22:05:30 +0100 Subject: [PATCH 02/30] fix: plugin dependencies and cleanup --- .../plugins/ContextMenus/ContextMenuPlugin.ts | 6 ++-- .../src/plugins/ContextMenus/actions/ban.ts | 6 +--- .../src/plugins/ContextMenus/actions/clean.ts | 5 +-- .../src/plugins/ContextMenus/actions/mute.ts | 4 --- .../src/plugins/ContextMenus/actions/note.ts | 5 +-- .../src/plugins/ContextMenus/actions/warn.ts | 7 ++-- .../ContextMenus/commands/ModMenuCmd.ts | 33 +++++++------------ backend/src/plugins/ContextMenus/types.ts | 9 ----- 8 files changed, 20 insertions(+), 55 deletions(-) diff --git a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts index dc08389e..b48cc0ea 100644 --- a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts +++ b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts @@ -4,6 +4,7 @@ import { makeIoTsConfigParser } from "../../pluginUtils"; import { trimPluginDescription } from "../../utils"; import { CasesPlugin } from "../Cases/CasesPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; +import { ModActionsPlugin } from "../ModActions/ModActionsPlugin"; import { MutesPlugin } from "../Mutes/MutesPlugin"; import { UtilityPlugin } from "../Utility/UtilityPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; @@ -15,8 +16,6 @@ const defaultOptions: PluginOptions = { can_use: false, can_open_mod_menu: false, - - log_channel: null, }, overrides: [ { @@ -41,8 +40,9 @@ export const ContextMenuPlugin = zeppelinGuildPlugin()({ configSchema: ConfigSchema, }, - dependencies: () => [CasesPlugin, MutesPlugin, LogsPlugin, UtilityPlugin], + dependencies: () => [CasesPlugin, MutesPlugin, ModActionsPlugin, LogsPlugin, UtilityPlugin], configParser: makeIoTsConfigParser(ConfigSchema), + defaultOptions, contextMenuCommands: [ModMenuCmd], diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts index 38ec91a1..bfe7bc13 100644 --- a/backend/src/plugins/ContextMenus/actions/ban.ts +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -47,7 +47,7 @@ async function banAction( const durationMs = duration ? convertDelayStringToMS(duration)! : undefined; const result = await modactions.banUserId(target, reason, { caseArgs }, durationMs); if (result.status === "failed") { - await interaction.editReply({ content: "ERROR: Failed to ban user", embeds: [], components: [] }); + await interaction.editReply({ content: "Error: Failed to ban user", embeds: [], components: [] }); return; } @@ -66,22 +66,18 @@ export async function launchBanActionModal( target: string, ) { const modal = new ModalBuilder().setCustomId("ban").setTitle("Ban"); - const durationIn = new TextInputBuilder() .setCustomId("duration") .setLabel("Duration (Optional)") .setRequired(false) .setStyle(TextInputStyle.Short); - const reasonIn = new TextInputBuilder() .setCustomId("reason") .setLabel("Reason (Optional)") .setRequired(false) .setStyle(TextInputStyle.Paragraph); - const durationRow = new ActionRowBuilder().addComponents(durationIn); const reasonRow = new ActionRowBuilder().addComponents(reasonIn); - modal.addComponents(durationRow, reasonRow); await interaction.showModal(modal); diff --git a/backend/src/plugins/ContextMenus/actions/clean.ts b/backend/src/plugins/ContextMenus/actions/clean.ts index 6274f230..3d005bfb 100644 --- a/backend/src/plugins/ContextMenus/actions/clean.ts +++ b/backend/src/plugins/ContextMenus/actions/clean.ts @@ -43,11 +43,8 @@ export async function launchCleanActionModal( target: string, ) { const modal = new ModalBuilder().setCustomId("clean").setTitle("Clean"); - const amountIn = new TextInputBuilder().setCustomId("amount").setLabel("Amount").setStyle(TextInputStyle.Short); - const amountRow = new ActionRowBuilder().addComponents(amountIn); - modal.addComponents(amountRow); await interaction.showModal(modal); @@ -57,7 +54,7 @@ export async function launchCleanActionModal( const amount = submitted.fields.getTextInputValue("amount"); if (isNaN(Number(amount))) { - interaction.editReply({ content: `ERROR: Amount ${amount} is invalid`, embeds: [], components: [] }); + interaction.editReply({ content: `Error: Amount '${amount}' is invalid`, embeds: [], components: [] }); return; } diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index a86a5ddd..90a04575 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -77,22 +77,18 @@ export async function launchMuteActionModal( target: string, ) { const modal = new ModalBuilder().setCustomId("mute").setTitle("Mute"); - const durationIn = new TextInputBuilder() .setCustomId("duration") .setLabel("Duration (Optional)") .setRequired(false) .setStyle(TextInputStyle.Short); - const reasonIn = new TextInputBuilder() .setCustomId("reason") .setLabel("Reason (Optional)") .setRequired(false) .setStyle(TextInputStyle.Paragraph); - const durationRow = new ActionRowBuilder().addComponents(durationIn); const reasonRow = new ActionRowBuilder().addComponents(reasonIn); - modal.addComponents(durationRow, reasonRow); await interaction.showModal(modal); diff --git a/backend/src/plugins/ContextMenus/actions/note.ts b/backend/src/plugins/ContextMenus/actions/note.ts index 13d855d5..84b0e2bb 100644 --- a/backend/src/plugins/ContextMenus/actions/note.ts +++ b/backend/src/plugins/ContextMenus/actions/note.ts @@ -36,7 +36,7 @@ async function noteAction( const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interaction.editReply({ content: "Cannot mute: insufficient permissions", embeds: [], components: [] }); + await interaction.editReply({ content: "Cannot note: insufficient permissions", embeds: [], components: [] }); return; } @@ -69,11 +69,8 @@ export async function launchNoteActionModal( target: string, ) { const modal = new ModalBuilder().setCustomId("note").setTitle("Note"); - const reasonIn = new TextInputBuilder().setCustomId("reason").setLabel("Note").setStyle(TextInputStyle.Paragraph); - const reasonRow = new ActionRowBuilder().addComponents(reasonIn); - modal.addComponents(reasonRow); await interaction.showModal(modal); diff --git a/backend/src/plugins/ContextMenus/actions/warn.ts b/backend/src/plugins/ContextMenus/actions/warn.ts index bbfa66c5..c6a0c8ca 100644 --- a/backend/src/plugins/ContextMenus/actions/warn.ts +++ b/backend/src/plugins/ContextMenus/actions/warn.ts @@ -34,7 +34,7 @@ async function warnAction( const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interaction.editReply({ content: "Cannot mute: insufficient permissions", embeds: [], components: [] }); + await interaction.editReply({ content: "Cannot warn: insufficient permissions", embeds: [], components: [] }); return; } @@ -44,7 +44,7 @@ async function warnAction( const result = await modactions.warnMember(targetMember, reason, { caseArgs }); if (result.status === "failed") { - await interaction.editReply({ content: "Failed to warn user", embeds: [], components: [] }); + await interaction.editReply({ content: "Error: Failed to warn user", embeds: [], components: [] }); return; } @@ -61,11 +61,8 @@ export async function launchWarnActionModal( target: string, ) { const modal = new ModalBuilder().setCustomId("warn").setTitle("Warn"); - const reasonIn = new TextInputBuilder().setCustomId("reason").setLabel("Reason").setStyle(TextInputStyle.Paragraph); - const reasonRow = new ActionRowBuilder().addComponents(reasonIn); - modal.addComponents(reasonRow); await interaction.showModal(modal); diff --git a/backend/src/plugins/ContextMenus/commands/ModMenuCmd.ts b/backend/src/plugins/ContextMenus/commands/ModMenuCmd.ts index faf9bd2f..1150893c 100644 --- a/backend/src/plugins/ContextMenus/commands/ModMenuCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/ModMenuCmd.ts @@ -84,33 +84,24 @@ export const ModMenuCmd = guildPluginUserContextMenuCommand({ lines.length == 0 ? `${userName}` : `Most recent cases for ${userName} | ${firstCaseNum}-${lastCaseNum} of ${totalCases}`; - const embedFields = - lines.length == 0 - ? [ - { - name: `**No cases found**`, - value: "", - }, - ] - : [ - ...getChunkedEmbedFields( - emptyEmbedValue, - lines.length == 0 ? `No cases found for **${userName}**` : lines.join("\n"), - ), - { - name: emptyEmbedValue, - value: trimLines(` - Use \`${prefix}case \` to see more information about an individual case - `), - }, - ]; const embed = { author: { name: title, icon_url: user instanceof User ? user.displayAvatarURL() : undefined, }, - fields: embedFields, + fields: [ + ...getChunkedEmbedFields( + emptyEmbedValue, + lines.length == 0 ? `No cases found for **${userName}**` : lines.join("\n"), + ), + { + name: emptyEmbedValue, + value: trimLines( + lines.length == 0 ? "" : `Use \`${prefix}case \` to see more information about an individual case`, + ), + }, + ], footer: { text: `Page ${page}/${totalPages}` }, } satisfies APIEmbed; diff --git a/backend/src/plugins/ContextMenus/types.ts b/backend/src/plugins/ContextMenus/types.ts index b4340b1b..d099d843 100644 --- a/backend/src/plugins/ContextMenus/types.ts +++ b/backend/src/plugins/ContextMenus/types.ts @@ -2,27 +2,18 @@ import { APIEmbed, Awaitable } from "discord.js"; import * as t from "io-ts"; import { BasePluginType } from "knub"; import { GuildCases } from "../../data/GuildCases"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildMutes } from "../../data/GuildMutes"; -import { GuildTempbans } from "../../data/GuildTempbans"; -import { tNullable } from "../../utils"; export const ConfigSchema = t.type({ can_use: t.boolean, can_open_mod_menu: t.boolean, - - log_channel: tNullable(t.string), }); export type TConfigSchema = t.TypeOf; export interface ContextMenuPluginType extends BasePluginType { config: TConfigSchema; state: { - mutes: GuildMutes; cases: GuildCases; - tempbans: GuildTempbans; - serverLogs: GuildLogs; }; } From 454bec6c9f0ade8e6512382d6fc44f0f3e1f8bd2 Mon Sep 17 00:00:00 2001 From: Obliie Date: Sat, 15 Jul 2023 22:51:41 +0100 Subject: [PATCH 03/30] feat: Add user context menu commands for notes, warns, mutes and bans --- .../plugins/ContextMenus/ContextMenuPlugin.ts | 8 +++- .../src/plugins/ContextMenus/actions/ban.ts | 25 ++++++++----- .../src/plugins/ContextMenus/actions/clean.ts | 2 +- .../src/plugins/ContextMenus/actions/mute.ts | 37 ++++++++++++++----- .../src/plugins/ContextMenus/actions/note.ts | 31 ++++++++++++---- .../src/plugins/ContextMenus/actions/warn.ts | 33 ++++++++++++----- .../ContextMenus/commands/BanUserCtxCmd.ts | 9 +++++ .../{ModMenuCmd.ts => ModMenuUserCtxCmd.ts} | 2 +- .../ContextMenus/commands/MuteUserCtxCmd.ts | 9 +++++ .../ContextMenus/commands/NoteUserCtxCmd.ts | 9 +++++ .../ContextMenus/commands/WarnUserCtxCmd.ts | 9 +++++ 11 files changed, 135 insertions(+), 39 deletions(-) create mode 100644 backend/src/plugins/ContextMenus/commands/BanUserCtxCmd.ts rename backend/src/plugins/ContextMenus/commands/{ModMenuCmd.ts => ModMenuUserCtxCmd.ts} (99%) create mode 100644 backend/src/plugins/ContextMenus/commands/MuteUserCtxCmd.ts create mode 100644 backend/src/plugins/ContextMenus/commands/NoteUserCtxCmd.ts create mode 100644 backend/src/plugins/ContextMenus/commands/WarnUserCtxCmd.ts diff --git a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts index b48cc0ea..5461409d 100644 --- a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts +++ b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts @@ -8,7 +8,11 @@ import { ModActionsPlugin } from "../ModActions/ModActionsPlugin"; import { MutesPlugin } from "../Mutes/MutesPlugin"; import { UtilityPlugin } from "../Utility/UtilityPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { ModMenuCmd } from "./commands/ModMenuCmd"; +import { BanCmd } from "./commands/BanUserCtxCmd"; +import { ModMenuCmd } from "./commands/ModMenuUserCtxCmd"; +import { MuteCmd } from "./commands/MuteUserCtxCmd"; +import { NoteCmd } from "./commands/NoteUserCtxCmd"; +import { WarnCmd } from "./commands/WarnUserCtxCmd"; import { ConfigSchema, ContextMenuPluginType } from "./types"; const defaultOptions: PluginOptions = { @@ -45,7 +49,7 @@ export const ContextMenuPlugin = zeppelinGuildPlugin()({ defaultOptions, - contextMenuCommands: [ModMenuCmd], + contextMenuCommands: [ModMenuCmd, NoteCmd, WarnCmd, MuteCmd, BanCmd], beforeLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts index bfe7bc13..bfc756d2 100644 --- a/backend/src/plugins/ContextMenus/actions/ban.ts +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -1,6 +1,7 @@ import { ActionRowBuilder, ButtonInteraction, + ContextMenuCommandInteraction, ModalBuilder, ModalSubmitInteraction, TextInputBuilder, @@ -12,7 +13,7 @@ import { canActOn } from "src/pluginUtils"; import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; import { convertDelayStringToMS, renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; -import { MODAL_TIMEOUT } from "../commands/ModMenuCmd"; +import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; import { ContextMenuPluginType } from "../types"; async function banAction( @@ -20,8 +21,10 @@ async function banAction( duration: string | undefined, reason: string | undefined, target: string, - interaction: ButtonInteraction, + interaction: ButtonInteraction | ContextMenuCommandInteraction, + submitInteraction: ModalSubmitInteraction, ) { + const interactionToReply = interaction instanceof ButtonInteraction ? interaction : submitInteraction; const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -30,13 +33,13 @@ async function banAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasBanPermission(executingMember, interaction.channelId))) { - await interaction.editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }); + await interactionToReply.editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interaction.editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }); + await interactionToReply.editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }); return; } @@ -47,7 +50,7 @@ async function banAction( const durationMs = duration ? convertDelayStringToMS(duration)! : undefined; const result = await modactions.banUserId(target, reason, { caseArgs }, durationMs); if (result.status === "failed") { - await interaction.editReply({ content: "Error: Failed to ban user", embeds: [], components: [] }); + await interactionToReply.editReply({ content: "Error: Failed to ban user", embeds: [], components: [] }); return; } @@ -57,12 +60,12 @@ async function banAction( durationMs ? `for ${humanizeDuration(durationMs)}` : "indefinitely" } (Case #${result.case.case_number})${messageResultText}`; - await interaction.editReply({ content: banMessage, embeds: [], components: [] }); + await interactionToReply.editReply({ content: banMessage, embeds: [], components: [] }); } export async function launchBanActionModal( pluginData: GuildPluginData, - interaction: ButtonInteraction, + interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { const modal = new ModalBuilder().setCustomId("ban").setTitle("Ban"); @@ -83,11 +86,15 @@ export async function launchBanActionModal( await interaction.showModal(modal); const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); if (submitted) { - await submitted.deferUpdate(); + if (interaction instanceof ButtonInteraction) { + await submitted.deferUpdate(); + } else { + await submitted.deferReply({ ephemeral: true }); + } const duration = submitted.fields.getTextInputValue("duration"); const reason = submitted.fields.getTextInputValue("reason"); - await banAction(pluginData, duration, reason, target, interaction); + await banAction(pluginData, duration, reason, target, interaction, submitted); } } diff --git a/backend/src/plugins/ContextMenus/actions/clean.ts b/backend/src/plugins/ContextMenus/actions/clean.ts index 3d005bfb..34ae2d14 100644 --- a/backend/src/plugins/ContextMenus/actions/clean.ts +++ b/backend/src/plugins/ContextMenus/actions/clean.ts @@ -8,7 +8,7 @@ import { } from "discord.js"; import { GuildPluginData } from "knub"; import { UtilityPlugin } from "../../../plugins/Utility/UtilityPlugin"; -import { MODAL_TIMEOUT } from "../commands/ModMenuCmd"; +import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; import { ContextMenuPluginType } from "../types"; export async function cleanAction( diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index 90a04575..28a988c8 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -1,6 +1,7 @@ import { ActionRowBuilder, ButtonInteraction, + ContextMenuCommandInteraction, ModalBuilder, ModalSubmitInteraction, TextInputBuilder, @@ -15,7 +16,7 @@ import { convertDelayStringToMS } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { MutesPlugin } from "../../Mutes/MutesPlugin"; -import { MODAL_TIMEOUT } from "../commands/ModMenuCmd"; +import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; import { ContextMenuPluginType } from "../types"; async function muteAction( @@ -23,8 +24,10 @@ async function muteAction( duration: string | undefined, reason: string | undefined, target: string, - interaction: ButtonInteraction, + interaction: ButtonInteraction | ContextMenuCommandInteraction, + submitInteraction: ModalSubmitInteraction, ) { + const interactionToReply = interaction instanceof ButtonInteraction ? interaction : submitInteraction; const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -33,13 +36,21 @@ async function muteAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasMutePermission(executingMember, interaction.channelId))) { - await interaction.editReply({ content: "Cannot mute: insufficient permissions", embeds: [], components: [] }); + await interactionToReply.editReply({ + content: "Cannot mute: insufficient permissions", + embeds: [], + components: [], + }); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interaction.editReply({ content: "Cannot mute: insufficient permissions", embeds: [], components: [] }); + await interactionToReply.editReply({ + content: "Cannot mute: insufficient permissions", + embeds: [], + components: [], + }); return; } @@ -57,9 +68,13 @@ async function muteAction( durationMs ? `for ${humanizeDuration(durationMs)}` : "indefinitely" } (Case #${result.case.case_number})${messageResultText}`; - await interaction.editReply({ content: muteMessage, embeds: [], components: [] }); + await interactionToReply.editReply({ content: muteMessage, embeds: [], components: [] }); } catch (e) { - await interaction.editReply({ content: "Plugin error, please check your BOT_ALERTs", embeds: [], components: [] }); + await interactionToReply.editReply({ + content: "Plugin error, please check your BOT_ALERTs", + embeds: [], + components: [], + }); if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { pluginData.getPlugin(LogsPlugin).logBotAlert({ @@ -73,7 +88,7 @@ async function muteAction( export async function launchMuteActionModal( pluginData: GuildPluginData, - interaction: ButtonInteraction, + interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { const modal = new ModalBuilder().setCustomId("mute").setTitle("Mute"); @@ -94,11 +109,15 @@ export async function launchMuteActionModal( await interaction.showModal(modal); const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); if (submitted) { - await submitted.deferUpdate(); + if (interaction instanceof ButtonInteraction) { + await submitted.deferUpdate(); + } else { + await submitted.deferReply({ ephemeral: true }); + } const duration = submitted.fields.getTextInputValue("duration"); const reason = submitted.fields.getTextInputValue("reason"); - await muteAction(pluginData, duration, reason, target, interaction); + await muteAction(pluginData, duration, reason, target, interaction, submitted); } } diff --git a/backend/src/plugins/ContextMenus/actions/note.ts b/backend/src/plugins/ContextMenus/actions/note.ts index 84b0e2bb..51a018ca 100644 --- a/backend/src/plugins/ContextMenus/actions/note.ts +++ b/backend/src/plugins/ContextMenus/actions/note.ts @@ -1,6 +1,7 @@ import { ActionRowBuilder, ButtonInteraction, + ContextMenuCommandInteraction, ModalBuilder, ModalSubmitInteraction, TextInputBuilder, @@ -13,15 +14,17 @@ import { CaseTypes } from "../../../data/CaseTypes"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { renderUserUsername } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { MODAL_TIMEOUT } from "../commands/ModMenuCmd"; +import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; import { ContextMenuPluginType } from "../types"; async function noteAction( pluginData: GuildPluginData, reason: string, target: string, - interaction: ButtonInteraction, + interaction: ButtonInteraction | ContextMenuCommandInteraction, + submitInteraction: ModalSubmitInteraction, ) { + const interactionToReply = interaction instanceof ButtonInteraction ? interaction : submitInteraction; const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -30,13 +33,21 @@ async function noteAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasNotePermission(executingMember, interaction.channelId))) { - await interaction.editReply({ content: "Cannot note: insufficient permissions", embeds: [], components: [] }); + await interactionToReply.editReply({ + content: "Cannot note: insufficient permissions", + embeds: [], + components: [], + }); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interaction.editReply({ content: "Cannot note: insufficient permissions", embeds: [], components: [] }); + await interactionToReply.editReply({ + content: "Cannot note: insufficient permissions", + embeds: [], + components: [], + }); return; } @@ -56,7 +67,7 @@ async function noteAction( }); const userName = renderUserUsername(targetMember.user); - await interaction.editReply({ + await interactionToReply.editReply({ content: `Note added on **${userName}** (Case #${createdCase.case_number})`, embeds: [], components: [], @@ -65,7 +76,7 @@ async function noteAction( export async function launchNoteActionModal( pluginData: GuildPluginData, - interaction: ButtonInteraction, + interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { const modal = new ModalBuilder().setCustomId("note").setTitle("Note"); @@ -76,10 +87,14 @@ export async function launchNoteActionModal( await interaction.showModal(modal); const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); if (submitted) { - await submitted.deferUpdate(); + if (interaction instanceof ButtonInteraction) { + await submitted.deferUpdate(); + } else { + await submitted.deferReply({ ephemeral: true }); + } const reason = submitted.fields.getTextInputValue("reason"); - await noteAction(pluginData, reason, target, interaction); + await noteAction(pluginData, reason, target, interaction, submitted); } } diff --git a/backend/src/plugins/ContextMenus/actions/warn.ts b/backend/src/plugins/ContextMenus/actions/warn.ts index c6a0c8ca..4ec0cf43 100644 --- a/backend/src/plugins/ContextMenus/actions/warn.ts +++ b/backend/src/plugins/ContextMenus/actions/warn.ts @@ -1,6 +1,7 @@ import { ActionRowBuilder, ButtonInteraction, + ContextMenuCommandInteraction, ModalBuilder, ModalSubmitInteraction, TextInputBuilder, @@ -11,15 +12,17 @@ import { canActOn } from "src/pluginUtils"; import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; import { renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; -import { MODAL_TIMEOUT } from "../commands/ModMenuCmd"; +import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; import { ContextMenuPluginType } from "../types"; async function warnAction( pluginData: GuildPluginData, reason: string, target: string, - interaction: ButtonInteraction, + interaction: ButtonInteraction | ContextMenuCommandInteraction, + submitInteraction: ModalSubmitInteraction, ) { + const interactionToReply = interaction instanceof ButtonInteraction ? interaction : submitInteraction; const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -28,13 +31,21 @@ async function warnAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasWarnPermission(executingMember, interaction.channelId))) { - await interaction.editReply({ content: "Cannot warn: insufficient permissions", embeds: [], components: [] }); + await interactionToReply.editReply({ + content: "Cannot warn: insufficient permissions", + embeds: [], + components: [], + }); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interaction.editReply({ content: "Cannot warn: insufficient permissions", embeds: [], components: [] }); + await interactionToReply.editReply({ + content: "Cannot warn: insufficient permissions", + embeds: [], + components: [], + }); return; } @@ -44,7 +55,7 @@ async function warnAction( const result = await modactions.warnMember(targetMember, reason, { caseArgs }); if (result.status === "failed") { - await interaction.editReply({ content: "Error: Failed to warn user", embeds: [], components: [] }); + await interactionToReply.editReply({ content: "Error: Failed to warn user", embeds: [], components: [] }); return; } @@ -52,12 +63,12 @@ async function warnAction( const messageResultText = result.notifyResult.text ? ` (${result.notifyResult.text})` : ""; const muteMessage = `Warned **${userName}** (Case #${result.case.case_number})${messageResultText}`; - await interaction.editReply({ content: muteMessage, embeds: [], components: [] }); + await interactionToReply.editReply({ content: muteMessage, embeds: [], components: [] }); } export async function launchWarnActionModal( pluginData: GuildPluginData, - interaction: ButtonInteraction, + interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { const modal = new ModalBuilder().setCustomId("warn").setTitle("Warn"); @@ -68,10 +79,14 @@ export async function launchWarnActionModal( await interaction.showModal(modal); const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); if (submitted) { - await submitted.deferUpdate(); + if (interaction instanceof ButtonInteraction) { + await submitted.deferUpdate(); + } else { + await submitted.deferReply({ ephemeral: true }); + } const reason = submitted.fields.getTextInputValue("reason"); - await warnAction(pluginData, reason, target, interaction); + await warnAction(pluginData, reason, target, interaction, submitted); } } diff --git a/backend/src/plugins/ContextMenus/commands/BanUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/BanUserCtxCmd.ts new file mode 100644 index 00000000..237d81cb --- /dev/null +++ b/backend/src/plugins/ContextMenus/commands/BanUserCtxCmd.ts @@ -0,0 +1,9 @@ +import { guildPluginUserContextMenuCommand } from "knub"; +import { launchBanActionModal } from "../actions/ban"; + +export const BanCmd = guildPluginUserContextMenuCommand({ + name: "Ban", + async run({ pluginData, interaction }) { + await launchBanActionModal(pluginData, interaction, interaction.targetId); + }, +}); diff --git a/backend/src/plugins/ContextMenus/commands/ModMenuCmd.ts b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts similarity index 99% rename from backend/src/plugins/ContextMenus/commands/ModMenuCmd.ts rename to backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts index 1150893c..e8a51556 100644 --- a/backend/src/plugins/ContextMenus/commands/ModMenuCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts @@ -9,13 +9,13 @@ import { } from "discord.js"; import { GuildPluginData, guildPluginUserContextMenuCommand } from "knub"; import { Case } from "../../../data/entities/Case"; -import { getUserInfoEmbed } from "../../../plugins/Utility/functions/getUserInfoEmbed"; import { SECONDS, UnknownUser, emptyEmbedValue, renderUserUsername, resolveUser, trimLines } from "../../../utils"; import { asyncMap } from "../../../utils/async"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { UtilityPlugin } from "../../Utility/UtilityPlugin"; +import { getUserInfoEmbed } from "../../Utility/functions/getUserInfoEmbed"; import { launchBanActionModal } from "../actions/ban"; import { launchCleanActionModal } from "../actions/clean"; import { launchMuteActionModal } from "../actions/mute"; diff --git a/backend/src/plugins/ContextMenus/commands/MuteUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/MuteUserCtxCmd.ts new file mode 100644 index 00000000..3c060cb3 --- /dev/null +++ b/backend/src/plugins/ContextMenus/commands/MuteUserCtxCmd.ts @@ -0,0 +1,9 @@ +import { guildPluginUserContextMenuCommand } from "knub"; +import { launchMuteActionModal } from "../actions/mute"; + +export const MuteCmd = guildPluginUserContextMenuCommand({ + name: "Mute", + async run({ pluginData, interaction }) { + await launchMuteActionModal(pluginData, interaction, interaction.targetId); + }, +}); diff --git a/backend/src/plugins/ContextMenus/commands/NoteUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/NoteUserCtxCmd.ts new file mode 100644 index 00000000..c4f0fa9d --- /dev/null +++ b/backend/src/plugins/ContextMenus/commands/NoteUserCtxCmd.ts @@ -0,0 +1,9 @@ +import { guildPluginUserContextMenuCommand } from "knub"; +import { launchNoteActionModal } from "../actions/note"; + +export const NoteCmd = guildPluginUserContextMenuCommand({ + name: "Note", + async run({ pluginData, interaction }) { + await launchNoteActionModal(pluginData, interaction, interaction.targetId); + }, +}); diff --git a/backend/src/plugins/ContextMenus/commands/WarnUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/WarnUserCtxCmd.ts new file mode 100644 index 00000000..3f62196c --- /dev/null +++ b/backend/src/plugins/ContextMenus/commands/WarnUserCtxCmd.ts @@ -0,0 +1,9 @@ +import { guildPluginUserContextMenuCommand } from "knub"; +import { launchWarnActionModal } from "../actions/warn"; + +export const WarnCmd = guildPluginUserContextMenuCommand({ + name: "Warn", + async run({ pluginData, interaction }) { + await launchWarnActionModal(pluginData, interaction, interaction.targetId); + }, +}); From 7f2f2c8f98ddbd34b142b16e64b7971caf0934e2 Mon Sep 17 00:00:00 2001 From: Obliie Date: Sun, 16 Jul 2023 00:12:13 +0100 Subject: [PATCH 04/30] fix: modal id conflicts causing collectors to respond to unrelated submissions --- .../src/plugins/ContextMenus/actions/ban.ts | 32 +++++++++------- .../src/plugins/ContextMenus/actions/clean.ts | 37 +++++++++---------- .../src/plugins/ContextMenus/actions/mute.ts | 32 +++++++++------- .../src/plugins/ContextMenus/actions/note.ts | 30 ++++++++------- .../src/plugins/ContextMenus/actions/warn.ts | 30 ++++++++------- 5 files changed, 87 insertions(+), 74 deletions(-) diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts index bfc756d2..5227c793 100644 --- a/backend/src/plugins/ContextMenus/actions/ban.ts +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -11,10 +11,11 @@ import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { canActOn } from "src/pluginUtils"; import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { logger } from "../../../logger"; import { convertDelayStringToMS, renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType } from "../types"; +import { ContextMenuPluginType, ModMenuActionType } from "../types"; async function banAction( pluginData: GuildPluginData, @@ -24,7 +25,7 @@ async function banAction( interaction: ButtonInteraction | ContextMenuCommandInteraction, submitInteraction: ModalSubmitInteraction, ) { - const interactionToReply = interaction instanceof ButtonInteraction ? interaction : submitInteraction; + const interactionToReply = interaction.isButton() ? interaction : submitInteraction; const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -68,7 +69,8 @@ export async function launchBanActionModal( interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { - const modal = new ModalBuilder().setCustomId("ban").setTitle("Ban"); + const modalId = `${ModMenuActionType.WARN}:${interaction.id}`; + const modal = new ModalBuilder().setCustomId(modalId).setTitle("Ban"); const durationIn = new TextInputBuilder() .setCustomId("duration") .setLabel("Duration (Optional)") @@ -84,17 +86,19 @@ export async function launchBanActionModal( modal.addComponents(durationRow, reasonRow); await interaction.showModal(modal); - const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); - if (submitted) { - if (interaction instanceof ButtonInteraction) { - await submitted.deferUpdate(); - } else { - await submitted.deferReply({ ephemeral: true }); - } + await interaction + .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) + .then(async (submitted) => { + if (interaction.isButton()) { + await submitted.deferUpdate(); + } else if (interaction.isContextMenuCommand()) { + await submitted.deferReply({ ephemeral: true }); + } - const duration = submitted.fields.getTextInputValue("duration"); - const reason = submitted.fields.getTextInputValue("reason"); + const duration = submitted.fields.getTextInputValue("duration"); + const reason = submitted.fields.getTextInputValue("reason"); - await banAction(pluginData, duration, reason, target, interaction, submitted); - } + await banAction(pluginData, duration, reason, target, interaction, submitted); + }) + .catch((err) => logger.error(`Ban modal interaction failed: ${err}`)); } diff --git a/backend/src/plugins/ContextMenus/actions/clean.ts b/backend/src/plugins/ContextMenus/actions/clean.ts index 34ae2d14..13795f04 100644 --- a/backend/src/plugins/ContextMenus/actions/clean.ts +++ b/backend/src/plugins/ContextMenus/actions/clean.ts @@ -1,15 +1,9 @@ -import { - ActionRowBuilder, - ButtonInteraction, - ModalBuilder, - ModalSubmitInteraction, - TextInputBuilder, - TextInputStyle, -} from "discord.js"; +import { ActionRowBuilder, ButtonInteraction, ModalBuilder, TextInputBuilder, TextInputStyle } from "discord.js"; import { GuildPluginData } from "knub"; +import { logger } from "../../../logger"; import { UtilityPlugin } from "../../../plugins/Utility/UtilityPlugin"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType } from "../types"; +import { ContextMenuPluginType, ModMenuActionType } from "../types"; export async function cleanAction( pluginData: GuildPluginData, @@ -42,22 +36,25 @@ export async function launchCleanActionModal( interaction: ButtonInteraction, target: string, ) { - const modal = new ModalBuilder().setCustomId("clean").setTitle("Clean"); + const modalId = `${ModMenuActionType.CLEAN}:${interaction.id}`; + const modal = new ModalBuilder().setCustomId(modalId).setTitle("Clean"); const amountIn = new TextInputBuilder().setCustomId("amount").setLabel("Amount").setStyle(TextInputStyle.Short); const amountRow = new ActionRowBuilder().addComponents(amountIn); modal.addComponents(amountRow); await interaction.showModal(modal); - const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); - if (submitted) { - await submitted.deferUpdate(); + await interaction + .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) + .then(async (submitted) => { + await submitted.deferUpdate(); - const amount = submitted.fields.getTextInputValue("amount"); - if (isNaN(Number(amount))) { - interaction.editReply({ content: `Error: Amount '${amount}' is invalid`, embeds: [], components: [] }); - return; - } + const amount = submitted.fields.getTextInputValue("amount"); + if (isNaN(Number(amount))) { + interaction.editReply({ content: `Error: Amount '${amount}' is invalid`, embeds: [], components: [] }); + return; + } - await cleanAction(pluginData, Number(amount), target, interaction); - } + await cleanAction(pluginData, Number(amount), target, interaction); + }) + .catch((err) => logger.error(`Clean modal interaction failed: ${err}`)); } diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index 28a988c8..ad98d544 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -12,12 +12,13 @@ import { GuildPluginData } from "knub"; import { canActOn } from "src/pluginUtils"; import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { logger } from "../../../logger"; import { convertDelayStringToMS } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { MutesPlugin } from "../../Mutes/MutesPlugin"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType } from "../types"; +import { ContextMenuPluginType, ModMenuActionType } from "../types"; async function muteAction( pluginData: GuildPluginData, @@ -27,7 +28,7 @@ async function muteAction( interaction: ButtonInteraction | ContextMenuCommandInteraction, submitInteraction: ModalSubmitInteraction, ) { - const interactionToReply = interaction instanceof ButtonInteraction ? interaction : submitInteraction; + const interactionToReply = interaction.isButton() ? interaction : submitInteraction; const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -91,7 +92,8 @@ export async function launchMuteActionModal( interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { - const modal = new ModalBuilder().setCustomId("mute").setTitle("Mute"); + const modalId = `${ModMenuActionType.MUTE}:${interaction.id}`; + const modal = new ModalBuilder().setCustomId(modalId).setTitle("Mute"); const durationIn = new TextInputBuilder() .setCustomId("duration") .setLabel("Duration (Optional)") @@ -107,17 +109,19 @@ export async function launchMuteActionModal( modal.addComponents(durationRow, reasonRow); await interaction.showModal(modal); - const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); - if (submitted) { - if (interaction instanceof ButtonInteraction) { - await submitted.deferUpdate(); - } else { - await submitted.deferReply({ ephemeral: true }); - } + await interaction + .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) + .then(async (submitted) => { + if (interaction.isButton()) { + await submitted.deferUpdate(); + } else if (interaction.isContextMenuCommand()) { + await submitted.deferReply({ ephemeral: true }); + } - const duration = submitted.fields.getTextInputValue("duration"); - const reason = submitted.fields.getTextInputValue("reason"); + const duration = submitted.fields.getTextInputValue("duration"); + const reason = submitted.fields.getTextInputValue("reason"); - await muteAction(pluginData, duration, reason, target, interaction, submitted); - } + await muteAction(pluginData, duration, reason, target, interaction, submitted); + }) + .catch((err) => logger.error(`Mute modal interaction failed: ${err}`)); } diff --git a/backend/src/plugins/ContextMenus/actions/note.ts b/backend/src/plugins/ContextMenus/actions/note.ts index 51a018ca..ecc48d6e 100644 --- a/backend/src/plugins/ContextMenus/actions/note.ts +++ b/backend/src/plugins/ContextMenus/actions/note.ts @@ -11,11 +11,12 @@ import { GuildPluginData } from "knub"; import { canActOn } from "src/pluginUtils"; import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; +import { logger } from "../../../logger"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { renderUserUsername } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType } from "../types"; +import { ContextMenuPluginType, ModMenuActionType } from "../types"; async function noteAction( pluginData: GuildPluginData, @@ -24,7 +25,7 @@ async function noteAction( interaction: ButtonInteraction | ContextMenuCommandInteraction, submitInteraction: ModalSubmitInteraction, ) { - const interactionToReply = interaction instanceof ButtonInteraction ? interaction : submitInteraction; + const interactionToReply = interaction.isButton() ? interaction : submitInteraction; const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -79,22 +80,25 @@ export async function launchNoteActionModal( interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { - const modal = new ModalBuilder().setCustomId("note").setTitle("Note"); + const modalId = `${ModMenuActionType.NOTE}:${interaction.id}`; + const modal = new ModalBuilder().setCustomId(modalId).setTitle("Note"); const reasonIn = new TextInputBuilder().setCustomId("reason").setLabel("Note").setStyle(TextInputStyle.Paragraph); const reasonRow = new ActionRowBuilder().addComponents(reasonIn); modal.addComponents(reasonRow); await interaction.showModal(modal); - const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); - if (submitted) { - if (interaction instanceof ButtonInteraction) { - await submitted.deferUpdate(); - } else { - await submitted.deferReply({ ephemeral: true }); - } + await interaction + .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) + .then(async (submitted) => { + if (interaction.isButton()) { + await submitted.deferUpdate(); + } else if (interaction.isContextMenuCommand()) { + await submitted.deferReply({ ephemeral: true }); + } - const reason = submitted.fields.getTextInputValue("reason"); + const reason = submitted.fields.getTextInputValue("reason"); - await noteAction(pluginData, reason, target, interaction, submitted); - } + await noteAction(pluginData, reason, target, interaction, submitted); + }) + .catch((err) => logger.error(`Note modal interaction failed: ${err}`)); } diff --git a/backend/src/plugins/ContextMenus/actions/warn.ts b/backend/src/plugins/ContextMenus/actions/warn.ts index 4ec0cf43..9afbf44e 100644 --- a/backend/src/plugins/ContextMenus/actions/warn.ts +++ b/backend/src/plugins/ContextMenus/actions/warn.ts @@ -10,10 +10,11 @@ import { import { GuildPluginData } from "knub"; import { canActOn } from "src/pluginUtils"; import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { logger } from "../../../logger"; import { renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType } from "../types"; +import { ContextMenuPluginType, ModMenuActionType } from "../types"; async function warnAction( pluginData: GuildPluginData, @@ -22,7 +23,7 @@ async function warnAction( interaction: ButtonInteraction | ContextMenuCommandInteraction, submitInteraction: ModalSubmitInteraction, ) { - const interactionToReply = interaction instanceof ButtonInteraction ? interaction : submitInteraction; + const interactionToReply = interaction.isButton() ? interaction : submitInteraction; const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ channelId: interaction.channelId, @@ -71,22 +72,25 @@ export async function launchWarnActionModal( interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { - const modal = new ModalBuilder().setCustomId("warn").setTitle("Warn"); + const modalId = `${ModMenuActionType.WARN}:${interaction.id}`; + const modal = new ModalBuilder().setCustomId(modalId).setTitle("Warn"); const reasonIn = new TextInputBuilder().setCustomId("reason").setLabel("Reason").setStyle(TextInputStyle.Paragraph); const reasonRow = new ActionRowBuilder().addComponents(reasonIn); modal.addComponents(reasonRow); await interaction.showModal(modal); - const submitted: ModalSubmitInteraction = await interaction.awaitModalSubmit({ time: MODAL_TIMEOUT }); - if (submitted) { - if (interaction instanceof ButtonInteraction) { - await submitted.deferUpdate(); - } else { - await submitted.deferReply({ ephemeral: true }); - } + await interaction + .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) + .then(async (submitted) => { + if (interaction.isButton()) { + await submitted.deferUpdate(); + } else if (interaction.isContextMenuCommand()) { + await submitted.deferReply({ ephemeral: true }); + } - const reason = submitted.fields.getTextInputValue("reason"); + const reason = submitted.fields.getTextInputValue("reason"); - await warnAction(pluginData, reason, target, interaction, submitted); - } + await warnAction(pluginData, reason, target, interaction, submitted); + }) + .catch((err) => logger.error(`Mute modal interaction failed: ${err}`)); } From 8fcbd50ea1517c9fe912cbf8d17d5454372b247a Mon Sep 17 00:00:00 2001 From: Obliie Date: Sun, 16 Jul 2023 00:38:35 +0100 Subject: [PATCH 05/30] fix: interaction error handling --- .../src/plugins/ContextMenus/actions/ban.ts | 22 +- .../src/plugins/ContextMenus/actions/clean.ts | 22 +- .../src/plugins/ContextMenus/actions/mute.ts | 46 ++-- .../src/plugins/ContextMenus/actions/note.ts | 42 ++-- .../src/plugins/ContextMenus/actions/warn.ts | 40 ++-- .../commands/ModMenuUserCtxCmd.ts | 200 ++++++++++-------- 6 files changed, 217 insertions(+), 155 deletions(-) diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts index 5227c793..0a61c57f 100644 --- a/backend/src/plugins/ContextMenus/actions/ban.ts +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -34,13 +34,17 @@ async function banAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasBanPermission(executingMember, interaction.channelId))) { - await interactionToReply.editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }); + await interactionToReply + .editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }) + .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interactionToReply.editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }); + await interactionToReply + .editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }) + .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); return; } @@ -51,7 +55,9 @@ async function banAction( const durationMs = duration ? convertDelayStringToMS(duration)! : undefined; const result = await modactions.banUserId(target, reason, { caseArgs }, durationMs); if (result.status === "failed") { - await interactionToReply.editReply({ content: "Error: Failed to ban user", embeds: [], components: [] }); + await interactionToReply + .editReply({ content: "Error: Failed to ban user", embeds: [], components: [] }) + .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); return; } @@ -61,7 +67,9 @@ async function banAction( durationMs ? `for ${humanizeDuration(durationMs)}` : "indefinitely" } (Case #${result.case.case_number})${messageResultText}`; - await interactionToReply.editReply({ content: banMessage, embeds: [], components: [] }); + await interactionToReply + .editReply({ content: banMessage, embeds: [], components: [] }) + .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); } export async function launchBanActionModal( @@ -90,9 +98,11 @@ export async function launchBanActionModal( .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) .then(async (submitted) => { if (interaction.isButton()) { - await submitted.deferUpdate(); + await submitted.deferUpdate().catch((err) => logger.error(`Ban interaction defer failed: ${err}`)); } else if (interaction.isContextMenuCommand()) { - await submitted.deferReply({ ephemeral: true }); + await submitted + .deferReply({ ephemeral: true }) + .catch((err) => logger.error(`Ban interaction defer failed: ${err}`)); } const duration = submitted.fields.getTextInputValue("duration"); diff --git a/backend/src/plugins/ContextMenus/actions/clean.ts b/backend/src/plugins/ContextMenus/actions/clean.ts index 13795f04..628451c6 100644 --- a/backend/src/plugins/ContextMenus/actions/clean.ts +++ b/backend/src/plugins/ContextMenus/actions/clean.ts @@ -19,16 +19,20 @@ export async function cleanAction( const utility = pluginData.getPlugin(UtilityPlugin); if (!userCfg.can_use || !(await utility.hasPermission(executingMember, interaction.channelId, "can_clean"))) { - await interaction.editReply({ content: "Cannot clean: insufficient permissions", embeds: [], components: [] }); + await interaction + .editReply({ content: "Cannot clean: insufficient permissions", embeds: [], components: [] }) + .catch((err) => logger.error(`Clean interaction reply failed: ${err}`)); return; } // TODO: Implement message cleaning - await interaction.editReply({ - content: `TODO: Implementation incomplete`, - embeds: [], - components: [], - }); + await interaction + .editReply({ + content: `TODO: Implementation incomplete`, + embeds: [], + components: [], + }) + .catch((err) => logger.error(`Clean interaction reply failed: ${err}`)); } export async function launchCleanActionModal( @@ -46,11 +50,13 @@ export async function launchCleanActionModal( await interaction .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) .then(async (submitted) => { - await submitted.deferUpdate(); + await submitted.deferUpdate().catch((err) => logger.error(`Clean interaction defer failed: ${err}`)); const amount = submitted.fields.getTextInputValue("amount"); if (isNaN(Number(amount))) { - interaction.editReply({ content: `Error: Amount '${amount}' is invalid`, embeds: [], components: [] }); + interaction + .editReply({ content: `Error: Amount '${amount}' is invalid`, embeds: [], components: [] }) + .catch((err) => logger.error(`Clean interaction reply failed: ${err}`)); return; } diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index ad98d544..b0ea8776 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -37,21 +37,25 @@ async function muteAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasMutePermission(executingMember, interaction.channelId))) { - await interactionToReply.editReply({ - content: "Cannot mute: insufficient permissions", - embeds: [], - components: [], - }); + await interactionToReply + .editReply({ + content: "Cannot mute: insufficient permissions", + embeds: [], + components: [], + }) + .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interactionToReply.editReply({ - content: "Cannot mute: insufficient permissions", - embeds: [], - components: [], - }); + await interactionToReply + .editReply({ + content: "Cannot mute: insufficient permissions", + embeds: [], + components: [], + }) + .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); return; } @@ -69,13 +73,17 @@ async function muteAction( durationMs ? `for ${humanizeDuration(durationMs)}` : "indefinitely" } (Case #${result.case.case_number})${messageResultText}`; - await interactionToReply.editReply({ content: muteMessage, embeds: [], components: [] }); + await interactionToReply + .editReply({ content: muteMessage, embeds: [], components: [] }) + .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); } catch (e) { - await interactionToReply.editReply({ - content: "Plugin error, please check your BOT_ALERTs", - embeds: [], - components: [], - }); + await interactionToReply + .editReply({ + content: "Plugin error, please check your BOT_ALERTs", + embeds: [], + components: [], + }) + .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { pluginData.getPlugin(LogsPlugin).logBotAlert({ @@ -113,9 +121,11 @@ export async function launchMuteActionModal( .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) .then(async (submitted) => { if (interaction.isButton()) { - await submitted.deferUpdate(); + await submitted.deferUpdate().catch((err) => logger.error(`Mute interaction defer failed: ${err}`)); } else if (interaction.isContextMenuCommand()) { - await submitted.deferReply({ ephemeral: true }); + await submitted + .deferReply({ ephemeral: true }) + .catch((err) => logger.error(`Mute interaction defer failed: ${err}`)); } const duration = submitted.fields.getTextInputValue("duration"); diff --git a/backend/src/plugins/ContextMenus/actions/note.ts b/backend/src/plugins/ContextMenus/actions/note.ts index ecc48d6e..b6911274 100644 --- a/backend/src/plugins/ContextMenus/actions/note.ts +++ b/backend/src/plugins/ContextMenus/actions/note.ts @@ -34,21 +34,25 @@ async function noteAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasNotePermission(executingMember, interaction.channelId))) { - await interactionToReply.editReply({ - content: "Cannot note: insufficient permissions", - embeds: [], - components: [], - }); + await interactionToReply + .editReply({ + content: "Cannot note: insufficient permissions", + embeds: [], + components: [], + }) + .catch((err) => logger.error(`Note interaction reply failed: ${err}`)); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interactionToReply.editReply({ - content: "Cannot note: insufficient permissions", - embeds: [], - components: [], - }); + await interactionToReply + .editReply({ + content: "Cannot note: insufficient permissions", + embeds: [], + components: [], + }) + .catch((err) => logger.error(`Note interaction reply failed: ${err}`)); return; } @@ -68,11 +72,13 @@ async function noteAction( }); const userName = renderUserUsername(targetMember.user); - await interactionToReply.editReply({ - content: `Note added on **${userName}** (Case #${createdCase.case_number})`, - embeds: [], - components: [], - }); + await interactionToReply + .editReply({ + content: `Note added on **${userName}** (Case #${createdCase.case_number})`, + embeds: [], + components: [], + }) + .catch((err) => logger.error(`Note interaction reply failed: ${err}`)); } export async function launchNoteActionModal( @@ -91,9 +97,11 @@ export async function launchNoteActionModal( .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) .then(async (submitted) => { if (interaction.isButton()) { - await submitted.deferUpdate(); + await submitted.deferUpdate().catch((err) => logger.error(`Note interaction defer failed: ${err}`)); } else if (interaction.isContextMenuCommand()) { - await submitted.deferReply({ ephemeral: true }); + await submitted + .deferReply({ ephemeral: true }) + .catch((err) => logger.error(`Note interaction defer failed: ${err}`)); } const reason = submitted.fields.getTextInputValue("reason"); diff --git a/backend/src/plugins/ContextMenus/actions/warn.ts b/backend/src/plugins/ContextMenus/actions/warn.ts index 9afbf44e..d8eba234 100644 --- a/backend/src/plugins/ContextMenus/actions/warn.ts +++ b/backend/src/plugins/ContextMenus/actions/warn.ts @@ -32,21 +32,25 @@ async function warnAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasWarnPermission(executingMember, interaction.channelId))) { - await interactionToReply.editReply({ - content: "Cannot warn: insufficient permissions", - embeds: [], - components: [], - }); + await interactionToReply + .editReply({ + content: "Cannot warn: insufficient permissions", + embeds: [], + components: [], + }) + .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interactionToReply.editReply({ - content: "Cannot warn: insufficient permissions", - embeds: [], - components: [], - }); + await interactionToReply + .editReply({ + content: "Cannot warn: insufficient permissions", + embeds: [], + components: [], + }) + .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); return; } @@ -56,7 +60,9 @@ async function warnAction( const result = await modactions.warnMember(targetMember, reason, { caseArgs }); if (result.status === "failed") { - await interactionToReply.editReply({ content: "Error: Failed to warn user", embeds: [], components: [] }); + await interactionToReply + .editReply({ content: "Error: Failed to warn user", embeds: [], components: [] }) + .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); return; } @@ -64,7 +70,9 @@ async function warnAction( const messageResultText = result.notifyResult.text ? ` (${result.notifyResult.text})` : ""; const muteMessage = `Warned **${userName}** (Case #${result.case.case_number})${messageResultText}`; - await interactionToReply.editReply({ content: muteMessage, embeds: [], components: [] }); + await interactionToReply + .editReply({ content: muteMessage, embeds: [], components: [] }) + .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); } export async function launchWarnActionModal( @@ -83,14 +91,16 @@ export async function launchWarnActionModal( .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) .then(async (submitted) => { if (interaction.isButton()) { - await submitted.deferUpdate(); + await submitted.deferUpdate().catch((err) => logger.error(`Warn interaction defer failed: ${err}`)); } else if (interaction.isContextMenuCommand()) { - await submitted.deferReply({ ephemeral: true }); + await submitted + .deferReply({ ephemeral: true }) + .catch((err) => logger.error(`Warn interaction defer failed: ${err}`)); } const reason = submitted.fields.getTextInputValue("reason"); await warnAction(pluginData, reason, target, interaction, submitted); }) - .catch((err) => logger.error(`Mute modal interaction failed: ${err}`)); + .catch((err) => logger.error(`Warn modal interaction failed: ${err}`)); } diff --git a/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts index e8a51556..da8a9014 100644 --- a/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts @@ -9,6 +9,7 @@ import { } from "discord.js"; import { GuildPluginData, guildPluginUserContextMenuCommand } from "knub"; import { Case } from "../../../data/entities/Case"; +import { logger } from "../../../logger"; import { SECONDS, UnknownUser, emptyEmbedValue, renderUserUsername, resolveUser, trimLines } from "../../../utils"; import { asyncMap } from "../../../utils/async"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; @@ -36,7 +37,9 @@ const CASES_PER_PAGE = 10; export const ModMenuCmd = guildPluginUserContextMenuCommand({ name: "Mod Menu", async run({ pluginData, interaction }) { - await interaction.deferReply({ ephemeral: true }); + await interaction + .deferReply({ ephemeral: true }) + .catch((err) => logger.error(`Mod menu interaction defer failed: ${err}`)); // Run permission checks for executing user. const executingMember = await pluginData.guild.members.fetch(interaction.user.id); @@ -49,13 +52,17 @@ export const ModMenuCmd = guildPluginUserContextMenuCommand({ !userCfg.can_use || (await !utility.hasPermission(executingMember, interaction.channelId, "can_open_mod_menu")) ) { - await interaction.followUp({ content: "Error: Insufficient Permissions" }); + await interaction + .followUp({ content: "Error: Insufficient Permissions" }) + .catch((err) => logger.error(`Mod menu interaction follow up failed: ${err}`)); return; } const user = await resolveUser(pluginData.client, interaction.targetId); if (!user.id) { - await interaction.followUp("Error: User not found"); + await interaction + .followUp("Error: User not found") + .catch((err) => logger.error(`Mod menu interaction follow up failed: ${err}`)); return; } @@ -120,7 +127,7 @@ async function displayModMenu( infoEmbed: APIEmbed | null, ) { if (interaction.deferred == false) { - await interaction.deferReply(); + await interaction.deferReply().catch((err) => logger.error(`Mod menu interaction defer failed: ${err}`)); } const firstButton = new ButtonBuilder() @@ -177,98 +184,109 @@ async function displayModMenu( const moderationRow = new ActionRowBuilder().addComponents(moderationButtons); let page = 1; - const currentPage = await interaction.editReply({ - embeds: [await loadPage(page)], - components: [navigationRow, moderationRow], - }); - - const collector = await currentPage.createMessageComponentCollector({ - time: MOD_MENU_TIMEOUT, - }); - - collector.on("collect", async (i) => { - const opts = deserializeCustomId(i.customId); - if (opts.action == ModMenuActionType.PAGE) { - await i.deferUpdate(); - } - - // Update displayed embed if any navigation buttons were used - if (opts.action == ModMenuActionType.PAGE && opts.target == ModMenuNavigationType.INFO && infoEmbed != null) { - infoButton - .setLabel("Cases") - .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.CASES })); - firstButton.setDisabled(true); - prevButton.setDisabled(true); - nextButton.setDisabled(true); - lastButton.setDisabled(true); - - await i.editReply({ - embeds: [infoEmbed], - components: [navigationRow, moderationRow], + await interaction + .editReply({ + embeds: [await loadPage(page)], + components: [navigationRow, moderationRow], + }) + .then(async (currentPage) => { + const collector = await currentPage.createMessageComponentCollector({ + time: MOD_MENU_TIMEOUT, }); - } else if (opts.action == ModMenuActionType.PAGE && opts.target == ModMenuNavigationType.CASES) { - infoButton - .setLabel("Info") - .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.INFO })); - updateNavButtonState(firstButton, prevButton, nextButton, lastButton, page, totalPages); - await i.editReply({ - embeds: [await loadPage(page)], - components: [navigationRow, moderationRow], + collector.on("collect", async (i) => { + const opts = deserializeCustomId(i.customId); + if (opts.action == ModMenuActionType.PAGE) { + await i.deferUpdate().catch((err) => logger.error(`Mod menu defer failed: ${err}`)); + } + + // Update displayed embed if any navigation buttons were used + if (opts.action == ModMenuActionType.PAGE && opts.target == ModMenuNavigationType.INFO && infoEmbed != null) { + infoButton + .setLabel("Cases") + .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.CASES })); + firstButton.setDisabled(true); + prevButton.setDisabled(true); + nextButton.setDisabled(true); + lastButton.setDisabled(true); + + await i + .editReply({ + embeds: [infoEmbed], + components: [navigationRow, moderationRow], + }) + .catch((err) => logger.error(`Mod menu info view failed: ${err}`)); + } else if (opts.action == ModMenuActionType.PAGE && opts.target == ModMenuNavigationType.CASES) { + infoButton + .setLabel("Info") + .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.INFO })); + updateNavButtonState(firstButton, prevButton, nextButton, lastButton, page, totalPages); + + await i + .editReply({ + embeds: [await loadPage(page)], + components: [navigationRow, moderationRow], + }) + .catch((err) => logger.error(`Mod menu cases view failed: ${err}`)); + } else if (opts.action == ModMenuActionType.PAGE) { + let pageDelta = 0; + switch (opts.target) { + case ModMenuNavigationType.PREV: + pageDelta = -1; + break; + case ModMenuNavigationType.NEXT: + pageDelta = 1; + break; + } + + let newPage = 1; + if (opts.target == ModMenuNavigationType.PREV || opts.target == ModMenuNavigationType.NEXT) { + newPage = Math.max(Math.min(page + pageDelta, totalPages), 1); + } else if (opts.target == ModMenuNavigationType.FIRST) { + newPage = 1; + } else if (opts.target == ModMenuNavigationType.LAST) { + newPage = totalPages; + } + + if (newPage != page) { + updateNavButtonState(firstButton, prevButton, nextButton, lastButton, newPage, totalPages); + + await i + .editReply({ + embeds: [await loadPage(newPage)], + components: [navigationRow, moderationRow], + }) + .catch((err) => logger.error(`Mod menu navigation failed: ${err}`)); + + page = newPage; + } + } else if (opts.action == ModMenuActionType.NOTE) { + await launchNoteActionModal(pluginData, i as ButtonInteraction, opts.target); + } else if (opts.action == ModMenuActionType.WARN) { + await launchWarnActionModal(pluginData, i as ButtonInteraction, opts.target); + } else if (opts.action == ModMenuActionType.CLEAN) { + await launchCleanActionModal(pluginData, i as ButtonInteraction, opts.target); + } else if (opts.action == ModMenuActionType.MUTE) { + await launchMuteActionModal(pluginData, i as ButtonInteraction, opts.target); + } else if (opts.action == ModMenuActionType.BAN) { + await launchBanActionModal(pluginData, i as ButtonInteraction, opts.target); + } + + collector.resetTimer(); }); - } else if (opts.action == ModMenuActionType.PAGE) { - let pageDelta = 0; - switch (opts.target) { - case ModMenuNavigationType.PREV: - pageDelta = -1; - break; - case ModMenuNavigationType.NEXT: - pageDelta = 1; - break; - } - let newPage = 1; - if (opts.target == ModMenuNavigationType.PREV || opts.target == ModMenuNavigationType.NEXT) { - newPage = Math.max(Math.min(page + pageDelta, totalPages), 1); - } else if (opts.target == ModMenuNavigationType.FIRST) { - newPage = 1; - } else if (opts.target == ModMenuNavigationType.LAST) { - newPage = totalPages; - } - - if (newPage != page) { - updateNavButtonState(firstButton, prevButton, nextButton, lastButton, newPage, totalPages); - - await i.editReply({ - embeds: [await loadPage(newPage)], - components: [navigationRow, moderationRow], - }); - - page = newPage; - } - } else if (opts.action == ModMenuActionType.NOTE) { - await launchNoteActionModal(pluginData, i as ButtonInteraction, opts.target); - } else if (opts.action == ModMenuActionType.WARN) { - await launchWarnActionModal(pluginData, i as ButtonInteraction, opts.target); - } else if (opts.action == ModMenuActionType.CLEAN) { - await launchCleanActionModal(pluginData, i as ButtonInteraction, opts.target); - } else if (opts.action == ModMenuActionType.MUTE) { - await launchMuteActionModal(pluginData, i as ButtonInteraction, opts.target); - } else if (opts.action == ModMenuActionType.BAN) { - await launchBanActionModal(pluginData, i as ButtonInteraction, opts.target); - } - - collector.resetTimer(); - }); - - // Remove components on timeout. - collector.on("end", async (_, reason) => { - if (reason !== "messageDelete") { - interaction.editReply({ - components: [], + // Remove components on timeout. + collector.on("end", async (_, reason) => { + if (reason !== "messageDelete") { + await interaction + .editReply({ + components: [], + }) + .catch((err) => logger.error(`Mod menu timeout failed: ${err}`)); + } }); - } - }); + }) + .catch((err) => logger.error(`Mod menu setup failed: ${err}`)); } function serializeCustomId(opts: ModMenuActionOpts) { From cdcca8ccbb2f8f51d7d810fbb26ddc0e0fa39863 Mon Sep 17 00:00:00 2001 From: Obliie Date: Sun, 16 Jul 2023 18:46:00 +0100 Subject: [PATCH 06/30] style(ContextMenus): improve ux --- .../ContextMenus/commands/BanUserCtxCmd.ts | 2 + .../commands/ModMenuUserCtxCmd.ts | 49 ++++++++++++------- .../ContextMenus/commands/MuteUserCtxCmd.ts | 2 + .../ContextMenus/commands/NoteUserCtxCmd.ts | 2 + .../ContextMenus/commands/WarnUserCtxCmd.ts | 2 + 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/backend/src/plugins/ContextMenus/commands/BanUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/BanUserCtxCmd.ts index 237d81cb..741c8f74 100644 --- a/backend/src/plugins/ContextMenus/commands/BanUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/BanUserCtxCmd.ts @@ -1,8 +1,10 @@ +import { PermissionFlagsBits } from "discord.js"; import { guildPluginUserContextMenuCommand } from "knub"; import { launchBanActionModal } from "../actions/ban"; export const BanCmd = guildPluginUserContextMenuCommand({ name: "Ban", + defaultMemberPermissions: PermissionFlagsBits.BanMembers.toString(), async run({ pluginData, interaction }) { await launchBanActionModal(pluginData, interaction, interaction.targetId); }, diff --git a/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts index da8a9014..9cb40f14 100644 --- a/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts @@ -5,11 +5,14 @@ import { ButtonInteraction, ButtonStyle, ContextMenuCommandInteraction, + GuildMember, + PermissionFlagsBits, User, } from "discord.js"; import { GuildPluginData, guildPluginUserContextMenuCommand } from "knub"; import { Case } from "../../../data/entities/Case"; import { logger } from "../../../logger"; +import { ModActionsPlugin } from "../../../plugins/ModActions/ModActionsPlugin"; import { SECONDS, UnknownUser, emptyEmbedValue, renderUserUsername, resolveUser, trimLines } from "../../../utils"; import { asyncMap } from "../../../utils/async"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; @@ -18,7 +21,6 @@ import { CasesPlugin } from "../../Cases/CasesPlugin"; import { UtilityPlugin } from "../../Utility/UtilityPlugin"; import { getUserInfoEmbed } from "../../Utility/functions/getUserInfoEmbed"; import { launchBanActionModal } from "../actions/ban"; -import { launchCleanActionModal } from "../actions/clean"; import { launchMuteActionModal } from "../actions/mute"; import { launchNoteActionModal } from "../actions/note"; import { launchWarnActionModal } from "../actions/warn"; @@ -36,6 +38,7 @@ const CASES_PER_PAGE = 10; export const ModMenuCmd = guildPluginUserContextMenuCommand({ name: "Mod Menu", + defaultMemberPermissions: PermissionFlagsBits.ViewAuditLog.toString(), async run({ pluginData, interaction }) { await interaction .deferReply({ ephemeral: true }) @@ -115,6 +118,7 @@ export const ModMenuCmd = guildPluginUserContextMenuCommand({ return embed; }, infoEmbed, + executingMember, ); }, }); @@ -125,58 +129,65 @@ async function displayModMenu( totalPages: number, loadPage: LoadModMenuPageFn, infoEmbed: APIEmbed | null, + executingMember: GuildMember, ) { if (interaction.deferred == false) { await interaction.deferReply().catch((err) => logger.error(`Mod menu interaction defer failed: ${err}`)); } const firstButton = new ButtonBuilder() - .setStyle(ButtonStyle.Primary) - .setLabel("<<") + .setStyle(ButtonStyle.Secondary) + .setEmoji("⏪") .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.FIRST })) .setDisabled(true); const prevButton = new ButtonBuilder() - .setStyle(ButtonStyle.Primary) - .setLabel("<") + .setStyle(ButtonStyle.Secondary) + .setEmoji("⬅") .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.PREV })) .setDisabled(true); const infoButton = new ButtonBuilder() .setStyle(ButtonStyle.Primary) .setLabel("Info") + .setEmoji("ℹ") .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.INFO })) .setDisabled(infoEmbed != null ? false : true); const nextButton = new ButtonBuilder() - .setStyle(ButtonStyle.Primary) - .setLabel(">") + .setStyle(ButtonStyle.Secondary) + .setEmoji("➡") .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.NEXT })) .setDisabled(totalPages > 1 ? false : true); const lastButton = new ButtonBuilder() - .setStyle(ButtonStyle.Primary) - .setLabel(">>") + .setStyle(ButtonStyle.Secondary) + .setEmoji("⏩") .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.LAST })) .setDisabled(totalPages > 1 ? false : true); const navigationButtons = [firstButton, prevButton, infoButton, nextButton, lastButton] satisfies ButtonBuilder[]; + const modactions = pluginData.getPlugin(ModActionsPlugin); const moderationButtons = [ new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) + .setStyle(ButtonStyle.Primary) .setLabel("Note") + .setEmoji("📝") + .setDisabled(!(await modactions.hasNotePermission(executingMember, interaction.channelId))) .setCustomId(serializeCustomId({ action: ModMenuActionType.NOTE, target: interaction.targetId })), new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) + .setStyle(ButtonStyle.Primary) .setLabel("Warn") + .setEmoji("⚠️") + .setDisabled(!(await modactions.hasWarnPermission(executingMember, interaction.channelId))) .setCustomId(serializeCustomId({ action: ModMenuActionType.WARN, target: interaction.targetId })), new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) - .setLabel("Clean") - .setCustomId(serializeCustomId({ action: ModMenuActionType.CLEAN, target: interaction.targetId })), - new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) + .setStyle(ButtonStyle.Primary) .setLabel("Mute") + .setEmoji("🔇") + .setDisabled(!(await modactions.hasMutePermission(executingMember, interaction.channelId))) .setCustomId(serializeCustomId({ action: ModMenuActionType.MUTE, target: interaction.targetId })), new ButtonBuilder() - .setStyle(ButtonStyle.Secondary) + .setStyle(ButtonStyle.Primary) .setLabel("Ban") + .setEmoji("🚫") + .setDisabled(!(await modactions.hasBanPermission(executingMember, interaction.channelId))) .setCustomId(serializeCustomId({ action: ModMenuActionType.BAN, target: interaction.targetId })), ] satisfies ButtonBuilder[]; @@ -204,6 +215,7 @@ async function displayModMenu( if (opts.action == ModMenuActionType.PAGE && opts.target == ModMenuNavigationType.INFO && infoEmbed != null) { infoButton .setLabel("Cases") + .setEmoji("📋") .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.CASES })); firstButton.setDisabled(true); prevButton.setDisabled(true); @@ -219,6 +231,7 @@ async function displayModMenu( } else if (opts.action == ModMenuActionType.PAGE && opts.target == ModMenuNavigationType.CASES) { infoButton .setLabel("Info") + .setEmoji("ℹ") .setCustomId(serializeCustomId({ action: ModMenuActionType.PAGE, target: ModMenuNavigationType.INFO })); updateNavButtonState(firstButton, prevButton, nextButton, lastButton, page, totalPages); @@ -264,8 +277,6 @@ async function displayModMenu( await launchNoteActionModal(pluginData, i as ButtonInteraction, opts.target); } else if (opts.action == ModMenuActionType.WARN) { await launchWarnActionModal(pluginData, i as ButtonInteraction, opts.target); - } else if (opts.action == ModMenuActionType.CLEAN) { - await launchCleanActionModal(pluginData, i as ButtonInteraction, opts.target); } else if (opts.action == ModMenuActionType.MUTE) { await launchMuteActionModal(pluginData, i as ButtonInteraction, opts.target); } else if (opts.action == ModMenuActionType.BAN) { diff --git a/backend/src/plugins/ContextMenus/commands/MuteUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/MuteUserCtxCmd.ts index 3c060cb3..55123597 100644 --- a/backend/src/plugins/ContextMenus/commands/MuteUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/MuteUserCtxCmd.ts @@ -1,8 +1,10 @@ +import { PermissionFlagsBits } from "discord.js"; import { guildPluginUserContextMenuCommand } from "knub"; import { launchMuteActionModal } from "../actions/mute"; export const MuteCmd = guildPluginUserContextMenuCommand({ name: "Mute", + defaultMemberPermissions: PermissionFlagsBits.ModerateMembers.toString(), async run({ pluginData, interaction }) { await launchMuteActionModal(pluginData, interaction, interaction.targetId); }, diff --git a/backend/src/plugins/ContextMenus/commands/NoteUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/NoteUserCtxCmd.ts index c4f0fa9d..d1163383 100644 --- a/backend/src/plugins/ContextMenus/commands/NoteUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/NoteUserCtxCmd.ts @@ -1,8 +1,10 @@ +import { PermissionFlagsBits } from "discord.js"; import { guildPluginUserContextMenuCommand } from "knub"; import { launchNoteActionModal } from "../actions/note"; export const NoteCmd = guildPluginUserContextMenuCommand({ name: "Note", + defaultMemberPermissions: PermissionFlagsBits.ManageMessages.toString(), async run({ pluginData, interaction }) { await launchNoteActionModal(pluginData, interaction, interaction.targetId); }, diff --git a/backend/src/plugins/ContextMenus/commands/WarnUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/WarnUserCtxCmd.ts index 3f62196c..b3e6a545 100644 --- a/backend/src/plugins/ContextMenus/commands/WarnUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/WarnUserCtxCmd.ts @@ -1,8 +1,10 @@ +import { PermissionFlagsBits } from "discord.js"; import { guildPluginUserContextMenuCommand } from "knub"; import { launchWarnActionModal } from "../actions/warn"; export const WarnCmd = guildPluginUserContextMenuCommand({ name: "Warn", + defaultMemberPermissions: PermissionFlagsBits.ManageMessages.toString(), async run({ pluginData, interaction }) { await launchWarnActionModal(pluginData, interaction, interaction.targetId); }, From 26bf9363f91222ef094f75ef2d9f3d4dfe16705b Mon Sep 17 00:00:00 2001 From: Obliie Date: Sun, 16 Jul 2023 19:07:03 +0100 Subject: [PATCH 07/30] fix(ContextMenus): correct ban modal custom id --- backend/src/plugins/ContextMenus/actions/ban.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts index 0a61c57f..259622a6 100644 --- a/backend/src/plugins/ContextMenus/actions/ban.ts +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -77,7 +77,7 @@ export async function launchBanActionModal( interaction: ButtonInteraction | ContextMenuCommandInteraction, target: string, ) { - const modalId = `${ModMenuActionType.WARN}:${interaction.id}`; + const modalId = `${ModMenuActionType.BAN}:${interaction.id}`; const modal = new ModalBuilder().setCustomId(modalId).setTitle("Ban"); const durationIn = new TextInputBuilder() .setCustomId("duration") From 6689f91a6a14e0a72889a75fe0af3c170b4a9628 Mon Sep 17 00:00:00 2001 From: Obliie Date: Sun, 16 Jul 2023 19:48:53 +0100 Subject: [PATCH 08/30] feat(ContextMenus): add new field to modals for case evidence --- .../src/plugins/ContextMenus/actions/ban.ts | 17 +++++++++-- .../src/plugins/ContextMenus/actions/mute.ts | 17 +++++++++-- .../plugins/ContextMenus/actions/update.ts | 28 +++++++++++++++++++ .../src/plugins/ContextMenus/actions/warn.ts | 17 +++++++++-- 4 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 backend/src/plugins/ContextMenus/actions/update.ts diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts index 259622a6..f2b391cc 100644 --- a/backend/src/plugins/ContextMenus/actions/ban.ts +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -16,11 +16,13 @@ import { convertDelayStringToMS, renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; import { ContextMenuPluginType, ModMenuActionType } from "../types"; +import { updateAction } from "./update"; async function banAction( pluginData: GuildPluginData, duration: string | undefined, reason: string | undefined, + evidence: string | undefined, target: string, interaction: ButtonInteraction | ContextMenuCommandInteraction, submitInteraction: ModalSubmitInteraction, @@ -67,6 +69,10 @@ async function banAction( durationMs ? `for ${humanizeDuration(durationMs)}` : "indefinitely" } (Case #${result.case.case_number})${messageResultText}`; + if (evidence) { + await updateAction(pluginData, executingMember, result.case, evidence); + } + await interactionToReply .editReply({ content: banMessage, embeds: [], components: [] }) .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); @@ -89,9 +95,15 @@ export async function launchBanActionModal( .setLabel("Reason (Optional)") .setRequired(false) .setStyle(TextInputStyle.Paragraph); + const evidenceIn = new TextInputBuilder() + .setCustomId("evidence") + .setLabel("Evidence (Optional)") + .setRequired(false) + .setStyle(TextInputStyle.Paragraph); const durationRow = new ActionRowBuilder().addComponents(durationIn); const reasonRow = new ActionRowBuilder().addComponents(reasonIn); - modal.addComponents(durationRow, reasonRow); + const evidenceRow = new ActionRowBuilder().addComponents(evidenceIn); + modal.addComponents(durationRow, reasonRow, evidenceRow); await interaction.showModal(modal); await interaction @@ -107,8 +119,9 @@ export async function launchBanActionModal( const duration = submitted.fields.getTextInputValue("duration"); const reason = submitted.fields.getTextInputValue("reason"); + const evidence = submitted.fields.getTextInputValue("evidence"); - await banAction(pluginData, duration, reason, target, interaction, submitted); + await banAction(pluginData, duration, reason, evidence, target, interaction, submitted); }) .catch((err) => logger.error(`Ban modal interaction failed: ${err}`)); } diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index b0ea8776..58457cb0 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -19,11 +19,13 @@ import { LogsPlugin } from "../../Logs/LogsPlugin"; import { MutesPlugin } from "../../Mutes/MutesPlugin"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; import { ContextMenuPluginType, ModMenuActionType } from "../types"; +import { updateAction } from "./update"; async function muteAction( pluginData: GuildPluginData, duration: string | undefined, reason: string | undefined, + evidence: string | undefined, target: string, interaction: ButtonInteraction | ContextMenuCommandInteraction, submitInteraction: ModalSubmitInteraction, @@ -73,6 +75,10 @@ async function muteAction( durationMs ? `for ${humanizeDuration(durationMs)}` : "indefinitely" } (Case #${result.case.case_number})${messageResultText}`; + if (evidence) { + await updateAction(pluginData, executingMember, result.case, evidence); + } + await interactionToReply .editReply({ content: muteMessage, embeds: [], components: [] }) .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); @@ -112,9 +118,15 @@ export async function launchMuteActionModal( .setLabel("Reason (Optional)") .setRequired(false) .setStyle(TextInputStyle.Paragraph); + const evidenceIn = new TextInputBuilder() + .setCustomId("evidence") + .setLabel("Evidence (Optional)") + .setRequired(false) + .setStyle(TextInputStyle.Paragraph); const durationRow = new ActionRowBuilder().addComponents(durationIn); const reasonRow = new ActionRowBuilder().addComponents(reasonIn); - modal.addComponents(durationRow, reasonRow); + const evidenceRow = new ActionRowBuilder().addComponents(evidenceIn); + modal.addComponents(durationRow, reasonRow, evidenceRow); await interaction.showModal(modal); await interaction @@ -130,8 +142,9 @@ export async function launchMuteActionModal( const duration = submitted.fields.getTextInputValue("duration"); const reason = submitted.fields.getTextInputValue("reason"); + const evidence = submitted.fields.getTextInputValue("evidence"); - await muteAction(pluginData, duration, reason, target, interaction, submitted); + await muteAction(pluginData, duration, reason, evidence, target, interaction, submitted); }) .catch((err) => logger.error(`Mute modal interaction failed: ${err}`)); } diff --git a/backend/src/plugins/ContextMenus/actions/update.ts b/backend/src/plugins/ContextMenus/actions/update.ts new file mode 100644 index 00000000..3365f293 --- /dev/null +++ b/backend/src/plugins/ContextMenus/actions/update.ts @@ -0,0 +1,28 @@ +import { GuildMember } from "discord.js"; +import { GuildPluginData } from "knub"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { Case } from "../../../data/entities/Case"; +import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; +import { ContextMenuPluginType } from "../types"; + +export async function updateAction( + pluginData: GuildPluginData, + executingMember: GuildMember, + theCase: Case, + value: string, +) { + const casesPlugin = pluginData.getPlugin(CasesPlugin); + await casesPlugin.createCaseNote({ + caseId: theCase.case_number, + modId: executingMember.id, + body: value, + }); + + pluginData.getPlugin(LogsPlugin).logCaseUpdate({ + mod: executingMember.user, + caseNumber: theCase.case_number, + caseType: CaseTypes[theCase.type], + note: value, + }); +} diff --git a/backend/src/plugins/ContextMenus/actions/warn.ts b/backend/src/plugins/ContextMenus/actions/warn.ts index d8eba234..6fbd40f3 100644 --- a/backend/src/plugins/ContextMenus/actions/warn.ts +++ b/backend/src/plugins/ContextMenus/actions/warn.ts @@ -15,10 +15,12 @@ import { renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; import { ContextMenuPluginType, ModMenuActionType } from "../types"; +import { updateAction } from "./update"; async function warnAction( pluginData: GuildPluginData, reason: string, + evidence: string | undefined, target: string, interaction: ButtonInteraction | ContextMenuCommandInteraction, submitInteraction: ModalSubmitInteraction, @@ -70,6 +72,10 @@ async function warnAction( const messageResultText = result.notifyResult.text ? ` (${result.notifyResult.text})` : ""; const muteMessage = `Warned **${userName}** (Case #${result.case.case_number})${messageResultText}`; + if (evidence) { + await updateAction(pluginData, executingMember, result.case, evidence); + } + await interactionToReply .editReply({ content: muteMessage, embeds: [], components: [] }) .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); @@ -83,8 +89,14 @@ export async function launchWarnActionModal( const modalId = `${ModMenuActionType.WARN}:${interaction.id}`; const modal = new ModalBuilder().setCustomId(modalId).setTitle("Warn"); const reasonIn = new TextInputBuilder().setCustomId("reason").setLabel("Reason").setStyle(TextInputStyle.Paragraph); + const evidenceIn = new TextInputBuilder() + .setCustomId("evidence") + .setLabel("Evidence (Optional)") + .setRequired(false) + .setStyle(TextInputStyle.Paragraph); const reasonRow = new ActionRowBuilder().addComponents(reasonIn); - modal.addComponents(reasonRow); + const evidenceRow = new ActionRowBuilder().addComponents(evidenceIn); + modal.addComponents(reasonRow, evidenceRow); await interaction.showModal(modal); await interaction @@ -99,8 +111,9 @@ export async function launchWarnActionModal( } const reason = submitted.fields.getTextInputValue("reason"); + const evidence = submitted.fields.getTextInputValue("evidence"); - await warnAction(pluginData, reason, target, interaction, submitted); + await warnAction(pluginData, reason, evidence, target, interaction, submitted); }) .catch((err) => logger.error(`Warn modal interaction failed: ${err}`)); } From 740aa39cd5119581f8744932ba230d1502d0ccee Mon Sep 17 00:00:00 2001 From: Obliie Date: Sat, 5 Aug 2023 21:31:24 +0100 Subject: [PATCH 09/30] feat: add clean message context menu command --- backend/src/pluginUtils.ts | 43 +++++++++++------ .../plugins/ContextMenus/ContextMenuPlugin.ts | 3 +- .../src/plugins/ContextMenus/actions/clean.ts | 36 +++++++++++---- .../commands/CleanMessageCtxCmd.ts | 11 +++++ .../src/plugins/Utility/commands/CleanCmd.ts | 46 +++++++++++++++---- 5 files changed, 107 insertions(+), 32 deletions(-) create mode 100644 backend/src/plugins/ContextMenus/commands/CleanMessageCtxCmd.ts diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index 8e6c6da2..24899916 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -7,6 +7,7 @@ import { Message, MessageCreateOptions, MessageMentionOptions, + ModalSubmitInteraction, PermissionsBitField, TextBasedChannel, } from "discord.js"; @@ -104,6 +105,7 @@ export async function sendSuccessMessage( channel: TextBasedChannel, body: string, allowedMentions?: MessageMentionOptions, + responseInteraction?: ModalSubmitInteraction, ): Promise { const emoji = pluginData.fullConfig.success_emoji || undefined; const formattedBody = successMessage(body, emoji); @@ -111,13 +113,19 @@ export async function sendSuccessMessage( ? { content: formattedBody, allowedMentions } : { content: formattedBody }; - return channel - .send({ ...content }) // Force line break - .catch((err) => { - 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; - }); + if (responseInteraction) { + await responseInteraction + .editReply({ content: formattedBody, embeds: [], components: [] }) + .catch((err) => logger.error(`Interaction reply failed: ${err}`)); + } else { + return channel + .send({ ...content }) // Force line break + .catch((err) => { + 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; + }); + } } export async function sendErrorMessage( @@ -125,6 +133,7 @@ export async function sendErrorMessage( channel: TextBasedChannel, body: string, allowedMentions?: MessageMentionOptions, + responseInteraction?: ModalSubmitInteraction, ): Promise { const emoji = pluginData.fullConfig.error_emoji || undefined; const formattedBody = errorMessage(body, emoji); @@ -132,13 +141,19 @@ export async function sendErrorMessage( ? { content: formattedBody, allowedMentions } : { content: formattedBody }; - return channel - .send({ ...content }) // Force line break - .catch((err) => { - 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; - }); + if (responseInteraction) { + await responseInteraction + .editReply({ content: formattedBody, embeds: [], components: [] }) + .catch((err) => logger.error(`Interaction reply failed: ${err}`)); + } else { + return channel + .send({ ...content }) // Force line break + .catch((err) => { + 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; + }); + } } export function getBaseUrl(pluginData: AnyPluginData) { diff --git a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts index 5461409d..1d8750b3 100644 --- a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts +++ b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts @@ -9,6 +9,7 @@ import { MutesPlugin } from "../Mutes/MutesPlugin"; import { UtilityPlugin } from "../Utility/UtilityPlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { BanCmd } from "./commands/BanUserCtxCmd"; +import { CleanCmd } from "./commands/CleanMessageCtxCmd"; import { ModMenuCmd } from "./commands/ModMenuUserCtxCmd"; import { MuteCmd } from "./commands/MuteUserCtxCmd"; import { NoteCmd } from "./commands/NoteUserCtxCmd"; @@ -49,7 +50,7 @@ export const ContextMenuPlugin = zeppelinGuildPlugin()({ defaultOptions, - contextMenuCommands: [ModMenuCmd, NoteCmd, WarnCmd, MuteCmd, BanCmd], + contextMenuCommands: [ModMenuCmd, NoteCmd, WarnCmd, MuteCmd, BanCmd, CleanCmd], beforeLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/ContextMenus/actions/clean.ts b/backend/src/plugins/ContextMenus/actions/clean.ts index 628451c6..c5125721 100644 --- a/backend/src/plugins/ContextMenus/actions/clean.ts +++ b/backend/src/plugins/ContextMenus/actions/clean.ts @@ -1,4 +1,12 @@ -import { ActionRowBuilder, ButtonInteraction, ModalBuilder, TextInputBuilder, TextInputStyle } from "discord.js"; +import { + ActionRowBuilder, + Message, + MessageContextMenuCommandInteraction, + ModalBuilder, + ModalSubmitInteraction, + TextInputBuilder, + TextInputStyle, +} from "discord.js"; import { GuildPluginData } from "knub"; import { logger } from "../../../logger"; import { UtilityPlugin } from "../../../plugins/Utility/UtilityPlugin"; @@ -9,7 +17,9 @@ export async function cleanAction( pluginData: GuildPluginData, amount: number, target: string, - interaction: ButtonInteraction, + targetMessage: Message, + targetChannel: string, + interaction: ModalSubmitInteraction, ) { const executingMember = await pluginData.guild.members.fetch(interaction.user.id); const userCfg = await pluginData.config.getMatchingConfig({ @@ -18,26 +28,27 @@ export async function cleanAction( }); const utility = pluginData.getPlugin(UtilityPlugin); - if (!userCfg.can_use || !(await utility.hasPermission(executingMember, interaction.channelId, "can_clean"))) { + if (!userCfg.can_use || !(await utility.hasPermission(executingMember, targetChannel, "can_clean"))) { await interaction .editReply({ content: "Cannot clean: insufficient permissions", embeds: [], components: [] }) .catch((err) => logger.error(`Clean interaction reply failed: ${err}`)); return; } - // TODO: Implement message cleaning await interaction .editReply({ - content: `TODO: Implementation incomplete`, + content: `Cleaning ${amount} messages from ${target}...`, embeds: [], components: [], }) .catch((err) => logger.error(`Clean interaction reply failed: ${err}`)); + + await utility.clean({ count: amount, channel: targetChannel, "response-interaction": interaction }, targetMessage); } export async function launchCleanActionModal( pluginData: GuildPluginData, - interaction: ButtonInteraction, + interaction: MessageContextMenuCommandInteraction, target: string, ) { const modalId = `${ModMenuActionType.CLEAN}:${interaction.id}`; @@ -50,7 +61,9 @@ export async function launchCleanActionModal( await interaction .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) .then(async (submitted) => { - await submitted.deferUpdate().catch((err) => logger.error(`Clean interaction defer failed: ${err}`)); + await submitted + .deferReply({ ephemeral: true }) + .catch((err) => logger.error(`Clean interaction defer failed: ${err}`)); const amount = submitted.fields.getTextInputValue("amount"); if (isNaN(Number(amount))) { @@ -60,7 +73,14 @@ export async function launchCleanActionModal( return; } - await cleanAction(pluginData, Number(amount), target, interaction); + await cleanAction( + pluginData, + Number(amount), + target, + interaction.targetMessage, + interaction.channelId, + submitted, + ); }) .catch((err) => logger.error(`Clean modal interaction failed: ${err}`)); } diff --git a/backend/src/plugins/ContextMenus/commands/CleanMessageCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/CleanMessageCtxCmd.ts new file mode 100644 index 00000000..0902ab00 --- /dev/null +++ b/backend/src/plugins/ContextMenus/commands/CleanMessageCtxCmd.ts @@ -0,0 +1,11 @@ +import { PermissionFlagsBits } from "discord.js"; +import { guildPluginMessageContextMenuCommand } from "knub"; +import { launchCleanActionModal } from "../actions/clean"; + +export const CleanCmd = guildPluginMessageContextMenuCommand({ + name: "Clean", + defaultMemberPermissions: PermissionFlagsBits.ManageMessages.toString(), + async run({ pluginData, interaction }) { + await launchCleanActionModal(pluginData, interaction, interaction.targetId); + }, +}); diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index 18d4efa2..e47dc413 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -1,4 +1,4 @@ -import { Message, Snowflake, TextChannel, User } from "discord.js"; +import { Message, ModalSubmitInteraction, Snowflake, TextChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; import { allowTimeout } from "../../../RegExpRunner"; import { commandTypeHelpers as ct } from "../../../commandTypes"; @@ -77,17 +77,24 @@ export interface CleanArgs { "has-invites"?: boolean; match?: RegExp; "to-id"?: string; + "response-interaction"?: ModalSubmitInteraction; } export async function cleanCmd(pluginData: GuildPluginData, args: CleanArgs | any, msg) { if (args.count > MAX_CLEAN_COUNT || args.count <= 0) { - sendErrorMessage(pluginData, msg.channel, `Clean count must be between 1 and ${MAX_CLEAN_COUNT}`); + sendErrorMessage( + pluginData, + msg.channel, + `Clean count must be between 1 and ${MAX_CLEAN_COUNT}`, + undefined, + args["response-interaction"], + ); return; } const targetChannel = args.channel ? pluginData.guild.channels.cache.get(args.channel as Snowflake) : msg.channel; if (!targetChannel?.isTextBased()) { - sendErrorMessage(pluginData, msg.channel, `Invalid channel specified`); + sendErrorMessage(pluginData, msg.channel, `Invalid channel specified`, undefined, args["response-interaction"]); return; } @@ -99,12 +106,21 @@ export async function cleanCmd(pluginData: GuildPluginData, a categoryId: targetChannel.parentId, }); if (configForTargetChannel.can_clean !== true) { - sendErrorMessage(pluginData, msg.channel, `Missing permissions to use clean on that channel`); + sendErrorMessage( + pluginData, + msg.channel, + `Missing permissions to use clean on that channel`, + undefined, + args["response-interaction"], + ); return; } } - const cleaningMessage = msg.channel.send("Cleaning..."); + let cleaningMessage: Message | undefined = undefined; + if (!args["response-interaction"]) { + cleaningMessage = await msg.channel.send("Cleaning..."); + } const messagesToClean: Message[] = []; let beforeId = msg.id; @@ -202,19 +218,31 @@ export async function cleanCmd(pluginData: GuildPluginData, a } } - responseMsg = await sendSuccessMessage(pluginData, msg.channel, responseText); + responseMsg = await sendSuccessMessage( + pluginData, + msg.channel, + responseText, + undefined, + args["response-interaction"], + ); } else { const responseText = `Found no messages to clean${note ? ` (${note})` : ""}!`; - responseMsg = await sendErrorMessage(pluginData, msg.channel, responseText); + responseMsg = await sendErrorMessage( + pluginData, + msg.channel, + responseText, + undefined, + args["response-interaction"], + ); } - await (await cleaningMessage).delete(); + cleaningMessage?.delete(); if (targetChannel.id === msg.channel.id) { // Delete the !clean command and the bot response if a different channel wasn't specified // (so as not to spam the cleaned channel with the command itself) + msg.delete().catch(noop); setTimeout(() => { - msg.delete().catch(noop); responseMsg?.delete().catch(noop); }, CLEAN_COMMAND_DELETE_DELAY); } From dfb0e2c19d1aa123834294134830a67bdf00858d Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Mon, 22 Jan 2024 17:21:05 +0100 Subject: [PATCH 10/30] WIP: Note Slash Command --- backend/src/pluginUtils.ts | 64 +++++++- .../plugins/ModActions/ModActionsPlugin.ts | 23 ++- .../plugins/ModActions/commands/AddCaseCmd.ts | 4 +- .../src/plugins/ModActions/commands/BanCmd.ts | 146 +++++++++--------- .../plugins/ModActions/commands/CaseCmd.ts | 4 +- .../ModActions/commands/CasesModCmd.ts | 4 +- .../ModActions/commands/CasesUserCmd.ts | 4 +- .../ModActions/commands/DeleteCaseCmd.ts | 4 +- .../ModActions/commands/ForcebanCmd.ts | 4 +- .../ModActions/commands/ForcemuteCmd.ts | 4 +- .../ModActions/commands/ForceunmuteCmd.ts | 4 +- .../ModActions/commands/HideCaseCmd.ts | 4 +- .../plugins/ModActions/commands/KickCmd.ts | 4 +- .../plugins/ModActions/commands/MassBanCmd.ts | 4 +- .../ModActions/commands/MassUnbanCmd.ts | 4 +- .../ModActions/commands/MassmuteCmd.ts | 4 +- .../plugins/ModActions/commands/MuteCmd.ts | 4 +- .../plugins/ModActions/commands/NoteCmd.ts | 54 ------- .../ModActions/commands/SoftbanCommand.ts | 4 +- .../plugins/ModActions/commands/UnbanCmd.ts | 4 +- .../ModActions/commands/UnhideCaseCmd.ts | 4 +- .../plugins/ModActions/commands/UnmuteCmd.ts | 4 +- .../plugins/ModActions/commands/UpdateCmd.ts | 4 +- .../plugins/ModActions/commands/WarnCmd.ts | 4 +- .../ModActions/commands/note/NoteMsgCmd.ts | 31 ++++ .../ModActions/commands/note/NoteSlashCmd.ts | 45 ++++++ .../ModActions/functions/actualNoteCmd.ts | 47 ++++++ backend/src/plugins/ModActions/types.ts | 5 +- backend/src/plugins/availablePlugins.ts | 2 +- 29 files changed, 319 insertions(+), 178 deletions(-) delete mode 100644 backend/src/plugins/ModActions/commands/NoteCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualNoteCmd.ts diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index 24899916..7ae53217 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -3,6 +3,7 @@ */ import { + ChatInputCommandInteraction, GuildMember, Message, MessageCreateOptions, @@ -100,12 +101,19 @@ export function makeIoTsConfigParser>(schema: Schema) }; } +function isContextInteraction( + context: TextBasedChannel | ChatInputCommandInteraction, +): context is ChatInputCommandInteraction { + return "commandId" in context && !!context.commandId; +} + export async function sendSuccessMessage( pluginData: AnyPluginData, - channel: TextBasedChannel, + context: TextBasedChannel | ChatInputCommandInteraction, body: string, allowedMentions?: MessageMentionOptions, responseInteraction?: ModalSubmitInteraction, + ephemeral = false, ): Promise { const emoji = pluginData.fullConfig.success_emoji || undefined; const formattedBody = successMessage(body, emoji); @@ -117,23 +125,44 @@ export async function sendSuccessMessage( await responseInteraction .editReply({ content: formattedBody, embeds: [], components: [] }) .catch((err) => logger.error(`Interaction reply failed: ${err}`)); - } else { - return channel + + return; + } + + if (!isContextInteraction(context)) { + // noinspection TypeScriptValidateJSTypes + return context .send({ ...content }) // Force line break .catch((err) => { - const channelInfo = "guild" in channel ? `${channel.id} (${channel.guild.id})` : channel.id; + const channelInfo = "guild" in context ? `${context.id} (${context.guild.id})` : context.id; logger.warn(`Failed to send success message to ${channelInfo}): ${err.code} ${err.message}`); + return undefined; }); } + + const replyMethod = context.replied ? "followUp" : "reply"; + + return context[replyMethod]({ + content: formattedBody, + embeds: [], + components: [], + fetchReply: true, + ephemeral, + }).catch((err) => { + logger.error(`Context reply failed: ${err}`); + + return undefined; + }); } export async function sendErrorMessage( pluginData: AnyPluginData, - channel: TextBasedChannel, + context: TextBasedChannel | ChatInputCommandInteraction, body: string, allowedMentions?: MessageMentionOptions, responseInteraction?: ModalSubmitInteraction, + ephemeral = false, ): Promise { const emoji = pluginData.fullConfig.error_emoji || undefined; const formattedBody = errorMessage(body, emoji); @@ -145,15 +174,34 @@ export async function sendErrorMessage( await responseInteraction .editReply({ content: formattedBody, embeds: [], components: [] }) .catch((err) => logger.error(`Interaction reply failed: ${err}`)); - } else { - return channel + + return; + } + + if (!isContextInteraction(context)) { + // noinspection TypeScriptValidateJSTypes + return context .send({ ...content }) // Force line break .catch((err) => { - const channelInfo = "guild" in channel ? `${channel.id} (${channel.guild.id})` : channel.id; + const channelInfo = "guild" in context ? `${context.id} (${context.guild.id})` : context.id; logger.warn(`Failed to send error message to ${channelInfo}): ${err.code} ${err.message}`); return undefined; }); } + + const replyMethod = context.replied ? "followUp" : "reply"; + + return context[replyMethod]({ + content: formattedBody, + embeds: [], + components: [], + fetchReply: true, + ephemeral, + }).catch((err) => { + logger.error(`Context reply failed: ${err}`); + + return undefined; + }); } export function getBaseUrl(pluginData: AnyPluginData) { diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index 9b7d3404..57b2709e 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -28,13 +28,14 @@ import { MassbanCmd } from "./commands/MassBanCmd"; import { MassunbanCmd } from "./commands/MassUnbanCmd"; import { MassmuteCmd } from "./commands/MassmuteCmd"; import { MuteCmd } from "./commands/MuteCmd"; -import { NoteCmd } from "./commands/NoteCmd"; import { SoftbanCmd } from "./commands/SoftbanCommand"; import { UnbanCmd } from "./commands/UnbanCmd"; import { UnhideCaseCmd } from "./commands/UnhideCaseCmd"; import { UnmuteCmd } from "./commands/UnmuteCmd"; import { UpdateCmd } from "./commands/UpdateCmd"; import { WarnCmd } from "./commands/WarnCmd"; +import { NoteMsgCmd } from "./commands/note/NoteMsgCmd"; +import { NoteSlashCmd } from "./commands/note/NoteSlashCmd"; import { AuditLogEvents } from "./events/AuditLogEvents"; import { CreateBanCaseOnManualBanEvt } from "./events/CreateBanCaseOnManualBanEvt"; import { CreateUnbanCaseOnManualUnbanEvt } from "./events/CreateUnbanCaseOnManualUnbanEvt"; @@ -52,7 +53,14 @@ import { offModActionsEvent } from "./functions/offModActionsEvent"; import { onModActionsEvent } from "./functions/onModActionsEvent"; import { updateCase } from "./functions/updateCase"; import { warnMember } from "./functions/warnMember"; -import { BanOptions, ConfigSchema, KickOptions, ModActionsPluginType, WarnOptions } from "./types"; +import { + BanOptions, + ConfigSchema, + KickOptions, + ModActionsPluginType, + WarnOptions, + modActionsSlashGroup, +} from "./types"; const defaultOptions = { config: { @@ -135,9 +143,18 @@ export const ModActionsPlugin = zeppelinGuildPlugin()({ events: [CreateBanCaseOnManualBanEvt, CreateUnbanCaseOnManualUnbanEvt, PostAlertOnMemberJoinEvt, AuditLogEvents], + slashCommands: [ + modActionsSlashGroup({ + name: "mod", + description: "Moderation actions", + defaultMemberPermissions: "0", + subcommands: [{ type: "slash", ...NoteSlashCmd }], + }), + ], + messageCommands: [ UpdateCmd, - NoteCmd, + NoteMsgCmd, WarnCmd, MuteCmd, ForcemuteCmd, diff --git a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts index 43575463..dc8df97f 100644 --- a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts @@ -6,13 +6,13 @@ import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from ". import { renderUserUsername, resolveMember, resolveUser } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; const opts = { mod: ct.member({ option: true }), }; -export const AddCaseCmd = modActionsCmd({ +export const AddCaseCmd = modActionsMsgCmd({ trigger: "addcase", permission: "can_addcase", description: "Add an arbitrary case to the specified user without taking any action", diff --git a/backend/src/plugins/ModActions/commands/BanCmd.ts b/backend/src/plugins/ModActions/commands/BanCmd.ts index 9d32cd10..f0a20d5f 100644 --- a/backend/src/plugins/ModActions/commands/BanCmd.ts +++ b/backend/src/plugins/ModActions/commands/BanCmd.ts @@ -13,7 +13,7 @@ import { banUserId } from "../functions/banUserId"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { isBanned } from "../functions/isBanned"; import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; const opts = { mod: ct.member({ option: true }), @@ -22,7 +22,7 @@ const opts = { "delete-days": ct.number({ option: true, shortcut: "d" }), }; -export const BanCmd = modActionsCmd({ +export const BanCmd = modActionsMsgCmd({ trigger: "ban", permission: "can_ban", description: "Ban or Tempban the specified member", @@ -45,13 +45,12 @@ export const BanCmd = modActionsCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); + if (!user.id) { sendErrorMessage(pluginData, msg.channel, `User not found`); return; } - const time = args["time"] ? args["time"] : null; - const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]); const memberToBan = await resolveMember(pluginData.client, pluginData.guild, user.id); // The moderator who did the action is the message author or, if used, the specified -mod let mod = msg.member; @@ -64,85 +63,25 @@ export const BanCmd = modActionsCmd({ mod = args.mod; } + const time = args["time"] ? args["time"] : null; + const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]); + // acquire a lock because of the needed user-inputs below (if banned/not on server) const lock = await pluginData.locks.acquire(banLock(user)); let forceban = false; const existingTempban = await pluginData.state.tempbans.findExistingTempbanForUserId(user.id); + if (!memberToBan) { const banned = await isBanned(pluginData, user.id); - if (banned) { - // Abort if trying to ban user indefinitely if they are already banned indefinitely - if (!existingTempban && !time) { - sendErrorMessage(pluginData, msg.channel, `User is already banned indefinitely.`); - return; - } - // Ask the mod if we should update the existing ban - const reply = await waitForButtonConfirm( - msg.channel, - { content: "Failed to message the user. Log the warning anyway?" }, - { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, - ); - if (!reply) { - sendErrorMessage(pluginData, msg.channel, "User already banned, update cancelled by moderator"); - lock.unlock(); - return; - } else { - // Update or add new tempban / remove old tempban - if (time && time > 0) { - if (existingTempban) { - await pluginData.state.tempbans.updateExpiryTime(user.id, time, mod.id); - } else { - await pluginData.state.tempbans.addTempban(user.id, time, mod.id); - } - const tempban = (await pluginData.state.tempbans.findExistingTempbanForUserId(user.id))!; - registerExpiringTempban(tempban); - } else if (existingTempban) { - clearExpiringTempban(existingTempban); - pluginData.state.tempbans.clear(user.id); - } - - // Create a new case for the updated ban since we never stored the old case id and log the action - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const createdCase = await casesPlugin.createCase({ - modId: mod.id, - type: CaseTypes.Ban, - userId: user.id, - reason, - noteDetails: [`Ban updated to ${time ? humanizeDuration(time) : "indefinite"}`], - }); - if (time) { - pluginData.getPlugin(LogsPlugin).logMemberTimedBan({ - mod: mod.user, - user, - caseNumber: createdCase.case_number, - reason, - banTime: humanizeDuration(time), - }); - } else { - pluginData.getPlugin(LogsPlugin).logMemberBan({ - mod: mod.user, - user, - caseNumber: createdCase.case_number, - reason, - }); - } - - sendSuccessMessage( - pluginData, - msg.channel, - `Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`, - ); - lock.unlock(); - return; - } - } else { + if (!banned) { // Ask the mod if we should upgrade to a forceban as the user is not on the server const reply = await waitForButtonConfirm( msg.channel, { content: "User not on server, forceban instead?" }, { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, ); + if (!reply) { sendErrorMessage(pluginData, msg.channel, "User not on server, ban cancelled by moderator"); lock.unlock(); @@ -151,6 +90,73 @@ export const BanCmd = modActionsCmd({ forceban = true; } } + + // Abort if trying to ban user indefinitely if they are already banned indefinitely + if (!existingTempban && !time) { + sendErrorMessage(pluginData, msg.channel, `User is already banned indefinitely.`); + return; + } + + // Ask the mod if we should update the existing ban + const reply = await waitForButtonConfirm( + msg.channel, + { content: "Failed to message the user. Log the warning anyway?" }, + { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, + ); + + if (!reply) { + sendErrorMessage(pluginData, msg.channel, "User already banned, update cancelled by moderator"); + lock.unlock(); + return; + } + + // Update or add new tempban / remove old tempban + if (time && time > 0) { + if (existingTempban) { + await pluginData.state.tempbans.updateExpiryTime(user.id, time, mod.id); + } else { + await pluginData.state.tempbans.addTempban(user.id, time, mod.id); + } + const tempban = (await pluginData.state.tempbans.findExistingTempbanForUserId(user.id))!; + registerExpiringTempban(tempban); + } else if (existingTempban) { + clearExpiringTempban(existingTempban); + pluginData.state.tempbans.clear(user.id); + } + + // Create a new case for the updated ban since we never stored the old case id and log the action + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const createdCase = await casesPlugin.createCase({ + modId: mod.id, + type: CaseTypes.Ban, + userId: user.id, + reason, + noteDetails: [`Ban updated to ${time ? humanizeDuration(time) : "indefinite"}`], + }); + if (time) { + pluginData.getPlugin(LogsPlugin).logMemberTimedBan({ + mod: mod.user, + user, + caseNumber: createdCase.case_number, + reason, + banTime: humanizeDuration(time), + }); + } else { + pluginData.getPlugin(LogsPlugin).logMemberBan({ + mod: mod.user, + user, + caseNumber: createdCase.case_number, + reason, + }); + } + + sendSuccessMessage( + pluginData, + msg.channel, + `Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`, + ); + lock.unlock(); + return; } // Make sure we're allowed to ban this member if they are on the server diff --git a/backend/src/plugins/ModActions/commands/CaseCmd.ts b/backend/src/plugins/ModActions/commands/CaseCmd.ts index d3d8ce95..8a92ed3f 100644 --- a/backend/src/plugins/ModActions/commands/CaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/CaseCmd.ts @@ -1,9 +1,9 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { sendErrorMessage } from "../../../pluginUtils"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; -export const CaseCmd = modActionsCmd({ +export const CaseCmd = modActionsMsgCmd({ trigger: "case", permission: "can_view", description: "Show information about a specific case", diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts index 5b0e3273..e07176f5 100644 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesModCmd.ts @@ -7,7 +7,7 @@ import { createPaginatedMessage } from "../../../utils/createPaginatedMessage"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; const opts = { mod: ct.userId({ option: true }), @@ -15,7 +15,7 @@ const opts = { const casesPerPage = 5; -export const CasesModCmd = modActionsCmd({ +export const CasesModCmd = modActionsMsgCmd({ trigger: ["cases", "modlogs", "infractions"], permission: "can_view", description: "Show the most recent 5 cases by the specified -mod", diff --git a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts index 069ad31f..a92ea75d 100644 --- a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts +++ b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts @@ -7,7 +7,7 @@ import { UnknownUser, chunkArray, emptyEmbedValue, renderUserUsername, resolveUs import { asyncMap } from "../../../utils/async"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; const opts = { expand: ct.bool({ option: true, isSwitch: true, shortcut: "e" }), @@ -21,7 +21,7 @@ const opts = { unbans: ct.switchOption({ def: false, shortcut: "ub" }), }; -export const CasesUserCmd = modActionsCmd({ +export const CasesUserCmd = modActionsMsgCmd({ trigger: ["cases", "modlogs"], permission: "can_view", description: "Show a list of cases the specified user has", diff --git a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts index 823bc726..cb3c56d8 100644 --- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts @@ -6,9 +6,9 @@ import { SECONDS, trimLines } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; -export const DeleteCaseCmd = modActionsCmd({ +export const DeleteCaseCmd = modActionsMsgCmd({ trigger: ["delete_case", "deletecase"], permission: "can_deletecase", description: trimLines(` diff --git a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts index 4ddef154..251be232 100644 --- a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts @@ -9,13 +9,13 @@ import { LogsPlugin } from "../../Logs/LogsPlugin"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { ignoreEvent } from "../functions/ignoreEvent"; import { isBanned } from "../functions/isBanned"; -import { IgnoredEventType, modActionsCmd } from "../types"; +import { IgnoredEventType, modActionsMsgCmd } from "../types"; const opts = { mod: ct.member({ option: true }), }; -export const ForcebanCmd = modActionsCmd({ +export const ForcebanCmd = modActionsMsgCmd({ trigger: "forceban", permission: "can_ban", description: "Force-ban the specified user, even if they aren't on the server", diff --git a/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts b/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts index 18fe1228..4b6f90da 100644 --- a/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts @@ -2,7 +2,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn, sendErrorMessage } from "../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../utils"; import { actualMuteUserCmd } from "../functions/actualMuteUserCmd"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; const opts = { mod: ct.member({ option: true }), @@ -10,7 +10,7 @@ const opts = { "notify-channel": ct.textChannel({ option: true }), }; -export const ForcemuteCmd = modActionsCmd({ +export const ForcemuteCmd = modActionsMsgCmd({ trigger: "forcemute", permission: "can_mute", description: "Force-mute the specified user, even if they're not on the server", diff --git a/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts b/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts index 8ce0ce14..5ce489a1 100644 --- a/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts @@ -2,13 +2,13 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn, sendErrorMessage } from "../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../utils"; import { actualUnmuteCmd } from "../functions/actualUnmuteUserCmd"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; const opts = { mod: ct.member({ option: true }), }; -export const ForceUnmuteCmd = modActionsCmd({ +export const ForceUnmuteCmd = modActionsMsgCmd({ trigger: "forceunmute", permission: "can_mute", description: "Force-unmute the specified user, even if they're not on the server", diff --git a/backend/src/plugins/ModActions/commands/HideCaseCmd.ts b/backend/src/plugins/ModActions/commands/HideCaseCmd.ts index 38337d85..b08756db 100644 --- a/backend/src/plugins/ModActions/commands/HideCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/HideCaseCmd.ts @@ -1,8 +1,8 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; -export const HideCaseCmd = modActionsCmd({ +export const HideCaseCmd = modActionsMsgCmd({ trigger: ["hide", "hidecase", "hide_case"], permission: "can_hidecase", description: "Hide the specified case so it doesn't appear in !cases or !info", diff --git a/backend/src/plugins/ModActions/commands/KickCmd.ts b/backend/src/plugins/ModActions/commands/KickCmd.ts index 080294d0..2e32f3e2 100644 --- a/backend/src/plugins/ModActions/commands/KickCmd.ts +++ b/backend/src/plugins/ModActions/commands/KickCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { actualKickMemberCmd } from "../functions/actualKickMemberCmd"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; const opts = { mod: ct.member({ option: true }), @@ -9,7 +9,7 @@ const opts = { clean: ct.bool({ option: true, isSwitch: true }), }; -export const KickCmd = modActionsCmd({ +export const KickCmd = modActionsMsgCmd({ trigger: "kick", permission: "can_kick", description: "Kick the specified member", diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts index d31aadd7..4769cd51 100644 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassBanCmd.ts @@ -11,9 +11,9 @@ import { DAYS, MINUTES, SECONDS, noop } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { ignoreEvent } from "../functions/ignoreEvent"; -import { IgnoredEventType, modActionsCmd } from "../types"; +import { IgnoredEventType, modActionsMsgCmd } from "../types"; -export const MassbanCmd = modActionsCmd({ +export const MassbanCmd = modActionsMsgCmd({ trigger: "massban", permission: "can_massban", description: "Mass-ban a list of user IDs", diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts index c5ce37ac..a873b4c6 100644 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts @@ -9,9 +9,9 @@ import { LogsPlugin } from "../../Logs/LogsPlugin"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { ignoreEvent } from "../functions/ignoreEvent"; import { isBanned } from "../functions/isBanned"; -import { IgnoredEventType, modActionsCmd } from "../types"; +import { IgnoredEventType, modActionsMsgCmd } from "../types"; -export const MassunbanCmd = modActionsCmd({ +export const MassunbanCmd = modActionsMsgCmd({ trigger: "massunban", permission: "can_massunban", description: "Mass-unban a list of user IDs", diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts index a62c029e..65422f0f 100644 --- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts @@ -7,9 +7,9 @@ import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginU import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; -export const MassmuteCmd = modActionsCmd({ +export const MassmuteCmd = modActionsMsgCmd({ trigger: "massmute", permission: "can_massmute", description: "Mass-mute a list of user IDs", diff --git a/backend/src/plugins/ModActions/commands/MuteCmd.ts b/backend/src/plugins/ModActions/commands/MuteCmd.ts index f824fca3..4c505701 100644 --- a/backend/src/plugins/ModActions/commands/MuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/MuteCmd.ts @@ -4,7 +4,7 @@ import { resolveMember, resolveUser } from "../../../utils"; import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; import { actualMuteUserCmd } from "../functions/actualMuteUserCmd"; import { isBanned } from "../functions/isBanned"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; const opts = { mod: ct.member({ option: true }), @@ -12,7 +12,7 @@ const opts = { "notify-channel": ct.textChannel({ option: true }), }; -export const MuteCmd = modActionsCmd({ +export const MuteCmd = modActionsMsgCmd({ trigger: "mute", permission: "can_mute", description: "Mute the specified member", diff --git a/backend/src/plugins/ModActions/commands/NoteCmd.ts b/backend/src/plugins/ModActions/commands/NoteCmd.ts deleted file mode 100644 index b13ed498..00000000 --- a/backend/src/plugins/ModActions/commands/NoteCmd.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { renderUserUsername, resolveUser } from "../../../utils"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { modActionsCmd } from "../types"; - -export const NoteCmd = modActionsCmd({ - trigger: "note", - permission: "can_note", - description: "Add a note to the specified user", - - signature: { - user: ct.string(), - note: ct.string({ required: false, catchAll: true }), - }, - - async run({ pluginData, message: msg, args }) { - const user = await resolveUser(pluginData.client, args.user); - if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); - return; - } - - if (!args.note && msg.attachments.size === 0) { - sendErrorMessage(pluginData, msg.channel, "Text or attachment required"); - return; - } - - const userName = renderUserUsername(user); - const reason = formatReasonWithAttachments(args.note, [...msg.attachments.values()]); - - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const createdCase = await casesPlugin.createCase({ - userId: user.id, - modId: msg.author.id, - type: CaseTypes.Note, - reason, - }); - - pluginData.getPlugin(LogsPlugin).logMemberNote({ - mod: msg.author, - user, - caseNumber: createdCase.case_number, - reason, - }); - - sendSuccessMessage(pluginData, msg.channel, `Note added on **${userName}** (Case #${createdCase.case_number})`); - - pluginData.state.events.emit("note", user.id, reason); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/SoftbanCommand.ts b/backend/src/plugins/ModActions/commands/SoftbanCommand.ts index 9bbb6415..a5806cdd 100644 --- a/backend/src/plugins/ModActions/commands/SoftbanCommand.ts +++ b/backend/src/plugins/ModActions/commands/SoftbanCommand.ts @@ -1,7 +1,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { trimPluginDescription } from "../../../utils"; import { actualKickMemberCmd } from "../functions/actualKickMemberCmd"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; const opts = { mod: ct.member({ option: true }), @@ -9,7 +9,7 @@ const opts = { "notify-channel": ct.textChannel({ option: true }), }; -export const SoftbanCmd = modActionsCmd({ +export const SoftbanCmd = modActionsMsgCmd({ trigger: "softban", permission: "can_kick", description: trimPluginDescription(` diff --git a/backend/src/plugins/ModActions/commands/UnbanCmd.ts b/backend/src/plugins/ModActions/commands/UnbanCmd.ts index 53363ee0..d232f4e4 100644 --- a/backend/src/plugins/ModActions/commands/UnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnbanCmd.ts @@ -9,13 +9,13 @@ import { resolveUser } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; import { ignoreEvent } from "../functions/ignoreEvent"; -import { IgnoredEventType, modActionsCmd } from "../types"; +import { IgnoredEventType, modActionsMsgCmd } from "../types"; const opts = { mod: ct.member({ option: true }), }; -export const UnbanCmd = modActionsCmd({ +export const UnbanCmd = modActionsMsgCmd({ trigger: "unban", permission: "can_unban", description: "Unban the specified member", diff --git a/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts b/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts index 9fe9e208..7c6eb774 100644 --- a/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts @@ -1,8 +1,8 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; -export const UnhideCaseCmd = modActionsCmd({ +export const UnhideCaseCmd = modActionsMsgCmd({ trigger: ["unhide", "unhidecase", "unhide_case"], permission: "can_hidecase", description: "Un-hide the specified case, making it appear in !cases and !info again", diff --git a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts b/backend/src/plugins/ModActions/commands/UnmuteCmd.ts index 55c84631..3a4171ac 100644 --- a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/UnmuteCmd.ts @@ -5,13 +5,13 @@ import { resolveMember, resolveUser } from "../../../utils"; import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; import { actualUnmuteCmd } from "../functions/actualUnmuteUserCmd"; import { isBanned } from "../functions/isBanned"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; const opts = { mod: ct.member({ option: true }), }; -export const UnmuteCmd = modActionsCmd({ +export const UnmuteCmd = modActionsMsgCmd({ trigger: "unmute", permission: "can_mute", description: "Unmute the specified member", diff --git a/backend/src/plugins/ModActions/commands/UpdateCmd.ts b/backend/src/plugins/ModActions/commands/UpdateCmd.ts index 3310522e..59c68b0d 100644 --- a/backend/src/plugins/ModActions/commands/UpdateCmd.ts +++ b/backend/src/plugins/ModActions/commands/UpdateCmd.ts @@ -1,8 +1,8 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { updateCase } from "../functions/updateCase"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; -export const UpdateCmd = modActionsCmd({ +export const UpdateCmd = modActionsMsgCmd({ trigger: ["update", "reason"], permission: "can_note", description: diff --git a/backend/src/plugins/ModActions/commands/WarnCmd.ts b/backend/src/plugins/ModActions/commands/WarnCmd.ts index c8192015..2b3121fd 100644 --- a/backend/src/plugins/ModActions/commands/WarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/WarnCmd.ts @@ -8,9 +8,9 @@ import { formatReasonWithAttachments } from "../functions/formatReasonWithAttach import { isBanned } from "../functions/isBanned"; import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; import { warnMember } from "../functions/warnMember"; -import { modActionsCmd } from "../types"; +import { modActionsMsgCmd } from "../types"; -export const WarnCmd = modActionsCmd({ +export const WarnCmd = modActionsMsgCmd({ trigger: "warn", permission: "can_warn", description: "Send a warning to the specified user", diff --git a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts new file mode 100644 index 00000000..c7122fe9 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts @@ -0,0 +1,31 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { sendErrorMessage } from "../../../../pluginUtils"; +import { resolveUser } from "../../../../utils"; +import { actualNoteCmd } from "../../functions/actualNoteCmd"; +import { modActionsMsgCmd } from "../../types"; + +export const NoteMsgCmd = modActionsMsgCmd({ + trigger: "note", + permission: "can_note", + description: "Add a note to the specified user", + + signature: { + user: ct.string(), + note: ct.string({ required: false, catchAll: true }), + }, + + async run({ pluginData, message: msg, args }) { + const user = await resolveUser(pluginData.client, args.user); + if (!user.id) { + sendErrorMessage(pluginData, msg.channel, `User not found`); + return; + } + + if (!args.note && msg.attachments.size === 0) { + sendErrorMessage(pluginData, msg.channel, "Text or attachment required"); + return; + } + + actualNoteCmd(pluginData, msg.channel, msg.author, [...msg.attachments.values()], user, args.note || ""); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts new file mode 100644 index 00000000..82b38be7 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts @@ -0,0 +1,45 @@ +import { ApplicationCommandOptionType, ChatInputCommandInteraction } from "discord.js"; +import { slashOptions } from "knub"; +import { sendErrorMessage } from "../../../../pluginUtils"; +import { actualNoteCmd } from "../../functions/actualNoteCmd"; + +export const NoteSlashCmd = { + name: "note", + description: "Add a note to the specified user", + allowDms: false, + configPermission: "can_note", + + signature: [ + slashOptions.user({ name: "user", description: "The user to add a note to", required: true }), + slashOptions.string({ name: "note", description: "The note to add to the user", required: false }), + ...new Array(10).fill(0).map((_, i) => { + return { + name: `attachment${i + 1}`, + description: "An attachment to add to the note", + type: ApplicationCommandOptionType.Attachment, + required: false, + resolveValue: (interaction: ChatInputCommandInteraction) => { + return interaction.options.getAttachment(`attachment${i + 1}`); + }, + getExtraAPIProps: () => ({}), + }; + }), + ], + + async run({ interaction, options, pluginData }) { + const attachments = new Array(10) + .fill(0) + .map((_, i) => { + return options[`attachment${i + 1}`]; + }) + .filter((a) => a); + + if ((!options.note || options.note.trim() === "") && attachments.length < 1) { + sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + actualNoteCmd(pluginData, interaction, interaction.user, attachments, options.user, options.note || ""); + }, +}; diff --git a/backend/src/plugins/ModActions/functions/actualNoteCmd.ts b/backend/src/plugins/ModActions/functions/actualNoteCmd.ts new file mode 100644 index 00000000..524a182c --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualNoteCmd.ts @@ -0,0 +1,47 @@ +import { Attachment, ChatInputCommandInteraction, TextBasedChannel, User } from "discord.js"; +import { GuildPluginData } from "knub"; +import { CaseTypes } from "../../../data/CaseTypes"; +import { sendSuccessMessage } from "../../../pluginUtils"; +import { UnknownUser, renderUserUsername } from "../../../utils"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { ModActionsPluginType } from "../types"; +import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; + +export async function actualNoteCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + author: User, + attachments: Array, + user: User | UnknownUser, + note: string, +) { + const userName = renderUserUsername(user); + const reason = formatReasonWithAttachments(note, attachments); + + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const createdCase = await casesPlugin.createCase({ + userId: user.id, + modId: author.id, + type: CaseTypes.Note, + reason, + }); + + pluginData.getPlugin(LogsPlugin).logMemberNote({ + mod: author, + user, + caseNumber: createdCase.case_number, + reason, + }); + + sendSuccessMessage( + pluginData, + context, + `Note added on **${userName}** (Case #${createdCase.case_number})`, + undefined, + undefined, + true, + ); + + pluginData.state.events.emit("note", user.id, reason); +} diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index 447b9638..c6c1fe70 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -1,7 +1,7 @@ import { GuildTextBasedChannel } from "discord.js"; import { EventEmitter } from "events"; import * as t from "io-ts"; -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, guildPluginSlashGroup } from "knub"; import { Queue } from "../../Queue"; import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; @@ -147,5 +147,6 @@ export interface BanOptions { export type ModActionType = "note" | "warn" | "mute" | "unmute" | "kick" | "ban" | "unban"; -export const modActionsCmd = guildPluginMessageCommand(); +export const modActionsMsgCmd = guildPluginMessageCommand(); +export const modActionsSlashGroup = guildPluginSlashGroup(); export const modActionsEvt = guildPluginEventListener(); diff --git a/backend/src/plugins/availablePlugins.ts b/backend/src/plugins/availablePlugins.ts index 3df9c347..45119f0f 100644 --- a/backend/src/plugins/availablePlugins.ts +++ b/backend/src/plugins/availablePlugins.ts @@ -53,8 +53,8 @@ export const guildPlugins: Array> = [ PostPlugin, ReactionRolesPlugin, MessageSaverPlugin, - // GuildMemberCachePlugin, // FIXME: New caching thing, or fix deadlocks with this plugin ModActionsPlugin, + // GuildMemberCachePlugin, // FIXME: New caching thing, or fix deadlocks with this plugin NameHistoryPlugin, RemindersPlugin, RolesPlugin, From a4c4b17a1458ba6f558357fbf4122cd4d5fcc5aa Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Wed, 14 Feb 2024 09:17:11 +0100 Subject: [PATCH 11/30] =?UTF-8?q?feat:=20first=20batch=20of=20emojis=20?= =?UTF-8?q?=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/package-lock.json | 30 +- backend/src/data/GuildCases.ts | 37 ++- backend/src/pluginUtils.ts | 28 +- .../Cases/functions/getRecentCasesByMod.ts | 4 +- .../Cases/functions/getTotalCasesByMod.ts | 10 +- .../plugins/ModActions/ModActionsPlugin.ts | 126 ++++++--- .../plugins/ModActions/commands/AddCaseCmd.ts | 93 ------- .../src/plugins/ModActions/commands/BanCmd.ts | 225 --------------- .../plugins/ModActions/commands/CaseCmd.ts | 29 -- .../ModActions/commands/CasesModCmd.ts | 81 ------ .../ModActions/commands/CasesUserCmd.ts | 139 ---------- .../ModActions/commands/DeleteCaseCmd.ts | 98 ------- .../ModActions/commands/ForcebanCmd.ts | 103 ------- .../ModActions/commands/ForcemuteCmd.ts | 51 ---- .../ModActions/commands/HideCaseCmd.ts | 45 --- .../plugins/ModActions/commands/KickCmd.ts | 29 -- .../plugins/ModActions/commands/MassBanCmd.ts | 156 ----------- .../ModActions/commands/MassUnbanCmd.ts | 125 --------- .../ModActions/commands/MassmuteCmd.ts | 105 ------- .../ModActions/commands/SoftbanCommand.ts | 35 --- .../plugins/ModActions/commands/UnbanCmd.ts | 90 ------ .../ModActions/commands/UnhideCaseCmd.ts | 45 --- .../plugins/ModActions/commands/WarnCmd.ts | 112 -------- .../commands/addcase/AddCaseMsgCmd.ts | 63 +++++ .../commands/addcase/AddCaseSlashCmd.ts | 65 +++++ .../ModActions/commands/ban/BanMsgCmd.ts | 75 +++++ .../ModActions/commands/ban/BanSlashCmd.ts | 98 +++++++ .../ModActions/commands/case/CaseMsgCmd.ts | 19 ++ .../ModActions/commands/case/CaseSlashCmd.ts | 17 ++ .../commands/cases/CasesModMsgCmd.ts | 47 ++++ .../commands/cases/CasesSlashCmd.ts | 48 ++++ .../commands/cases/CasesUserMsgCmd.ts | 57 ++++ .../plugins/ModActions/commands/constants.ts | 2 + .../commands/deletecase/DeleteCaseMsgCmd.ts | 23 ++ .../commands/deletecase/DeleteCaseSlashCmd.ts | 27 ++ .../commands/forceban/ForceBanMsgCmd.ts | 60 ++++ .../commands/forceban/ForceBanSlashCmd.ts | 57 ++++ .../commands/forcemute/ForceMuteMsgCmd.ts | 84 ++++++ .../commands/forcemute/ForceMuteSlashCmd.ts | 95 +++++++ .../ForceUnmuteMsgCmd.ts} | 37 ++- .../forceunmute/ForceUnmuteSlashCmd.ts | 60 ++++ .../commands/hidecase/HideCaseMsgCmd.ts | 19 ++ .../commands/hidecase/HideCaseSlashCmd.ts | 17 ++ .../ModActions/commands/kick/KickMsgCmd.ts | 68 +++++ .../ModActions/commands/kick/KickSlashCmd.ts | 91 ++++++ .../commands/massban/MassBanMsgCmd.ts | 19 ++ .../commands/massban/MassBanSlashCmd.ts | 15 + .../commands/massmute/MassMuteMsgCmd.ts | 19 ++ .../commands/massmute/MassMuteSlashCmd.ts | 15 + .../commands/massunban/MassUnbanMsgCmd.ts | 19 ++ .../commands/massunban/MassUnbanSlashCmd.ts | 15 + .../{MuteCmd.ts => mute/MuteMsgCmd.ts} | 51 +++- .../ModActions/commands/mute/MuteSlashCmd.ts | 130 +++++++++ .../ModActions/commands/note/NoteMsgCmd.ts | 2 +- .../ModActions/commands/note/NoteSlashCmd.ts | 39 +-- .../ModActions/commands/unban/UnbanMsgCmd.ts | 45 +++ .../commands/unban/UnbanSlashCmd.ts | 50 ++++ .../commands/unhidecase/UnhideCaseMsgCmd.ts | 19 ++ .../commands/unhidecase/UnhideCaseSlashCmd.ts | 17 ++ .../{UnmuteCmd.ts => unmute/UnmuteMsgCmd.ts} | 43 ++- .../commands/unmute/UnmuteSlashCmd.ts | 108 ++++++++ .../{UpdateCmd.ts => update/UpdateMsgCmd.ts} | 10 +- .../commands/update/UpdateSlashCmd.ts | 33 +++ .../ModActions/commands/warn/WarnMsgCmd.ts | 79 ++++++ .../ModActions/commands/warn/WarnSlashCmd.ts | 105 +++++++ .../actualCommands/actualAddCaseCmd.ts | 55 ++++ .../functions/actualCommands/actualBanCmd.ts | 182 ++++++++++++ .../functions/actualCommands/actualCaseCmd.ts | 24 ++ .../actualCommands/actualCasesCmd.ts | 258 ++++++++++++++++++ .../actualCommands/actualDeleteCaseCmd.ts | 95 +++++++ .../actualCommands/actualForceBanCmd.ts | 60 ++++ .../actualCommands/actualHideCaseCmd.ts | 38 +++ .../functions/actualCommands/actualKickCmd.ts | 89 ++++++ .../actualCommands/actualMassBanCmd.ts | 163 +++++++++++ .../actualCommands/actualMassMuteCmd.ts | 110 ++++++++ .../actualCommands/actualMassUnbanCmd.ts | 127 +++++++++ .../functions/actualCommands/actualMuteCmd.ts | 96 +++++++ .../{ => actualCommands}/actualNoteCmd.ts | 14 +- .../actualCommands/actualUnbanCmd.ts | 63 +++++ .../actualCommands/actualUnhideCaseCmd.ts | 39 +++ .../actualCommands/actualUnmuteCmd.ts | 55 ++++ .../functions/actualCommands/actualWarnCmd.ts | 61 +++++ .../functions/actualKickMemberCmd.ts | 110 -------- .../ModActions/functions/actualMuteUserCmd.ts | 114 -------- .../functions/actualUnmuteUserCmd.ts | 65 ----- .../ModActions/functions/updateCase.ts | 41 +-- .../ModActions/functions/warnMember.ts | 30 +- backend/src/plugins/ModActions/types.ts | 4 +- backend/src/utils/createPaginatedMessage.ts | 6 +- backend/src/utils/multipleSlashOptions.ts | 20 ++ backend/src/utils/waitForInteraction.ts | 14 +- 91 files changed, 3659 insertions(+), 2032 deletions(-) delete mode 100644 backend/src/plugins/ModActions/commands/AddCaseCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/BanCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/CaseCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/CasesModCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/CasesUserCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/ForcebanCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/ForcemuteCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/HideCaseCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/KickCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/MassBanCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/MassUnbanCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/MassmuteCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/SoftbanCommand.ts delete mode 100644 backend/src/plugins/ModActions/commands/UnbanCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts delete mode 100644 backend/src/plugins/ModActions/commands/WarnCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/constants.ts create mode 100644 backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts rename backend/src/plugins/ModActions/commands/{ForceunmuteCmd.ts => forceunmute/ForceUnmuteMsgCmd.ts} (55%) create mode 100644 backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts rename backend/src/plugins/ModActions/commands/{MuteCmd.ts => mute/MuteMsgCmd.ts} (56%) create mode 100644 backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts rename backend/src/plugins/ModActions/commands/{UnmuteCmd.ts => unmute/UnmuteMsgCmd.ts} (65%) create mode 100644 backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts rename backend/src/plugins/ModActions/commands/{UpdateCmd.ts => update/UpdateMsgCmd.ts} (57%) create mode 100644 backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts create mode 100644 backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts rename backend/src/plugins/ModActions/functions/{ => actualCommands}/actualNoteCmd.ts (71%) create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts create mode 100644 backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts delete mode 100644 backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts delete mode 100644 backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts delete mode 100644 backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts create mode 100644 backend/src/utils/multipleSlashOptions.ts diff --git a/backend/package-lock.json b/backend/package-lock.json index 2949ed98..daf05930 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -5520,9 +5520,9 @@ } }, "node_modules/knub": { - "version": "32.0.0-next.16", - "resolved": "https://registry.npmjs.org/knub/-/knub-32.0.0-next.16.tgz", - "integrity": "sha512-lmjbLusvinWCoyo0T3dtWy6PEuqysIcqQvg85W85th59ubHasnTc+KGR+4o6EgLCzuDUtc4dP1XQk7XAIKnkYQ==", + "version": "32.0.0-next.17", + "resolved": "https://registry.npmjs.org/knub/-/knub-32.0.0-next.17.tgz", + "integrity": "sha512-q8PeIJuOYUQySOmVuXF56ykklKRnnJmAMpfSN1+vWCNhdMsDxIPZAkRpvekQD6oBkYoL7WlzEsMoUsECGZp+QQ==", "dependencies": { "discord.js": "^14.11.0", "knub-command-manager": "^9.1.0", @@ -9228,11 +9228,16 @@ } }, "node_modules/ts-essentials": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-9.3.2.tgz", - "integrity": "sha512-JxKJzuWqH1MmH4ZFHtJzGEhkfN3QvVR3C3w+4BIoWeoY68UVVoA2Np/Bca9z0IPSErVCWhv439aT0We4Dks8kQ==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-9.4.1.tgz", + "integrity": "sha512-oke0rI2EN9pzHsesdmrOrnqv1eQODmJpd/noJjwj2ZPC3Z4N2wbjrOEqnsEgmvlO2+4fBb0a794DCna2elEVIQ==", "peerDependencies": { "typescript": ">=4.1.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/ts-mixer": { @@ -9645,19 +9650,6 @@ "node": ">=12" } }, - "node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/uid2": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.4.tgz", diff --git a/backend/src/data/GuildCases.ts b/backend/src/data/GuildCases.ts index eb5ed6b7..4137fbee 100644 --- a/backend/src/data/GuildCases.ts +++ b/backend/src/data/GuildCases.ts @@ -1,4 +1,5 @@ import { In, InsertResult, Repository } from "typeorm"; +import { FindOptionsWhere } from "typeorm/find-options/FindOptionsWhere"; import { Queue } from "../Queue"; import { chunkArray } from "../utils"; import { BaseGuildRepository } from "./BaseGuildRepository"; @@ -73,12 +74,16 @@ export class GuildCases extends BaseGuildRepository { }); } - async getByUserId(userId: string): Promise { + async getByUserId( + userId: string, + filters: Omit, "guild_id" | "user_id"> = {}, + ): Promise { return this.cases.find({ relations: this.getRelations(), where: { guild_id: this.guildId, user_id: userId, + ...filters, }, }); } @@ -98,24 +103,40 @@ export class GuildCases extends BaseGuildRepository { }); } - async getTotalCasesByModId(modId: string): Promise { + async getTotalCasesByModId( + modId: string, + filters: Omit, "guild_id" | "mod_id" | "is_hidden"> = {}, + ): Promise { return this.cases.count({ where: { guild_id: this.guildId, mod_id: modId, is_hidden: false, + ...filters, }, }); } - async getRecentByModId(modId: string, count: number, skip = 0): Promise { + async getRecentByModId( + modId: string, + count: number, + skip = 0, + filters: Omit, "guild_id" | "mod_id"> = {}, + ): Promise { + const where: FindOptionsWhere = { + guild_id: this.guildId, + mod_id: modId, + is_hidden: false, + ...filters, + }; + + if (where.is_hidden === true) { + delete where.is_hidden; + } + return this.cases.find({ relations: this.getRelations(), - where: { - guild_id: this.guildId, - mod_id: modId, - is_hidden: false, - }, + where, skip, take: count, order: { diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index 7ae53217..9736c9fe 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -11,6 +11,7 @@ import { ModalSubmitInteraction, PermissionsBitField, TextBasedChannel, + User, } from "discord.js"; import * as t from "io-ts"; import { @@ -101,19 +102,32 @@ export function makeIoTsConfigParser>(schema: Schema) }; } -function isContextInteraction( - context: TextBasedChannel | ChatInputCommandInteraction, +export function isContextInteraction( + context: TextBasedChannel | User | ChatInputCommandInteraction, ): context is ChatInputCommandInteraction { return "commandId" in context && !!context.commandId; } +export function sendContextResponse( + context: TextBasedChannel | User | ChatInputCommandInteraction, + response: string | Omit, +): Promise { + if (isContextInteraction(context)) { + const options = { ...(typeof response === "string" ? { content: response } : response), fetchReply: true }; + + return (context.replied ? context.followUp(options) : context.reply(options)) as Promise; + } else { + return context.send(response); + } +} + export async function sendSuccessMessage( pluginData: AnyPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: TextBasedChannel | User | ChatInputCommandInteraction, body: string, allowedMentions?: MessageMentionOptions, responseInteraction?: ModalSubmitInteraction, - ephemeral = false, + ephemeral = true, ): Promise { const emoji = pluginData.fullConfig.success_emoji || undefined; const formattedBody = successMessage(body, emoji); @@ -153,12 +167,12 @@ export async function sendSuccessMessage( logger.error(`Context reply failed: ${err}`); return undefined; - }); + }) as Promise; } export async function sendErrorMessage( pluginData: AnyPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: TextBasedChannel | User | ChatInputCommandInteraction, body: string, allowedMentions?: MessageMentionOptions, responseInteraction?: ModalSubmitInteraction, @@ -201,7 +215,7 @@ export async function sendErrorMessage( logger.error(`Context reply failed: ${err}`); return undefined; - }); + }) as Promise; } export function getBaseUrl(pluginData: AnyPluginData) { diff --git a/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts b/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts index b9988078..e482fbd6 100644 --- a/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts +++ b/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts @@ -1,4 +1,5 @@ import { GuildPluginData } from "knub"; +import { FindOptionsWhere } from "typeorm/find-options/FindOptionsWhere"; import { Case } from "../../../data/entities/Case"; import { CasesPluginType } from "../types"; @@ -7,6 +8,7 @@ export function getRecentCasesByMod( modId: string, count: number, skip = 0, + filters: Omit, "guild_id" | "mod_id" | "is_hidden"> = {}, ): Promise { - return pluginData.state.cases.getRecentByModId(modId, count, skip); + return pluginData.state.cases.getRecentByModId(modId, count, skip, filters); } diff --git a/backend/src/plugins/Cases/functions/getTotalCasesByMod.ts b/backend/src/plugins/Cases/functions/getTotalCasesByMod.ts index 5753f12e..235f2d8a 100644 --- a/backend/src/plugins/Cases/functions/getTotalCasesByMod.ts +++ b/backend/src/plugins/Cases/functions/getTotalCasesByMod.ts @@ -1,6 +1,12 @@ import { GuildPluginData } from "knub"; +import { FindOptionsWhere } from "typeorm/find-options/FindOptionsWhere"; +import { Case } from "../../../data/entities/Case"; import { CasesPluginType } from "../types"; -export function getTotalCasesByMod(pluginData: GuildPluginData, modId: string): Promise { - return pluginData.state.cases.getTotalCasesByModId(modId); +export function getTotalCasesByMod( + pluginData: GuildPluginData, + modId: string, + filters: Omit, "guild_id" | "mod_id" | "is_hidden"> = {}, +): Promise { + return pluginData.state.cases.getTotalCasesByModId(modId, filters); } diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index 57b2709e..d9b08381 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -13,29 +13,47 @@ import { LogsPlugin } from "../Logs/LogsPlugin"; import { MutesPlugin } from "../Mutes/MutesPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; -import { AddCaseCmd } from "./commands/AddCaseCmd"; -import { BanCmd } from "./commands/BanCmd"; -import { CaseCmd } from "./commands/CaseCmd"; -import { CasesModCmd } from "./commands/CasesModCmd"; -import { CasesUserCmd } from "./commands/CasesUserCmd"; -import { DeleteCaseCmd } from "./commands/DeleteCaseCmd"; -import { ForcebanCmd } from "./commands/ForcebanCmd"; -import { ForcemuteCmd } from "./commands/ForcemuteCmd"; -import { ForceUnmuteCmd } from "./commands/ForceunmuteCmd"; -import { HideCaseCmd } from "./commands/HideCaseCmd"; -import { KickCmd } from "./commands/KickCmd"; -import { MassbanCmd } from "./commands/MassBanCmd"; -import { MassunbanCmd } from "./commands/MassUnbanCmd"; -import { MassmuteCmd } from "./commands/MassmuteCmd"; -import { MuteCmd } from "./commands/MuteCmd"; -import { SoftbanCmd } from "./commands/SoftbanCommand"; -import { UnbanCmd } from "./commands/UnbanCmd"; -import { UnhideCaseCmd } from "./commands/UnhideCaseCmd"; -import { UnmuteCmd } from "./commands/UnmuteCmd"; -import { UpdateCmd } from "./commands/UpdateCmd"; -import { WarnCmd } from "./commands/WarnCmd"; +import { AddCaseMsgCmd } from "./commands/addcase/AddCaseMsgCmd"; +import { AddCaseSlashCmd } from "./commands/addcase/AddCaseSlashCmd"; +import { BanMsgCmd } from "./commands/ban/BanMsgCmd"; +import { BanSlashCmd } from "./commands/ban/BanSlashCmd"; +import { CaseMsgCmd } from "./commands/case/CaseMsgCmd"; +import { CaseSlashCmd } from "./commands/case/CaseSlashCmd"; +import { CasesModMsgCmd } from "./commands/cases/CasesModMsgCmd"; +import { CasesSlashCmd } from "./commands/cases/CasesSlashCmd"; +import { CasesUserMsgCmd } from "./commands/cases/CasesUserMsgCmd"; +import { DeleteCaseMsgCmd } from "./commands/deletecase/DeleteCaseMsgCmd"; +import { DeleteCaseSlashCmd } from "./commands/deletecase/DeleteCaseSlashCmd"; +import { ForceBanMsgCmd } from "./commands/forceban/ForceBanMsgCmd"; +import { ForceBanSlashCmd } from "./commands/forceban/ForceBanSlashCmd"; +import { ForceMuteMsgCmd } from "./commands/forcemute/ForceMuteMsgCmd"; +import { ForceMuteSlashCmd } from "./commands/forcemute/ForceMuteSlashCmd"; +import { ForceUnmuteMsgCmd } from "./commands/forceunmute/ForceUnmuteMsgCmd"; +import { ForceUnmuteSlashCmd } from "./commands/forceunmute/ForceUnmuteSlashCmd"; +import { HideCaseMsgCmd } from "./commands/hidecase/HideCaseMsgCmd"; +import { HideCaseSlashCmd } from "./commands/hidecase/HideCaseSlashCmd"; +import { KickMsgCmd } from "./commands/kick/KickMsgCmd"; +import { KickSlashCmd } from "./commands/kick/KickSlashCmd"; +import { MassBanMsgCmd } from "./commands/massban/MassBanMsgCmd"; +import { MassBanSlashCmd } from "./commands/massban/MassBanSlashCmd"; +import { MassMuteMsgCmd } from "./commands/massmute/MassMuteMsgCmd"; +import { MassMuteSlashSlashCmd } from "./commands/massmute/MassMuteSlashCmd"; +import { MassUnbanMsgCmd } from "./commands/massunban/MassUnbanMsgCmd"; +import { MassUnbanSlashCmd } from "./commands/massunban/MassUnbanSlashCmd"; +import { MuteMsgCmd } from "./commands/mute/MuteMsgCmd"; +import { MuteSlashCmd } from "./commands/mute/MuteSlashCmd"; import { NoteMsgCmd } from "./commands/note/NoteMsgCmd"; import { NoteSlashCmd } from "./commands/note/NoteSlashCmd"; +import { UnbanMsgCmd } from "./commands/unban/UnbanMsgCmd"; +import { UnbanSlashCmd } from "./commands/unban/UnbanSlashCmd"; +import { UnhideCaseMsgCmd } from "./commands/unhidecase/UnhideCaseMsgCmd"; +import { UnhideCaseSlashCmd } from "./commands/unhidecase/UnhideCaseSlashCmd"; +import { UnmuteMsgCmd } from "./commands/unmute/UnmuteMsgCmd"; +import { UnmuteSlashCmd } from "./commands/unmute/UnmuteSlashCmd"; +import { UpdateMsgCmd } from "./commands/update/UpdateMsgCmd"; +import { UpdateSlashCmd } from "./commands/update/UpdateSlashCmd"; +import { WarnMsgCmd } from "./commands/warn/WarnMsgCmd"; +import { WarnSlashCmd } from "./commands/warn/WarnSlashCmd"; import { AuditLogEvents } from "./events/AuditLogEvents"; import { CreateBanCaseOnManualBanEvt } from "./events/CreateBanCaseOnManualBanEvt"; import { CreateUnbanCaseOnManualUnbanEvt } from "./events/CreateUnbanCaseOnManualUnbanEvt"; @@ -148,33 +166,53 @@ export const ModActionsPlugin = zeppelinGuildPlugin()({ name: "mod", description: "Moderation actions", defaultMemberPermissions: "0", - subcommands: [{ type: "slash", ...NoteSlashCmd }], + subcommands: [ + { type: "slash", ...AddCaseSlashCmd }, + { type: "slash", ...BanSlashCmd }, + { type: "slash", ...CaseSlashCmd }, + { type: "slash", ...CasesSlashCmd }, + { type: "slash", ...DeleteCaseSlashCmd }, + { type: "slash", ...ForceBanSlashCmd }, + { type: "slash", ...ForceMuteSlashCmd }, + { type: "slash", ...ForceUnmuteSlashCmd }, + { type: "slash", ...HideCaseSlashCmd }, + { type: "slash", ...KickSlashCmd }, + { type: "slash", ...MassBanSlashCmd }, + { type: "slash", ...MassMuteSlashSlashCmd }, + { type: "slash", ...MassUnbanSlashCmd }, + { type: "slash", ...MuteSlashCmd }, + { type: "slash", ...NoteSlashCmd }, + { type: "slash", ...UnbanSlashCmd }, + { type: "slash", ...UnhideCaseSlashCmd }, + { type: "slash", ...UnmuteSlashCmd }, + { type: "slash", ...UpdateSlashCmd }, + { type: "slash", ...WarnSlashCmd }, + ], }), ], messageCommands: [ - UpdateCmd, + UpdateMsgCmd, NoteMsgCmd, - WarnCmd, - MuteCmd, - ForcemuteCmd, - UnmuteCmd, - ForceUnmuteCmd, - KickCmd, - SoftbanCmd, - BanCmd, - UnbanCmd, - ForcebanCmd, - MassbanCmd, - MassmuteCmd, - MassunbanCmd, - AddCaseCmd, - CaseCmd, - CasesUserCmd, - CasesModCmd, - HideCaseCmd, - UnhideCaseCmd, - DeleteCaseCmd, + WarnMsgCmd, + MuteMsgCmd, + ForceMuteMsgCmd, + UnmuteMsgCmd, + ForceUnmuteMsgCmd, + KickMsgCmd, + BanMsgCmd, + UnbanMsgCmd, + ForceBanMsgCmd, + MassBanMsgCmd, + MassMuteMsgCmd, + MassUnbanMsgCmd, + AddCaseMsgCmd, + CaseMsgCmd, + CasesUserMsgCmd, + CasesModMsgCmd, + HideCaseMsgCmd, + UnhideCaseMsgCmd, + DeleteCaseMsgCmd, ], public: { @@ -198,7 +236,7 @@ export const ModActionsPlugin = zeppelinGuildPlugin()({ updateCase(pluginData) { return (msg: Message, caseNumber: number | null, note: string) => { - updateCase(pluginData, msg, { caseNumber, note }); + updateCase(pluginData, msg.channel, msg.author, caseNumber ?? undefined, note, [...msg.attachments.values()]); }; }, diff --git a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts b/backend/src/plugins/ModActions/commands/AddCaseCmd.ts deleted file mode 100644 index dc8df97f..00000000 --- a/backend/src/plugins/ModActions/commands/AddCaseCmd.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { Case } from "../../../data/entities/Case"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { renderUserUsername, resolveMember, resolveUser } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { modActionsMsgCmd } from "../types"; - -const opts = { - mod: ct.member({ option: true }), -}; - -export const AddCaseCmd = modActionsMsgCmd({ - trigger: "addcase", - permission: "can_addcase", - description: "Add an arbitrary case to the specified user without taking any action", - - signature: [ - { - type: ct.string(), - user: ct.string(), - reason: ct.string({ required: false, catchAll: true }), - - ...opts, - }, - ], - - async run({ pluginData, message: msg, args }) { - const user = await resolveUser(pluginData.client, args.user); - if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); - return; - } - - // If the user exists as a guild member, make sure we can act on them first - const member = await resolveMember(pluginData.client, pluginData.guild, user.id); - if (member && !canActOn(pluginData, msg.member, member)) { - sendErrorMessage(pluginData, msg.channel, "Cannot add case on this user: insufficient permissions"); - return; - } - - // The moderator who did the action is the message author or, if used, the specified -mod - let mod = msg.member; - if (args.mod) { - if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); - return; - } - - mod = args.mod; - } - - // Verify the case type is valid - const type: string = args.type[0].toUpperCase() + args.type.slice(1).toLowerCase(); - if (!CaseTypes[type]) { - sendErrorMessage(pluginData, msg.channel, "Cannot add case: invalid case type"); - return; - } - - const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]); - - // Create the case - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const theCase: Case = await casesPlugin.createCase({ - userId: user.id, - modId: mod.id, - type: CaseTypes[type], - reason, - ppId: mod.id !== msg.author.id ? msg.author.id : undefined, - }); - - if (user) { - sendSuccessMessage( - pluginData, - msg.channel, - `Case #${theCase.case_number} created for **${renderUserUsername(user)}**`, - ); - } else { - sendSuccessMessage(pluginData, msg.channel, `Case #${theCase.case_number} created`); - } - - // Log the action - pluginData.getPlugin(LogsPlugin).logCaseCreate({ - mod: mod.user, - userId: user.id, - caseNum: theCase.case_number, - caseType: type.toUpperCase(), - reason, - }); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/BanCmd.ts b/backend/src/plugins/ModActions/commands/BanCmd.ts deleted file mode 100644 index f0a20d5f..00000000 --- a/backend/src/plugins/ModActions/commands/BanCmd.ts +++ /dev/null @@ -1,225 +0,0 @@ -import humanizeDuration from "humanize-duration"; -import { getMemberLevel } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { clearExpiringTempban, registerExpiringTempban } from "../../../data/loops/expiringTempbansLoop"; -import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { renderUserUsername, resolveMember, resolveUser } from "../../../utils"; -import { banLock } from "../../../utils/lockNameHelpers"; -import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { banUserId } from "../functions/banUserId"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { isBanned } from "../functions/isBanned"; -import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; -import { modActionsMsgCmd } from "../types"; - -const opts = { - mod: ct.member({ option: true }), - notify: ct.string({ option: true }), - "notify-channel": ct.textChannel({ option: true }), - "delete-days": ct.number({ option: true, shortcut: "d" }), -}; - -export const BanCmd = modActionsMsgCmd({ - trigger: "ban", - permission: "can_ban", - description: "Ban or Tempban the specified member", - - signature: [ - { - user: ct.string(), - time: ct.delay(), - reason: ct.string({ required: false, catchAll: true }), - - ...opts, - }, - { - user: ct.string(), - reason: ct.string({ required: false, catchAll: true }), - - ...opts, - }, - ], - - async run({ pluginData, message: msg, args }) { - const user = await resolveUser(pluginData.client, args.user); - - if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); - return; - } - - const memberToBan = await resolveMember(pluginData.client, pluginData.guild, user.id); - // The moderator who did the action is the message author or, if used, the specified -mod - let mod = msg.member; - if (args.mod) { - if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg, channelId: msg.channel.id }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); - return; - } - - mod = args.mod; - } - - const time = args["time"] ? args["time"] : null; - const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]); - - // acquire a lock because of the needed user-inputs below (if banned/not on server) - const lock = await pluginData.locks.acquire(banLock(user)); - let forceban = false; - const existingTempban = await pluginData.state.tempbans.findExistingTempbanForUserId(user.id); - - if (!memberToBan) { - const banned = await isBanned(pluginData, user.id); - - if (!banned) { - // Ask the mod if we should upgrade to a forceban as the user is not on the server - const reply = await waitForButtonConfirm( - msg.channel, - { content: "User not on server, forceban instead?" }, - { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, - ); - - if (!reply) { - sendErrorMessage(pluginData, msg.channel, "User not on server, ban cancelled by moderator"); - lock.unlock(); - return; - } else { - forceban = true; - } - } - - // Abort if trying to ban user indefinitely if they are already banned indefinitely - if (!existingTempban && !time) { - sendErrorMessage(pluginData, msg.channel, `User is already banned indefinitely.`); - return; - } - - // Ask the mod if we should update the existing ban - const reply = await waitForButtonConfirm( - msg.channel, - { content: "Failed to message the user. Log the warning anyway?" }, - { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, - ); - - if (!reply) { - sendErrorMessage(pluginData, msg.channel, "User already banned, update cancelled by moderator"); - lock.unlock(); - return; - } - - // Update or add new tempban / remove old tempban - if (time && time > 0) { - if (existingTempban) { - await pluginData.state.tempbans.updateExpiryTime(user.id, time, mod.id); - } else { - await pluginData.state.tempbans.addTempban(user.id, time, mod.id); - } - const tempban = (await pluginData.state.tempbans.findExistingTempbanForUserId(user.id))!; - registerExpiringTempban(tempban); - } else if (existingTempban) { - clearExpiringTempban(existingTempban); - pluginData.state.tempbans.clear(user.id); - } - - // Create a new case for the updated ban since we never stored the old case id and log the action - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const createdCase = await casesPlugin.createCase({ - modId: mod.id, - type: CaseTypes.Ban, - userId: user.id, - reason, - noteDetails: [`Ban updated to ${time ? humanizeDuration(time) : "indefinite"}`], - }); - if (time) { - pluginData.getPlugin(LogsPlugin).logMemberTimedBan({ - mod: mod.user, - user, - caseNumber: createdCase.case_number, - reason, - banTime: humanizeDuration(time), - }); - } else { - pluginData.getPlugin(LogsPlugin).logMemberBan({ - mod: mod.user, - user, - caseNumber: createdCase.case_number, - reason, - }); - } - - sendSuccessMessage( - pluginData, - msg.channel, - `Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`, - ); - lock.unlock(); - return; - } - - // Make sure we're allowed to ban this member if they are on the server - if (!forceban && !canActOn(pluginData, msg.member, memberToBan!)) { - const ourLevel = getMemberLevel(pluginData, msg.member); - const targetLevel = getMemberLevel(pluginData, memberToBan!); - sendErrorMessage( - pluginData, - msg.channel, - `Cannot ban: target permission level is equal or higher to yours, ${targetLevel} >= ${ourLevel}`, - ); - lock.unlock(); - return; - } - - let contactMethods; - try { - contactMethods = readContactMethodsFromArgs(args); - } catch (e) { - sendErrorMessage(pluginData, msg.channel, e.message); - lock.unlock(); - return; - } - - const deleteMessageDays = - args["delete-days"] ?? (await pluginData.config.getForMessage(msg)).ban_delete_message_days; - const banResult = await banUserId( - pluginData, - user.id, - reason, - { - contactMethods, - caseArgs: { - modId: mod.id, - ppId: mod.id !== msg.author.id ? msg.author.id : undefined, - }, - deleteMessageDays, - modId: mod.id, - }, - time, - ); - - if (banResult.status === "failed") { - sendErrorMessage(pluginData, msg.channel, `Failed to ban member: ${banResult.error}`); - lock.unlock(); - return; - } - - let forTime = ""; - if (time && time > 0) { - forTime = `for ${humanizeDuration(time)} `; - } - - // Confirm the action to the moderator - let response = ""; - if (!forceban) { - response = `Banned **${renderUserUsername(user)}** ${forTime}(Case #${banResult.case.case_number})`; - if (banResult.notifyResult.text) response += ` (${banResult.notifyResult.text})`; - } else { - response = `Member forcebanned ${forTime}(Case #${banResult.case.case_number})`; - } - - lock.unlock(); - sendSuccessMessage(pluginData, msg.channel, response); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/CaseCmd.ts b/backend/src/plugins/ModActions/commands/CaseCmd.ts deleted file mode 100644 index 8a92ed3f..00000000 --- a/backend/src/plugins/ModActions/commands/CaseCmd.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { sendErrorMessage } from "../../../pluginUtils"; -import { modActionsMsgCmd } from "../types"; - -export const CaseCmd = modActionsMsgCmd({ - trigger: "case", - permission: "can_view", - description: "Show information about a specific case", - - signature: [ - { - caseNumber: ct.number(), - }, - ], - - async run({ pluginData, message: msg, args }) { - const theCase = await pluginData.state.cases.findByCaseNumber(args.caseNumber); - - if (!theCase) { - sendErrorMessage(pluginData, msg.channel, "Case not found"); - return; - } - - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const embed = await casesPlugin.getCaseEmbed(theCase.id, msg.author.id); - msg.channel.send(embed); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/CasesModCmd.ts b/backend/src/plugins/ModActions/commands/CasesModCmd.ts deleted file mode 100644 index e07176f5..00000000 --- a/backend/src/plugins/ModActions/commands/CasesModCmd.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { APIEmbed, User } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; -import { emptyEmbedValue, resolveUser, trimLines } from "../../../utils"; -import { asyncMap } from "../../../utils/async"; -import { createPaginatedMessage } from "../../../utils/createPaginatedMessage"; -import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; -import { getGuildPrefix } from "../../../utils/getGuildPrefix"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { modActionsMsgCmd } from "../types"; - -const opts = { - mod: ct.userId({ option: true }), -}; - -const casesPerPage = 5; - -export const CasesModCmd = modActionsMsgCmd({ - trigger: ["cases", "modlogs", "infractions"], - permission: "can_view", - description: "Show the most recent 5 cases by the specified -mod", - - signature: [ - { - ...opts, - }, - ], - - async run({ pluginData, message: msg, args }) { - const modId = args.mod || msg.author.id; - const mod = await resolveUser(pluginData.client, modId); - const modName = mod instanceof User ? mod.tag : modId; - - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const totalCases = await casesPlugin.getTotalCasesByMod(modId); - - if (totalCases === 0) { - sendErrorMessage(pluginData, msg.channel, `No cases by **${modName}**`); - return; - } - - const totalPages = Math.max(Math.ceil(totalCases / casesPerPage), 1); - const prefix = getGuildPrefix(pluginData); - - createPaginatedMessage( - pluginData.client, - msg.channel, - totalPages, - async (page) => { - const cases = await casesPlugin.getRecentCasesByMod(modId, casesPerPage, (page - 1) * casesPerPage); - const lines = await asyncMap(cases, (c) => casesPlugin.getCaseSummary(c, true, msg.author.id)); - - const firstCaseNum = (page - 1) * casesPerPage + 1; - const lastCaseNum = page * casesPerPage; - const title = `Most recent cases ${firstCaseNum}-${lastCaseNum} of ${totalCases} by ${modName}`; - - const embed = { - author: { - name: title, - icon_url: mod instanceof User ? mod.displayAvatarURL() : undefined, - }, - fields: [ - ...getChunkedEmbedFields(emptyEmbedValue, lines.join("\n")), - { - name: emptyEmbedValue, - value: trimLines(` - Use \`${prefix}case \` to see more information about an individual case - Use \`${prefix}cases \` to see a specific user's cases - `), - }, - ], - } satisfies APIEmbed; - - return { embeds: [embed] }; - }, - { - limitToUserId: msg.author.id, - }, - ); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts b/backend/src/plugins/ModActions/commands/CasesUserCmd.ts deleted file mode 100644 index a92ea75d..00000000 --- a/backend/src/plugins/ModActions/commands/CasesUserCmd.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { APIEmbed, User } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { UnknownUser, chunkArray, emptyEmbedValue, renderUserUsername, resolveUser, trimLines } from "../../../utils"; -import { asyncMap } from "../../../utils/async"; -import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; -import { getGuildPrefix } from "../../../utils/getGuildPrefix"; -import { modActionsMsgCmd } from "../types"; - -const opts = { - expand: ct.bool({ option: true, isSwitch: true, shortcut: "e" }), - hidden: ct.bool({ option: true, isSwitch: true, shortcut: "h" }), - reverseFilters: ct.switchOption({ def: false, shortcut: "r" }), - notes: ct.switchOption({ def: false, shortcut: "n" }), - warns: ct.switchOption({ def: false, shortcut: "w" }), - mutes: ct.switchOption({ def: false, shortcut: "m" }), - unmutes: ct.switchOption({ def: false, shortcut: "um" }), - bans: ct.switchOption({ def: false, shortcut: "b" }), - unbans: ct.switchOption({ def: false, shortcut: "ub" }), -}; - -export const CasesUserCmd = modActionsMsgCmd({ - trigger: ["cases", "modlogs"], - permission: "can_view", - description: "Show a list of cases the specified user has", - - signature: [ - { - user: ct.string(), - - ...opts, - }, - ], - - async run({ pluginData, message: msg, args }) { - const user = await resolveUser(pluginData.client, args.user); - if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); - return; - } - - let cases = await pluginData.state.cases.with("notes").getByUserId(user.id); - - const typesToShow: CaseTypes[] = []; - if (args.notes) typesToShow.push(CaseTypes.Note); - if (args.warns) typesToShow.push(CaseTypes.Warn); - if (args.mutes) typesToShow.push(CaseTypes.Mute); - if (args.unmutes) typesToShow.push(CaseTypes.Unmute); - if (args.bans) typesToShow.push(CaseTypes.Ban); - if (args.unbans) typesToShow.push(CaseTypes.Unban); - - if (typesToShow.length > 0) { - // Reversed: Hide specified types - if (args.reverseFilters) cases = cases.filter((c) => !typesToShow.includes(c.type)); - // Normal: Show only specified types - else cases = cases.filter((c) => typesToShow.includes(c.type)); - } - - const normalCases = cases.filter((c) => !c.is_hidden); - const hiddenCases = cases.filter((c) => c.is_hidden); - - const userName = - user instanceof UnknownUser && cases.length ? cases[cases.length - 1].user_name : renderUserUsername(user); - - if (cases.length === 0) { - msg.channel.send(`No cases found for **${userName}**`); - } else { - const casesToDisplay = args.hidden ? cases : normalCases; - if (!casesToDisplay.length) { - msg.channel.send( - `No normal cases found for **${userName}**. Use "-hidden" to show ${cases.length} hidden cases.`, - ); - return; - } - - if (args.expand) { - if (casesToDisplay.length > 8) { - msg.channel.send("Too many cases for expanded view. Please use compact view instead."); - return; - } - - // Expanded view (= individual case embeds) - const casesPlugin = pluginData.getPlugin(CasesPlugin); - for (const theCase of casesToDisplay) { - const embed = await casesPlugin.getCaseEmbed(theCase.id); - msg.channel.send(embed); - } - } else { - // Compact view (= regular message with a preview of each case) - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const lines = await asyncMap(casesToDisplay, (c) => casesPlugin.getCaseSummary(c, true, msg.author.id)); - - const prefix = getGuildPrefix(pluginData); - const linesPerChunk = 10; - const lineChunks = chunkArray(lines, linesPerChunk); - - const footerField = { - name: emptyEmbedValue, - value: trimLines(` - Use \`${prefix}case \` to see more information about an individual case - `), - }; - - for (const [i, linesInChunk] of lineChunks.entries()) { - const isLastChunk = i === lineChunks.length - 1; - - if (isLastChunk && !args.hidden && hiddenCases.length) { - if (hiddenCases.length === 1) { - linesInChunk.push(`*+${hiddenCases.length} hidden case, use "-hidden" to show it*`); - } else { - linesInChunk.push(`*+${hiddenCases.length} hidden cases, use "-hidden" to show them*`); - } - } - - const chunkStart = i * linesPerChunk + 1; - const chunkEnd = Math.min((i + 1) * linesPerChunk, lines.length); - - const embed = { - author: { - name: - lineChunks.length === 1 - ? `Cases for ${userName} (${lines.length} total)` - : `Cases ${chunkStart}–${chunkEnd} of ${lines.length} for ${userName}`, - 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 deleted file mode 100644 index cb3c56d8..00000000 --- a/backend/src/plugins/ModActions/commands/DeleteCaseCmd.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { helpers } from "knub"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { Case } from "../../../data/entities/Case"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { SECONDS, trimLines } from "../../../utils"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { modActionsMsgCmd } from "../types"; - -export const DeleteCaseCmd = modActionsMsgCmd({ - trigger: ["delete_case", "deletecase"], - permission: "can_deletecase", - description: trimLines(` - Delete the specified case. This operation can *not* be reversed. - It is generally recommended to use \`!hidecase\` instead when possible. - `), - - signature: { - caseNumber: ct.number({ rest: true }), - - force: ct.switchOption({ def: false, shortcut: "f" }), - }, - - async run({ pluginData, message, args }) { - const failed: number[] = []; - const validCases: Case[] = []; - let cancelled = 0; - - for (const num of args.caseNumber) { - const theCase = await pluginData.state.cases.findByCaseNumber(num); - if (!theCase) { - failed.push(num); - continue; - } - - validCases.push(theCase); - } - - if (failed.length === args.caseNumber.length) { - sendErrorMessage(pluginData, message.channel, "None of the cases were found!"); - return; - } - - for (const theCase of validCases) { - if (!args.force) { - const cases = pluginData.getPlugin(CasesPlugin); - const embedContent = await cases.getCaseEmbed(theCase); - message.channel.send({ - ...embedContent, - content: "Delete the following case? Answer 'Yes' to continue, 'No' to cancel.", - }); - - 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."); - cancelled++; - continue; - } - } - - const deletedByName = message.author.tag; - - const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); - const deletedAt = timeAndDate.inGuildTz().format(timeAndDate.getDateFormat("pretty_datetime")); - - await pluginData.state.cases.softDelete( - theCase.id, - message.author.id, - deletedByName, - `Case deleted by **${deletedByName}** (\`${message.author.id}\`) on ${deletedAt}`, - ); - - const logs = pluginData.getPlugin(LogsPlugin); - logs.logCaseDelete({ - mod: message.member, - case: theCase, - }); - } - - const failedAddendum = - failed.length > 0 - ? `\nThe following cases were not found: ${failed.toString().replace(new RegExp(",", "g"), ", ")}` - : ""; - const amt = validCases.length - cancelled; - if (amt === 0) { - sendErrorMessage(pluginData, message.channel, "All deletions were cancelled, no cases were deleted."); - return; - } - - sendSuccessMessage( - pluginData, - message.channel, - `${amt} case${amt === 1 ? " was" : "s were"} deleted!${failedAddendum}`, - ); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts b/backend/src/plugins/ModActions/commands/ForcebanCmd.ts deleted file mode 100644 index 251be232..00000000 --- a/backend/src/plugins/ModActions/commands/ForcebanCmd.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { Snowflake } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; -import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { DAYS, MINUTES, resolveMember, resolveUser } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { ignoreEvent } from "../functions/ignoreEvent"; -import { isBanned } from "../functions/isBanned"; -import { IgnoredEventType, modActionsMsgCmd } from "../types"; - -const opts = { - mod: ct.member({ option: true }), -}; - -export const ForcebanCmd = modActionsMsgCmd({ - trigger: "forceban", - permission: "can_ban", - description: "Force-ban the specified user, even if they aren't on the server", - - signature: [ - { - user: ct.string(), - reason: ct.string({ required: false, catchAll: true }), - - ...opts, - }, - ], - - async run({ pluginData, message: msg, args }) { - const user = await resolveUser(pluginData.client, args.user); - if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); - return; - } - - // If the user exists as a guild member, make sure we can act on them first - const member = await resolveMember(pluginData.client, pluginData.guild, user.id); - if (member && !canActOn(pluginData, msg.member, member)) { - sendErrorMessage(pluginData, msg.channel, "Cannot forceban this user: insufficient permissions"); - return; - } - - // Make sure the user isn't already banned - const banned = await isBanned(pluginData, user.id); - if (banned) { - sendErrorMessage(pluginData, msg.channel, `User is already banned`); - return; - } - - // The moderator who did the action is the message author or, if used, the specified -mod - let mod = msg.member; - if (args.mod) { - if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); - return; - } - - mod = args.mod; - } - - const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]); - - ignoreEvent(pluginData, IgnoredEventType.Ban, user.id); - pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, user.id); - - try { - // FIXME: Use banUserId()? - await pluginData.guild.bans.create(user.id as Snowflake, { - deleteMessageSeconds: (1 * DAYS) / MINUTES, - reason: reason ?? undefined, - }); - } catch { - sendErrorMessage(pluginData, msg.channel, "Failed to forceban member"); - return; - } - - // Create a case - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const createdCase = await casesPlugin.createCase({ - userId: user.id, - modId: mod.id, - type: CaseTypes.Ban, - reason, - ppId: mod.id !== msg.author.id ? msg.author.id : undefined, - }); - - // Confirm the action - sendSuccessMessage(pluginData, msg.channel, `Member forcebanned (Case #${createdCase.case_number})`); - - // Log the action - pluginData.getPlugin(LogsPlugin).logMemberForceban({ - mod, - userId: user.id, - caseNumber: createdCase.case_number, - reason, - }); - - pluginData.state.events.emit("ban", user.id, reason); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts b/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts deleted file mode 100644 index 4b6f90da..00000000 --- a/backend/src/plugins/ModActions/commands/ForcemuteCmd.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage } from "../../../pluginUtils"; -import { resolveMember, resolveUser } from "../../../utils"; -import { actualMuteUserCmd } from "../functions/actualMuteUserCmd"; -import { modActionsMsgCmd } from "../types"; - -const opts = { - mod: ct.member({ option: true }), - notify: ct.string({ option: true }), - "notify-channel": ct.textChannel({ option: true }), -}; - -export const ForcemuteCmd = modActionsMsgCmd({ - trigger: "forcemute", - permission: "can_mute", - description: "Force-mute the specified user, even if they're not on the server", - - signature: [ - { - user: ct.string(), - time: ct.delay(), - reason: ct.string({ required: false, catchAll: true }), - - ...opts, - }, - { - user: ct.string(), - reason: ct.string({ required: false, catchAll: true }), - - ...opts, - }, - ], - - async run({ pluginData, message: msg, args }) { - const user = await resolveUser(pluginData.client, args.user); - if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); - return; - } - - const memberToMute = await resolveMember(pluginData.client, pluginData.guild, user.id); - - // Make sure we're allowed to mute this user - if (memberToMute && !canActOn(pluginData, msg.member, memberToMute)) { - sendErrorMessage(pluginData, msg.channel, "Cannot mute: insufficient permissions"); - return; - } - - actualMuteUserCmd(pluginData, user, msg, { ...args, notify: "none" }); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/HideCaseCmd.ts b/backend/src/plugins/ModActions/commands/HideCaseCmd.ts deleted file mode 100644 index b08756db..00000000 --- a/backend/src/plugins/ModActions/commands/HideCaseCmd.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { modActionsMsgCmd } from "../types"; - -export const HideCaseCmd = modActionsMsgCmd({ - trigger: ["hide", "hidecase", "hide_case"], - permission: "can_hidecase", - description: "Hide the specified case so it doesn't appear in !cases or !info", - - signature: [ - { - caseNum: ct.number({ rest: true }), - }, - ], - - async run({ pluginData, message: msg, args }) { - const failed: number[] = []; - - for (const num of args.caseNum) { - const theCase = await pluginData.state.cases.findByCaseNumber(num); - if (!theCase) { - failed.push(num); - continue; - } - - await pluginData.state.cases.setHidden(theCase.id, true); - } - - if (failed.length === args.caseNum.length) { - sendErrorMessage(pluginData, msg.channel, "None of the cases were found!"); - return; - } - const failedAddendum = - failed.length > 0 - ? `\nThe following cases were not found: ${failed.toString().replace(new RegExp(",", "g"), ", ")}` - : ""; - - const amt = args.caseNum.length - failed.length; - sendSuccessMessage( - pluginData, - msg.channel, - `${amt} case${amt === 1 ? " is" : "s are"} now hidden! Use \`unhidecase\` to unhide them.${failedAddendum}`, - ); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/KickCmd.ts b/backend/src/plugins/ModActions/commands/KickCmd.ts deleted file mode 100644 index 2e32f3e2..00000000 --- a/backend/src/plugins/ModActions/commands/KickCmd.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { actualKickMemberCmd } from "../functions/actualKickMemberCmd"; -import { modActionsMsgCmd } from "../types"; - -const opts = { - mod: ct.member({ option: true }), - notify: ct.string({ option: true }), - "notify-channel": ct.textChannel({ option: true }), - clean: ct.bool({ option: true, isSwitch: true }), -}; - -export const KickCmd = modActionsMsgCmd({ - trigger: "kick", - permission: "can_kick", - description: "Kick the specified member", - - signature: [ - { - user: ct.string(), - reason: ct.string({ required: false, catchAll: true }), - - ...opts, - }, - ], - - async run({ pluginData, message: msg, args }) { - actualKickMemberCmd(pluginData, msg, args); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/MassBanCmd.ts b/backend/src/plugins/ModActions/commands/MassBanCmd.ts deleted file mode 100644 index 4769cd51..00000000 --- a/backend/src/plugins/ModActions/commands/MassBanCmd.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { Snowflake } from "discord.js"; -import { waitForReply } from "knub/helpers"; -import { performance } from "perf_hooks"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; -import { humanizeDurationShort } from "../../../humanizeDurationShort"; -import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { DAYS, MINUTES, SECONDS, noop } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { ignoreEvent } from "../functions/ignoreEvent"; -import { IgnoredEventType, modActionsMsgCmd } from "../types"; - -export const MassbanCmd = modActionsMsgCmd({ - trigger: "massban", - permission: "can_massban", - description: "Mass-ban a list of user IDs", - - signature: [ - { - userIds: ct.string({ rest: true }), - }, - ], - - async run({ pluginData, message: msg, args }) { - // Limit to 100 users at once (arbitrary?) - if (args.userIds.length > 100) { - sendErrorMessage(pluginData, msg.channel, `Can only massban max 100 users at once`); - return; - } - - // 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, msg.author.id); - if (!banReasonReply || !banReasonReply.content || banReasonReply.content.toLowerCase().trim() === "cancel") { - sendErrorMessage(pluginData, msg.channel, "Cancelled"); - return; - } - - const banReason = formatReasonWithAttachments(banReasonReply.content, [...msg.attachments.values()]); - - // Verify we can act on each of the users specified - for (const userId of args.userIds) { - const member = pluginData.guild.members.cache.get(userId as Snowflake); // TODO: Get members on demand? - if (member && !canActOn(pluginData, msg.member, member)) { - sendErrorMessage(pluginData, msg.channel, "Cannot massban one or more users: insufficient permissions"); - return; - } - } - - // Show a loading indicator since this can take a while - const maxWaitTime = pluginData.state.massbanQueue.timeout * pluginData.state.massbanQueue.length; - const maxWaitTimeFormatted = humanizeDurationShort(maxWaitTime, { round: true }); - const initialLoadingText = - pluginData.state.massbanQueue.length === 0 - ? "Banning..." - : `Massban queued. Waiting for previous massban to finish (max wait ${maxWaitTimeFormatted}).`; - const loadingMsg = await msg.channel.send(initialLoadingText); - - const waitTimeStart = performance.now(); - const waitingInterval = setInterval(() => { - const waitTime = humanizeDurationShort(performance.now() - waitTimeStart, { round: true }); - loadingMsg - .edit(`Massban queued. Still waiting for previous massban to finish (waited ${waitTime}).`) - .catch(() => clearInterval(waitingInterval)); - }, 1 * MINUTES); - - pluginData.state.massbanQueue.add(async () => { - clearInterval(waitingInterval); - - if (pluginData.state.unloaded) { - void loadingMsg.delete().catch(noop); - return; - } - - void loadingMsg.edit("Banning...").catch(noop); - - // Ban each user and count failed bans (if any) - const startTime = performance.now(); - const failedBans: string[] = []; - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const deleteDays = (await pluginData.config.getForMessage(msg)).ban_delete_message_days; - for (const [i, userId] of args.userIds.entries()) { - if (pluginData.state.unloaded) { - break; - } - - try { - // Ignore automatic ban cases and logs - // We create our own cases below and post a single "mass banned" log instead - ignoreEvent(pluginData, IgnoredEventType.Ban, userId, 30 * MINUTES); - pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, userId, 30 * MINUTES); - - await pluginData.guild.bans.create(userId as Snowflake, { - deleteMessageSeconds: (deleteDays * DAYS) / SECONDS, - reason: banReason, - }); - - await casesPlugin.createCase({ - userId, - modId: msg.author.id, - type: CaseTypes.Ban, - reason: `Mass ban: ${banReason}`, - postInCaseLogOverride: false, - }); - - pluginData.state.events.emit("ban", userId, banReason); - } catch { - failedBans.push(userId); - } - - // Send a status update every 10 bans - if ((i + 1) % 10 === 0) { - loadingMsg.edit(`Banning... ${i + 1}/${args.userIds.length}`).catch(noop); - } - } - - const totalTime = performance.now() - startTime; - const formattedTimeTaken = humanizeDurationShort(totalTime, { round: true }); - - // Clear loading indicator - loadingMsg.delete().catch(noop); - - const successfulBanCount = args.userIds.length - failedBans.length; - if (successfulBanCount === 0) { - // All bans failed - don't create a log entry and notify the user - sendErrorMessage(pluginData, msg.channel, "All bans failed. Make sure the IDs are valid."); - } else { - // Some or all bans were successful. Create a log entry for the mass ban and notify the user. - pluginData.getPlugin(LogsPlugin).logMassBan({ - mod: msg.author, - count: successfulBanCount, - reason: banReason, - }); - - if (failedBans.length) { - sendSuccessMessage( - pluginData, - msg.channel, - `Banned ${successfulBanCount} users in ${formattedTimeTaken}, ${ - failedBans.length - } failed: ${failedBans.join(" ")}`, - ); - } else { - sendSuccessMessage( - pluginData, - msg.channel, - `Banned ${successfulBanCount} users successfully in ${formattedTimeTaken}`, - ); - } - } - }); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts deleted file mode 100644 index a873b4c6..00000000 --- a/backend/src/plugins/ModActions/commands/MassUnbanCmd.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { Snowflake } from "discord.js"; -import { waitForReply } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { ignoreEvent } from "../functions/ignoreEvent"; -import { isBanned } from "../functions/isBanned"; -import { IgnoredEventType, modActionsMsgCmd } from "../types"; - -export const MassunbanCmd = modActionsMsgCmd({ - trigger: "massunban", - permission: "can_massunban", - description: "Mass-unban a list of user IDs", - - signature: [ - { - userIds: ct.string({ rest: true }), - }, - ], - - async run({ pluginData, message: msg, args }) { - // Limit to 100 users at once (arbitrary?) - if (args.userIds.length > 100) { - sendErrorMessage(pluginData, msg.channel, `Can only mass-unban max 100 users at once`); - return; - } - - // 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, msg.author.id); - if (!unbanReasonReply || !unbanReasonReply.content || unbanReasonReply.content.toLowerCase().trim() === "cancel") { - sendErrorMessage(pluginData, msg.channel, "Cancelled"); - return; - } - - const unbanReason = formatReasonWithAttachments(unbanReasonReply.content, [...msg.attachments.values()]); - - // Ignore automatic unban cases and logs for these users - // We'll create our own cases below and post a single "mass unbanned" log instead - args.userIds.forEach((userId) => { - // Use longer timeouts since this can take a while - ignoreEvent(pluginData, IgnoredEventType.Unban, userId, 120 * 1000); - pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, userId, 120 * 1000); - }); - - // Show a loading indicator since this can take a while - const loadingMsg = await msg.channel.send("Unbanning..."); - - // Unban each user and count failed unbans (if any) - const failedUnbans: Array<{ userId: string; reason: UnbanFailReasons }> = []; - const casesPlugin = pluginData.getPlugin(CasesPlugin); - for (const userId of args.userIds) { - if (!(await isBanned(pluginData, userId))) { - failedUnbans.push({ userId, reason: UnbanFailReasons.NOT_BANNED }); - continue; - } - - try { - await pluginData.guild.bans.remove(userId as Snowflake, unbanReason ?? undefined); - - await casesPlugin.createCase({ - userId, - modId: msg.author.id, - type: CaseTypes.Unban, - reason: `Mass unban: ${unbanReason}`, - postInCaseLogOverride: false, - }); - } catch { - failedUnbans.push({ userId, reason: UnbanFailReasons.UNBAN_FAILED }); - } - } - - // Clear loading indicator - loadingMsg.delete(); - - const successfulUnbanCount = args.userIds.length - failedUnbans.length; - if (successfulUnbanCount === 0) { - // All unbans failed - don't create a log entry and notify the user - sendErrorMessage(pluginData, msg.channel, "All unbans failed. Make sure the IDs are valid and banned."); - } else { - // Some or all unbans were successful. Create a log entry for the mass unban and notify the user. - pluginData.getPlugin(LogsPlugin).logMassUnban({ - mod: msg.author, - count: successfulUnbanCount, - reason: unbanReason, - }); - - if (failedUnbans.length) { - const notBanned = failedUnbans.filter((x) => x.reason === UnbanFailReasons.NOT_BANNED); - const unbanFailed = failedUnbans.filter((x) => x.reason === UnbanFailReasons.UNBAN_FAILED); - - let failedMsg = ""; - if (notBanned.length > 0) { - failedMsg += `${notBanned.length}x ${UnbanFailReasons.NOT_BANNED}:`; - notBanned.forEach((fail) => { - failedMsg += " " + fail.userId; - }); - } - if (unbanFailed.length > 0) { - failedMsg += `\n${unbanFailed.length}x ${UnbanFailReasons.UNBAN_FAILED}:`; - unbanFailed.forEach((fail) => { - failedMsg += " " + fail.userId; - }); - } - - sendSuccessMessage( - pluginData, - msg.channel, - `Unbanned ${successfulUnbanCount} users, ${failedUnbans.length} failed:\n${failedMsg}`, - ); - } else { - sendSuccessMessage(pluginData, msg.channel, `Unbanned ${successfulUnbanCount} users successfully`); - } - } - }, -}); - -enum UnbanFailReasons { - NOT_BANNED = "Not banned", - UNBAN_FAILED = "Unban failed", -} diff --git a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts b/backend/src/plugins/ModActions/commands/MassmuteCmd.ts deleted file mode 100644 index 65422f0f..00000000 --- a/backend/src/plugins/ModActions/commands/MassmuteCmd.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { Snowflake } from "discord.js"; -import { waitForReply } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { LogType } from "../../../data/LogType"; -import { logger } from "../../../logger"; -import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { modActionsMsgCmd } from "../types"; - -export const MassmuteCmd = modActionsMsgCmd({ - trigger: "massmute", - permission: "can_massmute", - description: "Mass-mute a list of user IDs", - - signature: [ - { - userIds: ct.string({ rest: true }), - }, - ], - - async run({ pluginData, message: msg, args }) { - // Limit to 100 users at once (arbitrary?) - if (args.userIds.length > 100) { - sendErrorMessage(pluginData, msg.channel, `Can only massmute max 100 users at once`); - return; - } - - // Ask for mute reason - msg.channel.send("Mute reason? `cancel` to cancel"); - const muteReasonReceived = await waitForReply(pluginData.client, msg.channel, msg.author.id); - if ( - !muteReasonReceived || - !muteReasonReceived.content || - muteReasonReceived.content.toLowerCase().trim() === "cancel" - ) { - sendErrorMessage(pluginData, msg.channel, "Cancelled"); - return; - } - - const muteReason = formatReasonWithAttachments(muteReasonReceived.content, [...msg.attachments.values()]); - - // Verify we can act upon all users - for (const userId of args.userIds) { - const member = pluginData.guild.members.cache.get(userId as Snowflake); - if (member && !canActOn(pluginData, msg.member, member)) { - sendErrorMessage(pluginData, msg.channel, "Cannot massmute one or more users: insufficient permissions"); - return; - } - } - - // Ignore automatic mute cases and logs for these users - // We'll create our own cases below and post a single "mass muted" log instead - args.userIds.forEach((userId) => { - // Use longer timeouts since this can take a while - pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_MUTE, userId, 120 * 1000); - }); - - // Show loading indicator - const loadingMsg = await msg.channel.send("Muting..."); - - // Mute everyone and count fails - const modId = msg.author.id; - const failedMutes: string[] = []; - const mutesPlugin = pluginData.getPlugin(MutesPlugin); - for (const userId of args.userIds) { - try { - await mutesPlugin.muteUser(userId, 0, `Mass mute: ${muteReason}`, { - caseArgs: { - modId, - }, - }); - } catch (e) { - logger.info(e); - failedMutes.push(userId); - } - } - - // Clear loading indicator - loadingMsg.delete(); - - const successfulMuteCount = args.userIds.length - failedMutes.length; - if (successfulMuteCount === 0) { - // All mutes failed - sendErrorMessage(pluginData, msg.channel, "All mutes failed. Make sure the IDs are valid."); - } else { - // Success on all or some mutes - pluginData.getPlugin(LogsPlugin).logMassMute({ - mod: msg.author, - count: successfulMuteCount, - }); - - if (failedMutes.length) { - sendSuccessMessage( - pluginData, - msg.channel, - `Muted ${successfulMuteCount} users, ${failedMutes.length} failed: ${failedMutes.join(" ")}`, - ); - } else { - sendSuccessMessage(pluginData, msg.channel, `Muted ${successfulMuteCount} users successfully`); - } - } - }, -}); diff --git a/backend/src/plugins/ModActions/commands/SoftbanCommand.ts b/backend/src/plugins/ModActions/commands/SoftbanCommand.ts deleted file mode 100644 index a5806cdd..00000000 --- a/backend/src/plugins/ModActions/commands/SoftbanCommand.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { trimPluginDescription } from "../../../utils"; -import { actualKickMemberCmd } from "../functions/actualKickMemberCmd"; -import { modActionsMsgCmd } from "../types"; - -const opts = { - mod: ct.member({ option: true }), - notify: ct.string({ option: true }), - "notify-channel": ct.textChannel({ option: true }), -}; - -export const SoftbanCmd = modActionsMsgCmd({ - trigger: "softban", - permission: "can_kick", - description: trimPluginDescription(` - "Softban" the specified user by banning and immediately unbanning them. Effectively a kick with message deletions. - This command will be removed in the future, please use kick with the \`- clean\` argument instead - `), - - signature: [ - { - user: ct.string(), - reason: ct.string({ required: false, catchAll: true }), - - ...opts, - }, - ], - - async run({ pluginData, message: msg, args }) { - await actualKickMemberCmd(pluginData, msg, { clean: true, ...args }); - await msg.channel.send( - "Softban will be removed in the future - please use the kick command with the `-clean` argument instead!", - ); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/UnbanCmd.ts b/backend/src/plugins/ModActions/commands/UnbanCmd.ts deleted file mode 100644 index d232f4e4..00000000 --- a/backend/src/plugins/ModActions/commands/UnbanCmd.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { Snowflake } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; -import { clearExpiringTempban } from "../../../data/loops/expiringTempbansLoop"; -import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { resolveUser } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { ignoreEvent } from "../functions/ignoreEvent"; -import { IgnoredEventType, modActionsMsgCmd } from "../types"; - -const opts = { - mod: ct.member({ option: true }), -}; - -export const UnbanCmd = modActionsMsgCmd({ - trigger: "unban", - permission: "can_unban", - description: "Unban the specified member", - - signature: [ - { - user: ct.string(), - reason: ct.string({ required: false, catchAll: true }), - - ...opts, - }, - ], - - async run({ pluginData, message: msg, args }) { - const user = await resolveUser(pluginData.client, args.user); - if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); - return; - } - - // The moderator who did the action is the message author or, if used, the specified -mod - let mod = msg.member; - if (args.mod) { - if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg, channelId: msg.channel.id }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); - return; - } - - mod = args.mod; - } - - pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, user.id); - const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]); - - try { - ignoreEvent(pluginData, IgnoredEventType.Unban, user.id); - await pluginData.guild.bans.remove(user.id as Snowflake, reason ?? undefined); - } catch { - sendErrorMessage(pluginData, msg.channel, "Failed to unban member; are you sure they're banned?"); - return; - } - - // Create a case - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const createdCase = await casesPlugin.createCase({ - userId: user.id, - modId: mod.id, - type: CaseTypes.Unban, - reason, - ppId: mod.id !== msg.author.id ? msg.author.id : undefined, - }); - // Delete the tempban, if one exists - const tempban = await pluginData.state.tempbans.findExistingTempbanForUserId(user.id); - if (tempban) { - clearExpiringTempban(tempban); - await pluginData.state.tempbans.clear(user.id); - } - - // Confirm the action - sendSuccessMessage(pluginData, msg.channel, `Member unbanned (Case #${createdCase.case_number})`); - - // Log the action - pluginData.getPlugin(LogsPlugin).logMemberUnban({ - mod: mod.user, - userId: user.id, - caseNumber: createdCase.case_number, - reason: reason ?? "", - }); - - pluginData.state.events.emit("unban", user.id); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts b/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts deleted file mode 100644 index 7c6eb774..00000000 --- a/backend/src/plugins/ModActions/commands/UnhideCaseCmd.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { modActionsMsgCmd } from "../types"; - -export const UnhideCaseCmd = modActionsMsgCmd({ - trigger: ["unhide", "unhidecase", "unhide_case"], - permission: "can_hidecase", - description: "Un-hide the specified case, making it appear in !cases and !info again", - - signature: [ - { - caseNum: ct.number({ rest: true }), - }, - ], - - async run({ pluginData, message: msg, args }) { - const failed: number[] = []; - - for (const num of args.caseNum) { - const theCase = await pluginData.state.cases.findByCaseNumber(num); - if (!theCase) { - failed.push(num); - continue; - } - - await pluginData.state.cases.setHidden(theCase.id, false); - } - - if (failed.length === args.caseNum.length) { - sendErrorMessage(pluginData, msg.channel, "None of the cases were found!"); - return; - } - const failedAddendum = - failed.length > 0 - ? `\nThe following cases were not found: ${failed.toString().replace(new RegExp(",", "g"), ", ")}` - : ""; - - const amt = args.caseNum.length - failed.length; - sendSuccessMessage( - pluginData, - msg.channel, - `${amt} case${amt === 1 ? " is" : "s are"} no longer hidden!${failedAddendum}`, - ); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/WarnCmd.ts b/backend/src/plugins/ModActions/commands/WarnCmd.ts deleted file mode 100644 index 2b3121fd..00000000 --- a/backend/src/plugins/ModActions/commands/WarnCmd.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { canActOn, hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { errorMessage, renderUserUsername, resolveMember, resolveUser } from "../../../utils"; -import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { formatReasonWithAttachments } from "../functions/formatReasonWithAttachments"; -import { isBanned } from "../functions/isBanned"; -import { readContactMethodsFromArgs } from "../functions/readContactMethodsFromArgs"; -import { warnMember } from "../functions/warnMember"; -import { modActionsMsgCmd } from "../types"; - -export const WarnCmd = modActionsMsgCmd({ - trigger: "warn", - permission: "can_warn", - description: "Send a warning to the specified user", - - signature: { - user: ct.string(), - reason: ct.string({ catchAll: true }), - - mod: ct.member({ option: true }), - notify: ct.string({ option: true }), - "notify-channel": ct.textChannel({ option: true }), - }, - - async run({ pluginData, message: msg, args }) { - const user = await resolveUser(pluginData.client, args.user); - if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); - return; - } - - const memberToWarn = await resolveMember(pluginData.client, pluginData.guild, user.id); - - if (!memberToWarn) { - const _isBanned = await isBanned(pluginData, user.id); - if (_isBanned) { - sendErrorMessage(pluginData, msg.channel, `User is banned`); - } else { - sendErrorMessage(pluginData, msg.channel, `User not found on the server`); - } - - return; - } - - // Make sure we're allowed to warn this member - if (!canActOn(pluginData, msg.member, memberToWarn)) { - sendErrorMessage(pluginData, msg.channel, "Cannot warn: insufficient permissions"); - return; - } - - // The moderator who did the action is the message author or, if used, the specified -mod - let mod = msg.member; - if (args.mod) { - if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - msg.channel.send(errorMessage("You don't have permission to use -mod")); - return; - } - - mod = args.mod; - } - - const config = pluginData.config.get(); - const reason = formatReasonWithAttachments(args.reason, [...msg.attachments.values()]); - - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const priorWarnAmount = await casesPlugin.getCaseTypeAmountForUserId(memberToWarn.id, CaseTypes.Warn); - if (config.warn_notify_enabled && priorWarnAmount >= config.warn_notify_threshold) { - const reply = await waitForButtonConfirm( - msg.channel, - { content: config.warn_notify_message.replace("{priorWarnings}", `${priorWarnAmount}`) }, - { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, - ); - if (!reply) { - msg.channel.send(errorMessage("Warn cancelled by moderator")); - return; - } - } - - let contactMethods; - try { - contactMethods = readContactMethodsFromArgs(args); - } catch (e) { - sendErrorMessage(pluginData, msg.channel, e.message); - return; - } - - const warnResult = await warnMember(pluginData, memberToWarn, reason, { - contactMethods, - caseArgs: { - modId: mod.id, - ppId: mod.id !== msg.author.id ? msg.author.id : undefined, - reason, - }, - retryPromptChannel: msg.channel, - }); - - if (warnResult.status === "failed") { - sendErrorMessage(pluginData, msg.channel, "Failed to warn user"); - return; - } - - const messageResultText = warnResult.notifyResult.text ? ` (${warnResult.notifyResult.text})` : ""; - - sendSuccessMessage( - pluginData, - msg.channel, - `Warned **${renderUserUsername(memberToWarn.user)}** (Case #${warnResult.case.case_number})${messageResultText}`, - ); - }, -}); diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts new file mode 100644 index 00000000..41c2a380 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts @@ -0,0 +1,63 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { CaseTypes } from "../../../../data/CaseTypes"; +import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { resolveUser } from "../../../../utils"; +import { actualAddCaseCmd } from "../../functions/actualCommands/actualAddCaseCmd"; +import { modActionsMsgCmd } from "../../types"; + +const opts = { + mod: ct.member({ option: true }), +}; + +export const AddCaseMsgCmd = modActionsMsgCmd({ + trigger: "addcase", + permission: "can_addcase", + description: "Add an arbitrary case to the specified user without taking any action", + + signature: [ + { + type: ct.string(), + user: ct.string(), + reason: ct.string({ required: false, catchAll: true }), + + ...opts, + }, + ], + + async run({ pluginData, message: msg, args }) { + const user = await resolveUser(pluginData.client, args.user); + if (!user.id) { + sendErrorMessage(pluginData, msg.channel, `User not found`); + return; + } + + // The moderator who did the action is the message author or, if used, the specified -mod + let mod = msg.member; + if (args.mod) { + if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { + sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + return; + } + + mod = args.mod; + } + + // Verify the case type is valid + const type: string = args.type[0].toUpperCase() + args.type.slice(1).toLowerCase(); + if (!CaseTypes[type]) { + sendErrorMessage(pluginData, msg.channel, "Cannot add case: invalid case type"); + return; + } + + actualAddCaseCmd( + pluginData, + msg.channel, + msg.member, + mod, + [...msg.attachments.values()], + user, + type as keyof CaseTypes, + args.reason || "", + ); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts new file mode 100644 index 00000000..b5fbfc5f --- /dev/null +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts @@ -0,0 +1,65 @@ +import { slashOptions } from "knub"; +import { CaseTypes } from "../../../../data/CaseTypes"; +import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { actualAddCaseCmd } from "../../functions/actualCommands/actualAddCaseCmd"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "reason", description: "The reason", required: false }), + slashOptions.user({ name: "mod", description: "The moderator to add this case as", required: false }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason of the case", + }), +]; + +export const AddCaseSlashCmd = { + name: "addcase", + configPermission: "can_addcase", + description: "Add an arbitrary case to the specified user without taking any action", + allowDms: false, + + signature: [ + slashOptions.string({ + name: "type", + description: "The type of case to add", + required: true, + choices: Object.keys(CaseTypes).map((type) => ({ name: type, value: type })), + }), + slashOptions.user({ name: "user", description: "The user to add a case to", required: true }), + + ...opts, + ], + + async run({ interaction, options, pluginData }) { + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + // The moderator who did the action is the message author or, if used, the specified -mod + let mod = interaction.member; + const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { + channel: interaction.channel, + member: interaction.member, + }); + + if (options.mod) { + if (!canActAsOther) { + sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + return; + } + + mod = options.mod; + } + + actualAddCaseCmd( + pluginData, + interaction, + interaction.member, + mod, + attachments, + options.user, + options.type as keyof CaseTypes, + options.reason || "", + ); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts new file mode 100644 index 00000000..efea59d7 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts @@ -0,0 +1,75 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { UserNotificationMethod, resolveUser } from "../../../../utils"; +import { actualBanCmd } from "../../functions/actualCommands/actualBanCmd"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { modActionsMsgCmd } from "../../types"; + +const opts = { + mod: ct.member({ option: true }), + notify: ct.string({ option: true }), + "notify-channel": ct.textChannel({ option: true }), + "delete-days": ct.number({ option: true, shortcut: "d" }), +}; + +export const BanMsgCmd = modActionsMsgCmd({ + trigger: "ban", + permission: "can_ban", + description: "Ban or Tempban the specified member", + + signature: [ + { + user: ct.string(), + time: ct.delay(), + reason: ct.string({ required: false, catchAll: true }), + + ...opts, + }, + { + user: ct.string(), + reason: ct.string({ required: false, catchAll: true }), + + ...opts, + }, + ], + + async run({ pluginData, message: msg, args }) { + const user = await resolveUser(pluginData.client, args.user); + + if (!user.id) { + sendErrorMessage(pluginData, msg.channel, `User not found`); + return; + } + + // The moderator who did the action is the message author or, if used, the specified -mod + let mod = msg.member; + if (args.mod) { + if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { + sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + return; + } + + mod = args.mod; + } + + let contactMethods: UserNotificationMethod[] | undefined; + try { + contactMethods = readContactMethodsFromArgs(args) ?? undefined; + } catch (e) { + sendErrorMessage(pluginData, msg.channel, e.message); + return; + } + + actualBanCmd( + pluginData, + msg.channel, + user, + args["time"] ? args["time"] : null, + args.reason || "", + [...msg.attachments.values()], + msg.member, + mod, + contactMethods, + ); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts new file mode 100644 index 00000000..acd19a43 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts @@ -0,0 +1,98 @@ +import { ChannelType } from "discord.js"; +import { slashOptions } from "knub"; +import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { UserNotificationMethod, convertDelayStringToMS } from "../../../../utils"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { actualBanCmd } from "../../functions/actualCommands/actualBanCmd"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "time", description: "The duration of the ban", required: false }), + slashOptions.string({ name: "reason", description: "The reason", required: false }), + slashOptions.user({ name: "mod", description: "The moderator to ban as", required: false }), + slashOptions.string({ + name: "notify", + description: "How to notify", + required: false, + choices: [ + { name: "DM", value: "dm" }, + { name: "Channel", value: "channel" }, + ], + }), + slashOptions.channel({ + name: "notify-channel", + description: "The channel to notify in", + channelTypes: [ChannelType.GuildText, ChannelType.PrivateThread, ChannelType.PublicThread], + required: false, + }), + slashOptions.number({ + name: "delete-days", + description: "The number of days of messages to delete", + required: false, + }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason of the ban", + }), +]; + +export const BanSlashCmd = { + name: "ban", + configPermission: "can_ban", + description: "Ban or Tempban the specified member", + allowDms: false, + + signature: [slashOptions.user({ name: "user", description: "The user to ban", required: true }), ...opts], + + async run({ interaction, options, pluginData }) { + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { + sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + let mod = interaction.member; + const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { + channel: interaction.channel, + member: interaction.member, + }); + + if (options.mod) { + if (!canActAsOther) { + sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + return; + } + + mod = options.mod; + } + + let contactMethods: UserNotificationMethod[] | undefined; + try { + contactMethods = readContactMethodsFromArgs(options) ?? undefined; + } catch (e) { + sendErrorMessage(pluginData, interaction, e.message); + return; + } + + const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; + if (options.time && !convertedTime) { + sendErrorMessage(pluginData, interaction, `Could not convert ${options.time} to a delay`); + return; + } + + actualBanCmd( + pluginData, + interaction, + options.user, + convertedTime, + options.reason || "", + attachments, + interaction.member, + mod, + contactMethods, + ); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts new file mode 100644 index 00000000..6521e327 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts @@ -0,0 +1,19 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { actualCaseCmd } from "../../functions/actualCommands/actualCaseCmd"; +import { modActionsMsgCmd } from "../../types"; + +export const CaseMsgCmd = modActionsMsgCmd({ + trigger: "case", + permission: "can_view", + description: "Show information about a specific case", + + signature: [ + { + caseNumber: ct.number(), + }, + ], + + async run({ pluginData, message: msg, args }) { + actualCaseCmd(pluginData, msg.channel, msg.author.id, args.caseNumber); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts new file mode 100644 index 00000000..c537ec6e --- /dev/null +++ b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts @@ -0,0 +1,17 @@ +import { slashOptions } from "knub"; +import { actualCaseCmd } from "../../functions/actualCommands/actualCaseCmd"; + +export const CaseSlashCmd = { + name: "case", + configPermission: "can_view", + description: "Show information about a specific case", + allowDms: false, + + signature: [ + slashOptions.number({ name: "case-number", description: "The number of the case to show", required: true }), + ], + + async run({ interaction, options, pluginData }) { + actualCaseCmd(pluginData, interaction, interaction.user.id, options["case-number"]); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts new file mode 100644 index 00000000..b9e496b7 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts @@ -0,0 +1,47 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { actualCasesCmd } from "../../functions/actualCommands/actualCasesCmd"; +import { modActionsMsgCmd } from "../../types"; + +const opts = { + mod: ct.userId({ option: true }), + expand: ct.bool({ option: true, isSwitch: true, shortcut: "e" }), + hidden: ct.bool({ option: true, isSwitch: true, shortcut: "h" }), + reverseFilters: ct.switchOption({ def: false, shortcut: "r" }), + notes: ct.switchOption({ def: false, shortcut: "n" }), + warns: ct.switchOption({ def: false, shortcut: "w" }), + mutes: ct.switchOption({ def: false, shortcut: "m" }), + unmutes: ct.switchOption({ def: false, shortcut: "um" }), + bans: ct.switchOption({ def: false, shortcut: "b" }), + unbans: ct.switchOption({ def: false, shortcut: "ub" }), +}; + +export const CasesModMsgCmd = modActionsMsgCmd({ + trigger: ["cases", "modlogs", "infractions"], + permission: "can_view", + description: "Show the most recent 5 cases by the specified -mod", + + signature: [ + { + ...opts, + }, + ], + + async run({ pluginData, message: msg, args }) { + return actualCasesCmd( + pluginData, + msg.channel, + args.mod, + null, + msg.author, + args.notes, + args.warns, + args.mutes, + args.unmutes, + args.bans, + args.unbans, + args.reverseFilters, + args.hidden, + args.expand, + ); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts new file mode 100644 index 00000000..5207d76f --- /dev/null +++ b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts @@ -0,0 +1,48 @@ +import { slashOptions } from "knub"; +import { actualCasesCmd } from "../../functions/actualCommands/actualCasesCmd"; + +const opts = [ + slashOptions.user({ name: "user", description: "The user to show cases for", required: false }), + slashOptions.user({ name: "mod", description: "The mod to filter cases by", required: false }), + slashOptions.boolean({ name: "expand", description: "Show each case individually", required: false }), + slashOptions.boolean({ name: "hidden", description: "Whether or not to show hidden cases", required: false }), + slashOptions.boolean({ + name: "reverse-filters", + description: "To treat case type filters as exclusive instead of inclusive", + required: false, + }), + slashOptions.boolean({ name: "notes", description: "To filter notes", required: false }), + slashOptions.boolean({ name: "warns", description: "To filter warns", required: false }), + slashOptions.boolean({ name: "mutes", description: "To filter mutes", required: false }), + slashOptions.boolean({ name: "unmutes", description: "To filter unmutes", required: false }), + slashOptions.boolean({ name: "bans", description: "To filter bans", required: false }), + slashOptions.boolean({ name: "unbans", description: "To filter unbans", required: false }), +]; + +export const CasesSlashCmd = { + name: "cases", + configPermission: "can_view", + description: "Show a list of cases the specified user has or the specified mod made", + allowDms: false, + + signature: [...opts], + + async run({ interaction, options, pluginData }) { + return actualCasesCmd( + pluginData, + interaction, + options.mod, + options.user, + interaction.user, + options.notes, + options.warns, + options.mutes, + options.unmutes, + options.bans, + options.unbans, + options["reverse-filters"], + options.hidden, + options.expand, + ); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts new file mode 100644 index 00000000..765524df --- /dev/null +++ b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts @@ -0,0 +1,57 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { sendErrorMessage } from "../../../../pluginUtils"; +import { resolveUser } from "../../../../utils"; +import { actualCasesCmd } from "../../functions/actualCommands/actualCasesCmd"; +import { modActionsMsgCmd } from "../../types"; + +const opts = { + mod: ct.userId({ option: true }), + expand: ct.bool({ option: true, isSwitch: true, shortcut: "e" }), + hidden: ct.bool({ option: true, isSwitch: true, shortcut: "h" }), + reverseFilters: ct.switchOption({ def: false, shortcut: "r" }), + notes: ct.switchOption({ def: false, shortcut: "n" }), + warns: ct.switchOption({ def: false, shortcut: "w" }), + mutes: ct.switchOption({ def: false, shortcut: "m" }), + unmutes: ct.switchOption({ def: false, shortcut: "um" }), + bans: ct.switchOption({ def: false, shortcut: "b" }), + unbans: ct.switchOption({ def: false, shortcut: "ub" }), +}; + +export const CasesUserMsgCmd = modActionsMsgCmd({ + trigger: ["cases", "modlogs", "infractions"], + permission: "can_view", + description: "Show a list of cases the specified user has", + + signature: [ + { + user: ct.string(), + + ...opts, + }, + ], + + async run({ pluginData, message: msg, args }) { + const user = await resolveUser(pluginData.client, args.user); + if (!user.id) { + sendErrorMessage(pluginData, msg.channel, `User not found`); + return; + } + + return actualCasesCmd( + pluginData, + msg.channel, + args.mod, + user, + msg.author, + args.notes, + args.warns, + args.mutes, + args.unmutes, + args.bans, + args.unbans, + args.reverseFilters, + args.hidden, + args.expand, + ); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/constants.ts b/backend/src/plugins/ModActions/commands/constants.ts new file mode 100644 index 00000000..624f9de3 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/constants.ts @@ -0,0 +1,2 @@ +export const NUMBER_ATTACHMENTS_CASE_CREATION = 1; +export const NUMBER_ATTACHMENTS_CASE_UPDATE = 3; diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts new file mode 100644 index 00000000..70dbc92f --- /dev/null +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts @@ -0,0 +1,23 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { trimLines } from "../../../../utils"; +import { actualDeleteCaseCmd } from "../../functions/actualCommands/actualDeleteCaseCmd"; +import { modActionsMsgCmd } from "../../types"; + +export const DeleteCaseMsgCmd = modActionsMsgCmd({ + trigger: ["delete_case", "deletecase"], + permission: "can_deletecase", + description: trimLines(` + Delete the specified case. This operation can *not* be reversed. + It is generally recommended to use \`!hidecase\` instead when possible. + `), + + signature: { + caseNumber: ct.number({ rest: true }), + + force: ct.switchOption({ def: false, shortcut: "f" }), + }, + + async run({ pluginData, message, args }) { + actualDeleteCaseCmd(pluginData, message.channel, message.member, args.caseNumber, args.force); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts new file mode 100644 index 00000000..e087e3a4 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts @@ -0,0 +1,27 @@ +import { slashOptions } from "knub"; +import { actualDeleteCaseCmd } from "../../functions/actualCommands/actualDeleteCaseCmd"; + +const opts = [slashOptions.boolean({ name: "force", description: "Whether or not to force delete", required: false })]; + +export const DeleteCaseSlashCmd = { + name: "deletecase", + configPermission: "can_deletecase", + description: "Delete the specified case. This operation can *not* be reversed.", + allowDms: false, + + signature: [ + slashOptions.string({ name: "case-number", description: "The number of the case to delete", required: true }), + + ...opts, + ], + + async run({ interaction, options, pluginData }) { + actualDeleteCaseCmd( + pluginData, + interaction, + interaction.member, + options["case-number"].split(/[\s,]+/), + !!options.force, + ); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts new file mode 100644 index 00000000..ee0e4fa7 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts @@ -0,0 +1,60 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { resolveMember, resolveUser } from "../../../../utils"; +import { actualForceBanCmd } from "../../functions/actualCommands/actualForceBanCmd"; +import { isBanned } from "../../functions/isBanned"; +import { modActionsMsgCmd } from "../../types"; + +const opts = { + mod: ct.member({ option: true }), +}; + +export const ForceBanMsgCmd = modActionsMsgCmd({ + trigger: "forceban", + permission: "can_ban", + description: "Force-ban the specified user, even if they aren't on the server", + + signature: [ + { + user: ct.string(), + reason: ct.string({ required: false, catchAll: true }), + + ...opts, + }, + ], + + async run({ pluginData, message: msg, args }) { + const user = await resolveUser(pluginData.client, args.user); + if (!user.id) { + sendErrorMessage(pluginData, msg.channel, `User not found`); + return; + } + + // If the user exists as a guild member, make sure we can act on them first + const member = await resolveMember(pluginData.client, pluginData.guild, user.id); + if (member && !canActOn(pluginData, msg.member, member)) { + sendErrorMessage(pluginData, msg.channel, "Cannot forceban this user: insufficient permissions"); + return; + } + + // Make sure the user isn't already banned + const banned = await isBanned(pluginData, user.id); + if (banned) { + sendErrorMessage(pluginData, msg.channel, `User is already banned`); + return; + } + + // The moderator who did the action is the message author or, if used, the specified -mod + let mod = msg.member; + if (args.mod) { + if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { + sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + return; + } + + mod = args.mod; + } + + actualForceBanCmd(pluginData, msg.channel, msg.author.id, user, args.reason, [...msg.attachments.values()], mod); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts new file mode 100644 index 00000000..c1722fcc --- /dev/null +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts @@ -0,0 +1,57 @@ +import { slashOptions } from "knub"; +import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { convertDelayStringToMS } from "../../../../utils"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { actualForceBanCmd } from "../../functions/actualCommands/actualForceBanCmd"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "reason", description: "The reason", required: false }), + slashOptions.user({ name: "mod", description: "The moderator to ban as", required: false }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason of the ban", + }), +]; + +export const ForceBanSlashCmd = { + name: "forceban", + configPermission: "can_ban", + description: "Force-ban the specified user, even if they aren't on the server", + allowDms: false, + + signature: [slashOptions.user({ name: "user", description: "The user to ban", required: true }), ...opts], + + async run({ interaction, options, pluginData }) { + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { + sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + let mod = interaction.member; + const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { + channel: interaction.channel, + member: interaction.member, + }); + + if (options.mod) { + if (!canActAsOther) { + sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + return; + } + + mod = options.mod; + } + + const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; + if (options.time && !convertedTime) { + sendErrorMessage(pluginData, interaction, `Could not convert ${options.time} to a delay`); + return; + } + + actualForceBanCmd(pluginData, interaction, interaction.user.id, options.user, options.reason, attachments, mod); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts new file mode 100644 index 00000000..9ecbae61 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts @@ -0,0 +1,84 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { resolveMember, resolveUser } from "../../../../utils"; +import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { modActionsMsgCmd } from "../../types"; + +const opts = { + mod: ct.member({ option: true }), + notify: ct.string({ option: true }), + "notify-channel": ct.textChannel({ option: true }), +}; + +export const ForceMuteMsgCmd = modActionsMsgCmd({ + trigger: "forcemute", + permission: "can_mute", + description: "Force-mute the specified user, even if they're not on the server", + + signature: [ + { + user: ct.string(), + time: ct.delay(), + reason: ct.string({ required: false, catchAll: true }), + + ...opts, + }, + { + user: ct.string(), + reason: ct.string({ required: false, catchAll: true }), + + ...opts, + }, + ], + + async run({ pluginData, message: msg, args }) { + const user = await resolveUser(pluginData.client, args.user); + if (!user.id) { + sendErrorMessage(pluginData, msg.channel, `User not found`); + return; + } + + const memberToMute = await resolveMember(pluginData.client, pluginData.guild, user.id); + + // Make sure we're allowed to mute this user + if (memberToMute && !canActOn(pluginData, msg.member, memberToMute)) { + sendErrorMessage(pluginData, msg.channel, "Cannot mute: insufficient permissions"); + return; + } + + // The moderator who did the action is the message author or, if used, the specified -mod + let mod = msg.member; + let ppId: string | undefined; + + if (args.mod) { + if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { + sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + return; + } + + mod = args.mod; + ppId = msg.author.id; + } + + let contactMethods; + try { + contactMethods = readContactMethodsFromArgs(args); + } catch (e) { + sendErrorMessage(pluginData, msg.channel, e.message); + return; + } + + actualMuteCmd( + pluginData, + msg.channel, + user, + [...msg.attachments.values()], + mod, + ppId, + "time" in args ? args.time ?? undefined : undefined, + args.reason, + contactMethods, + ); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts new file mode 100644 index 00000000..b32cde4f --- /dev/null +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts @@ -0,0 +1,95 @@ +import { ChannelType } from "discord.js"; +import { slashOptions } from "knub"; +import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { UserNotificationMethod, convertDelayStringToMS } from "../../../../utils"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "time", description: "The duration of the mute", required: false }), + slashOptions.string({ name: "reason", description: "The reason", required: false }), + slashOptions.user({ name: "mod", description: "The moderator to mute as", required: false }), + slashOptions.string({ + name: "notify", + description: "How to notify", + required: false, + choices: [ + { name: "DM", value: "dm" }, + { name: "Channel", value: "channel" }, + ], + }), + slashOptions.channel({ + name: "notify-channel", + description: "The channel to notify in", + channelTypes: [ChannelType.GuildText, ChannelType.PrivateThread, ChannelType.PublicThread], + required: false, + }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason of the mute", + }), +]; + +export const ForceMuteSlashCmd = { + name: "forcemute", + configPermission: "can_mute", + description: "Force-mute the specified user, even if they're not on the server", + allowDms: false, + + signature: [slashOptions.user({ name: "user", description: "The user to mute", required: true }), ...opts], + + async run({ interaction, options, pluginData }) { + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { + sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + let mod = interaction.member; + let ppId: string | undefined; + const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { + channel: interaction.channel, + member: interaction.member, + }); + + if (options.mod) { + if (!canActAsOther) { + sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + return; + } + + mod = options.mod; + ppId = interaction.user.id; + } + + const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; + if (options.time && !convertedTime) { + sendErrorMessage(pluginData, interaction, `Could not convert ${options.time} to a delay`); + return; + } + + let contactMethods: UserNotificationMethod[] | undefined; + try { + contactMethods = readContactMethodsFromArgs(options) ?? undefined; + } catch (e) { + sendErrorMessage(pluginData, interaction, e.message); + return; + } + + actualMuteCmd( + pluginData, + interaction, + options.user, + attachments, + mod, + ppId, + options.time, + options.reason, + contactMethods, + ); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts similarity index 55% rename from backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts rename to backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts index 5ce489a1..c1b97351 100644 --- a/backend/src/plugins/ModActions/commands/ForceunmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts @@ -1,14 +1,14 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage } from "../../../pluginUtils"; -import { resolveMember, resolveUser } from "../../../utils"; -import { actualUnmuteCmd } from "../functions/actualUnmuteUserCmd"; -import { modActionsMsgCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { resolveMember, resolveUser } from "../../../../utils"; +import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { modActionsMsgCmd } from "../../types"; const opts = { mod: ct.member({ option: true }), }; -export const ForceUnmuteCmd = modActionsMsgCmd({ +export const ForceUnmuteMsgCmd = modActionsMsgCmd({ trigger: "forceunmute", permission: "can_mute", description: "Force-unmute the specified user, even if they're not on the server", @@ -51,6 +51,29 @@ export const ForceUnmuteCmd = modActionsMsgCmd({ return; } - actualUnmuteCmd(pluginData, user, msg, args); + // The moderator who did the action is the message author or, if used, the specified -mod + let mod = msg.member; + let ppId: string | undefined; + + if (args.mod) { + if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { + sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + return; + } + + mod = args.mod; + ppId = msg.author.id; + } + + actualUnmuteCmd( + pluginData, + msg.channel, + user, + [...msg.attachments.values()], + mod, + ppId, + "time" in args ? args.time ?? undefined : undefined, + args.reason, + ); }, }); diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts new file mode 100644 index 00000000..107151a8 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts @@ -0,0 +1,60 @@ +import { slashOptions } from "knub"; +import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { convertDelayStringToMS } from "../../../../utils"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "time", description: "The duration of the unmute", required: false }), + slashOptions.string({ name: "reason", description: "The reason", required: false }), + slashOptions.user({ name: "mod", description: "The moderator to unmute as", required: false }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason of the unmute", + }), +]; + +export const ForceUnmuteSlashCmd = { + name: "forceunmute", + configPermission: "can_mute", + description: "Force-unmute the specified user, even if they're not on the server", + allowDms: false, + + signature: [slashOptions.user({ name: "user", description: "The user to unmute", required: true }), ...opts], + + async run({ interaction, options, pluginData }) { + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { + sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + let mod = interaction.member; + let ppId: string | undefined; + const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { + channel: interaction.channel, + member: interaction.member, + }); + + if (options.mod) { + if (!canActAsOther) { + sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + return; + } + + mod = options.mod; + ppId = interaction.user.id; + } + + const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; + if (options.time && !convertedTime) { + sendErrorMessage(pluginData, interaction, `Could not convert ${options.time} to a delay`); + return; + } + + actualUnmuteCmd(pluginData, interaction, options.user, attachments, mod, ppId, options.time, options.reason); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts new file mode 100644 index 00000000..e7701d4a --- /dev/null +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts @@ -0,0 +1,19 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { actualHideCaseCmd } from "../../functions/actualCommands/actualHideCaseCmd"; +import { modActionsMsgCmd } from "../../types"; + +export const HideCaseMsgCmd = modActionsMsgCmd({ + trigger: ["hide", "hidecase", "hide_case"], + permission: "can_hidecase", + description: "Hide the specified case so it doesn't appear in !cases or !info", + + signature: [ + { + caseNum: ct.number({ rest: true }), + }, + ], + + async run({ pluginData, message: msg, args }) { + actualHideCaseCmd(pluginData, msg.channel, args.caseNum); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts new file mode 100644 index 00000000..c324b250 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts @@ -0,0 +1,17 @@ +import { slashOptions } from "knub"; +import { actualHideCaseCmd } from "../../functions/actualCommands/actualHideCaseCmd"; + +export const HideCaseSlashCmd = { + name: "hidecase", + configPermission: "can_hidecase", + description: "Hide the specified case so it doesn't appear in !cases or !info", + allowDms: false, + + signature: [ + slashOptions.string({ name: "case-number", description: "The number of the case to hide", required: true }), + ], + + async run({ interaction, options, pluginData }) { + actualHideCaseCmd(pluginData, interaction, options["case-number"].split(/[\s,]+/).map(Number)); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts new file mode 100644 index 00000000..bab6064d --- /dev/null +++ b/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts @@ -0,0 +1,68 @@ +import { hasPermission } from "knub/helpers"; +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { sendErrorMessage } from "../../../../pluginUtils"; +import { resolveUser } from "../../../../utils"; +import { actualKickCmd } from "../../functions/actualCommands/actualKickCmd"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { modActionsMsgCmd } from "../../types"; + +const opts = { + mod: ct.member({ option: true }), + notify: ct.string({ option: true }), + "notify-channel": ct.textChannel({ option: true }), + clean: ct.bool({ option: true, isSwitch: true }), +}; + +export const KickMsgCmd = modActionsMsgCmd({ + trigger: "kick", + permission: "can_kick", + description: "Kick the specified member", + + signature: [ + { + user: ct.string(), + reason: ct.string({ required: false, catchAll: true }), + + ...opts, + }, + ], + + async run({ pluginData, message: msg, args }) { + const user = await resolveUser(pluginData.client, args.user); + if (!user.id) { + sendErrorMessage(pluginData, msg.channel, `User not found`); + return; + } + + // The moderator who did the action is the message author or, if used, the specified -mod + let mod = msg.member; + if (args.mod) { + if (!(await hasPermission(await pluginData.config.getForMessage(msg), "can_act_as_other"))) { + sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + return; + } + + mod = args.mod; + } + + let contactMethods; + try { + contactMethods = readContactMethodsFromArgs(args); + } catch (e) { + sendErrorMessage(pluginData, msg.channel, e.message); + return; + } + + actualKickCmd( + pluginData, + msg.channel, + msg.member, + user, + args.reason, + [...msg.attachments.values()], + mod, + contactMethods, + args.clean, + ); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts new file mode 100644 index 00000000..46041006 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts @@ -0,0 +1,91 @@ +import { ChannelType } from "discord.js"; +import { slashOptions } from "knub"; +import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { UserNotificationMethod } from "../../../../utils"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { actualKickCmd } from "../../functions/actualCommands/actualKickCmd"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "reason", description: "The reason", required: false }), + slashOptions.user({ name: "mod", description: "The moderator to kick as", required: false }), + slashOptions.string({ + name: "notify", + description: "How to notify", + required: false, + choices: [ + { name: "DM", value: "dm" }, + { name: "Channel", value: "channel" }, + ], + }), + slashOptions.channel({ + name: "notify-channel", + description: "The channel to notify in", + channelTypes: [ChannelType.GuildText, ChannelType.PrivateThread, ChannelType.PublicThread], + required: false, + }), + slashOptions.boolean({ + name: "clean", + description: "Whether or not to delete the member's last messages", + required: false, + }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason of the kick", + }), +]; + +export const KickSlashCmd = { + name: "kick", + configPermission: "can_kick", + description: "Kick the specified member", + allowDms: false, + + signature: [slashOptions.user({ name: "user", description: "The user to kick", required: true }), ...opts], + + async run({ interaction, options, pluginData }) { + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { + sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + let mod = interaction.member; + const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { + channel: interaction.channel, + member: interaction.member, + }); + + if (options.mod) { + if (!canActAsOther) { + sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + return; + } + + mod = options.mod; + } + + let contactMethods: UserNotificationMethod[] | undefined; + try { + contactMethods = readContactMethodsFromArgs(options) ?? undefined; + } catch (e) { + sendErrorMessage(pluginData, interaction, e.message); + return; + } + + actualKickCmd( + pluginData, + interaction, + interaction.member, + options.user, + options.reason || "", + attachments, + mod, + contactMethods, + options.clean, + ); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts new file mode 100644 index 00000000..222dbacc --- /dev/null +++ b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts @@ -0,0 +1,19 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { actualMassBanCmd } from "../../functions/actualCommands/actualMassBanCmd"; +import { modActionsMsgCmd } from "../../types"; + +export const MassBanMsgCmd = modActionsMsgCmd({ + trigger: "massban", + permission: "can_massban", + description: "Mass-ban a list of user IDs", + + signature: [ + { + userIds: ct.string({ rest: true }), + }, + ], + + async run({ pluginData, message: msg, args }) { + actualMassBanCmd(pluginData, msg.channel, args.userIds, msg.member); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts new file mode 100644 index 00000000..74f9ba91 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts @@ -0,0 +1,15 @@ +import { slashOptions } from "knub"; +import { actualMassBanCmd } from "../../functions/actualCommands/actualMassBanCmd"; + +export const MassBanSlashCmd = { + name: "massban", + configPermission: "can_massban", + description: "Mass-ban a list of user IDs", + allowDms: false, + + signature: [slashOptions.string({ name: "user-ids", description: "The list of user IDs to ban", required: true })], + + async run({ interaction, options, pluginData }) { + actualMassBanCmd(pluginData, interaction, options["user-ids"].split(/[\s,\r\n]+/), interaction.member); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts new file mode 100644 index 00000000..0d7793ce --- /dev/null +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts @@ -0,0 +1,19 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { actualMassMuteCmd } from "../../functions/actualCommands/actualMassMuteCmd"; +import { modActionsMsgCmd } from "../../types"; + +export const MassMuteMsgCmd = modActionsMsgCmd({ + trigger: "massmute", + permission: "can_massmute", + description: "Mass-mute a list of user IDs", + + signature: [ + { + userIds: ct.string({ rest: true }), + }, + ], + + async run({ pluginData, message: msg, args }) { + actualMassMuteCmd(pluginData, msg.channel, args.userIds, msg.member); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts new file mode 100644 index 00000000..1650b174 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts @@ -0,0 +1,15 @@ +import { slashOptions } from "knub"; +import { actualMassMuteCmd } from "../../functions/actualCommands/actualMassMuteCmd"; + +export const MassMuteSlashSlashCmd = { + name: "massmute", + configPermission: "can_massmute", + description: "Mass-mute a list of user IDs", + allowDms: false, + + signature: [slashOptions.string({ name: "user-ids", description: "The list of user IDs to mute", required: true })], + + async run({ interaction, options, pluginData }) { + actualMassMuteCmd(pluginData, interaction, options["user-ids"].split(/[\s,\r\n]+/), interaction.member); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts new file mode 100644 index 00000000..8508b00e --- /dev/null +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts @@ -0,0 +1,19 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { actualMassBanCmd } from "../../functions/actualCommands/actualMassBanCmd"; +import { modActionsMsgCmd } from "../../types"; + +export const MassUnbanMsgCmd = modActionsMsgCmd({ + trigger: "massunban", + permission: "can_massunban", + description: "Mass-unban a list of user IDs", + + signature: [ + { + userIds: ct.string({ rest: true }), + }, + ], + + async run({ pluginData, message: msg, args }) { + actualMassBanCmd(pluginData, msg.channel, args.userIds, msg.member); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts new file mode 100644 index 00000000..15f6ca6a --- /dev/null +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts @@ -0,0 +1,15 @@ +import { slashOptions } from "knub"; +import { actualMassUnbanCmd } from "../../functions/actualCommands/actualMassUnbanCmd"; + +export const MassUnbanSlashCmd = { + name: "massunban", + configPermission: "can_massunban", + description: "Mass-unban a list of user IDs", + allowDms: false, + + signature: [slashOptions.string({ name: "user-ids", description: "The list of user IDs to unban", required: true })], + + async run({ interaction, options, pluginData }) { + actualMassUnbanCmd(pluginData, interaction, options["user-ids"].split(/[\s,\r\n]+/), interaction.member); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/MuteCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts similarity index 56% rename from backend/src/plugins/ModActions/commands/MuteCmd.ts rename to backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts index 4c505701..16a5343f 100644 --- a/backend/src/plugins/ModActions/commands/MuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts @@ -1,10 +1,11 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage } from "../../../pluginUtils"; -import { resolveMember, resolveUser } from "../../../utils"; -import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; -import { actualMuteUserCmd } from "../functions/actualMuteUserCmd"; -import { isBanned } from "../functions/isBanned"; -import { modActionsMsgCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { resolveMember, resolveUser } from "../../../../utils"; +import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; +import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; +import { isBanned } from "../../functions/isBanned"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { modActionsMsgCmd } from "../../types"; const opts = { mod: ct.member({ option: true }), @@ -12,7 +13,7 @@ const opts = { "notify-channel": ct.textChannel({ option: true }), }; -export const MuteCmd = modActionsMsgCmd({ +export const MuteMsgCmd = modActionsMsgCmd({ trigger: "mute", permission: "can_mute", description: "Mute the specified member", @@ -73,6 +74,38 @@ export const MuteCmd = modActionsMsgCmd({ return; } - actualMuteUserCmd(pluginData, user, msg, args); + // The moderator who did the action is the message author or, if used, the specified -mod + let mod = msg.member; + let ppId: string | undefined; + + if (args.mod) { + if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { + sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + return; + } + + mod = args.mod; + ppId = msg.author.id; + } + + let contactMethods; + try { + contactMethods = readContactMethodsFromArgs(args); + } catch (e) { + sendErrorMessage(pluginData, msg.channel, e.message); + return; + } + + actualMuteCmd( + pluginData, + msg.channel, + user, + [...msg.attachments.values()], + mod, + ppId, + "time" in args ? args.time ?? undefined : undefined, + args.reason, + contactMethods, + ); }, }); diff --git a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts new file mode 100644 index 00000000..c17200fc --- /dev/null +++ b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts @@ -0,0 +1,130 @@ +import { ChannelType } from "discord.js"; +import { slashOptions } from "knub"; +import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; +import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; +import { isBanned } from "../../functions/isBanned"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "time", description: "The duration of the mute", required: false }), + slashOptions.string({ name: "reason", description: "The reason", required: false }), + slashOptions.user({ name: "mod", description: "The moderator to mute as", required: false }), + slashOptions.string({ + name: "notify", + description: "How to notify", + required: false, + choices: [ + { name: "DM", value: "dm" }, + { name: "Channel", value: "channel" }, + ], + }), + slashOptions.channel({ + name: "notify-channel", + description: "The channel to notify in", + channelTypes: [ChannelType.GuildText, ChannelType.PrivateThread, ChannelType.PublicThread], + required: false, + }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason of the mute", + }), +]; + +export const MuteSlashCmd = { + name: "mute", + configPermission: "can_mute", + description: "Mute the specified member", + allowDms: false, + + signature: [slashOptions.user({ name: "user", description: "The user to mute", required: true }), ...opts], + + async run({ interaction, options, pluginData }) { + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { + sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + const memberToMute = await resolveMember(pluginData.client, pluginData.guild, options.user.id); + + if (!memberToMute) { + const _isBanned = await isBanned(pluginData, options.user.id); + const prefix = pluginData.fullConfig.prefix; + if (_isBanned) { + sendErrorMessage( + pluginData, + interaction, + `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.`, + ); + return; + } else { + // Ask the mod if we should upgrade to a forcemute as the user is not on the server + const reply = await waitForButtonConfirm( + interaction, + { content: "User not found on the server, forcemute instead?" }, + { confirmText: "Yes", cancelText: "No", restrictToId: interaction.member.id }, + ); + + if (!reply) { + sendErrorMessage(pluginData, interaction, "User not on server, mute cancelled by moderator"); + return; + } + } + } + + // Make sure we're allowed to mute this member + if (memberToMute && !canActOn(pluginData, interaction.member, memberToMute)) { + sendErrorMessage(pluginData, interaction, "Cannot mute: insufficient permissions"); + return; + } + + let mod = interaction.member; + let ppId: string | undefined; + const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { + channel: interaction.channel, + member: interaction.member, + }); + + if (options.mod) { + if (!canActAsOther) { + sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + return; + } + + mod = options.mod; + ppId = interaction.user.id; + } + + const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; + if (options.time && !convertedTime) { + sendErrorMessage(pluginData, interaction, `Could not convert ${options.time} to a delay`); + return; + } + + let contactMethods: UserNotificationMethod[] | undefined; + try { + contactMethods = readContactMethodsFromArgs(options) ?? undefined; + } catch (e) { + sendErrorMessage(pluginData, interaction, e.message); + return; + } + + actualMuteCmd( + pluginData, + interaction, + options.user, + attachments, + mod, + ppId, + options.time, + options.reason, + contactMethods, + ); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts index c7122fe9..14336d89 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts @@ -1,7 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { sendErrorMessage } from "../../../../pluginUtils"; import { resolveUser } from "../../../../utils"; -import { actualNoteCmd } from "../../functions/actualNoteCmd"; +import { actualNoteCmd } from "../../functions/actualCommands/actualNoteCmd"; import { modActionsMsgCmd } from "../../types"; export const NoteMsgCmd = modActionsMsgCmd({ diff --git a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts index 82b38be7..50fd2735 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts @@ -1,38 +1,27 @@ -import { ApplicationCommandOptionType, ChatInputCommandInteraction } from "discord.js"; import { slashOptions } from "knub"; import { sendErrorMessage } from "../../../../pluginUtils"; -import { actualNoteCmd } from "../../functions/actualNoteCmd"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { actualNoteCmd } from "../../functions/actualCommands/actualNoteCmd"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "note", description: "The note to add to the user", required: false }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the note", + }), +]; export const NoteSlashCmd = { name: "note", + configPermission: "can_note", description: "Add a note to the specified user", allowDms: false, - configPermission: "can_note", - signature: [ - slashOptions.user({ name: "user", description: "The user to add a note to", required: true }), - slashOptions.string({ name: "note", description: "The note to add to the user", required: false }), - ...new Array(10).fill(0).map((_, i) => { - return { - name: `attachment${i + 1}`, - description: "An attachment to add to the note", - type: ApplicationCommandOptionType.Attachment, - required: false, - resolveValue: (interaction: ChatInputCommandInteraction) => { - return interaction.options.getAttachment(`attachment${i + 1}`); - }, - getExtraAPIProps: () => ({}), - }; - }), - ], + signature: [slashOptions.user({ name: "user", description: "The user to add a note to", required: true }), ...opts], async run({ interaction, options, pluginData }) { - const attachments = new Array(10) - .fill(0) - .map((_, i) => { - return options[`attachment${i + 1}`]; - }) - .filter((a) => a); + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.note || options.note.trim() === "") && attachments.length < 1) { sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts new file mode 100644 index 00000000..1d9bd37d --- /dev/null +++ b/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts @@ -0,0 +1,45 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { resolveUser } from "../../../../utils"; +import { actualUnbanCmd } from "../../functions/actualCommands/actualUnbanCmd"; +import { modActionsMsgCmd } from "../../types"; + +const opts = { + mod: ct.member({ option: true }), +}; + +export const UnbanMsgCmd = modActionsMsgCmd({ + trigger: "unban", + permission: "can_unban", + description: "Unban the specified member", + + signature: [ + { + user: ct.string(), + reason: ct.string({ required: false, catchAll: true }), + + ...opts, + }, + ], + + async run({ pluginData, message: msg, args }) { + const user = await resolveUser(pluginData.client, args.user); + if (!user.id) { + sendErrorMessage(pluginData, msg.channel, `User not found`); + return; + } + + // The moderator who did the action is the message author or, if used, the specified -mod + let mod = msg.member; + if (args.mod) { + if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg, channelId: msg.channel.id }))) { + sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + return; + } + + mod = args.mod; + } + + actualUnbanCmd(pluginData, msg.channel, msg.author.id, user, args.reason, [...msg.attachments.values()], mod); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts new file mode 100644 index 00000000..e85cfdfb --- /dev/null +++ b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts @@ -0,0 +1,50 @@ +import { slashOptions } from "knub"; +import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { actualUnbanCmd } from "../../functions/actualCommands/actualUnbanCmd"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "reason", description: "The reason", required: false }), + slashOptions.user({ name: "mod", description: "The moderator to unban as", required: false }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason of the unban", + }), +]; + +export const UnbanSlashCmd = { + name: "unban", + configPermission: "can_unban", + description: "Unban the specified member", + allowDms: false, + + signature: [slashOptions.user({ name: "user", description: "The user to unban", required: true }), ...opts], + + async run({ interaction, options, pluginData }) { + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { + sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + let mod = interaction.member; + const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { + channel: interaction.channel, + member: interaction.member, + }); + + if (options.mod) { + if (!canActAsOther) { + sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + return; + } + + mod = options.mod; + } + + actualUnbanCmd(pluginData, interaction, interaction.user.id, options.user, options.reason, attachments, mod); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts new file mode 100644 index 00000000..94c029a2 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts @@ -0,0 +1,19 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { actualHideCaseCmd } from "../../functions/actualCommands/actualHideCaseCmd"; +import { modActionsMsgCmd } from "../../types"; + +export const UnhideCaseMsgCmd = modActionsMsgCmd({ + trigger: ["unhide", "unhidecase", "unhide_case"], + permission: "can_hidecase", + description: "Un-hide the specified case, making it appear in !cases and !info again", + + signature: [ + { + caseNum: ct.number({ rest: true }), + }, + ], + + async run({ pluginData, message: msg, args }) { + actualHideCaseCmd(pluginData, msg.channel, args.caseNum); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts new file mode 100644 index 00000000..d0a66d7c --- /dev/null +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts @@ -0,0 +1,17 @@ +import { slashOptions } from "knub"; +import { actualUnhideCaseCmd } from "../../functions/actualCommands/actualUnhideCaseCmd"; + +export const UnhideCaseSlashCmd = { + name: "unhidecase", + configPermission: "can_hidecase", + description: "Un-hide the specified case", + allowDms: false, + + signature: [ + slashOptions.string({ name: "case-number", description: "The number of the case to unhide", required: true }), + ], + + async run({ interaction, options, pluginData }) { + actualUnhideCaseCmd(pluginData, interaction, options["case-number"].split(/[\s,]+/).map(Number)); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts similarity index 65% rename from backend/src/plugins/ModActions/commands/UnmuteCmd.ts rename to backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts index 3a4171ac..8d7e111a 100644 --- a/backend/src/plugins/ModActions/commands/UnmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts @@ -1,17 +1,17 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; -import { canActOn, sendErrorMessage } from "../../../pluginUtils"; -import { resolveMember, resolveUser } from "../../../utils"; -import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; -import { actualUnmuteCmd } from "../functions/actualUnmuteUserCmd"; -import { isBanned } from "../functions/isBanned"; -import { modActionsMsgCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { resolveMember, resolveUser } from "../../../../utils"; +import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; +import { MutesPlugin } from "../../../Mutes/MutesPlugin"; +import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { isBanned } from "../../functions/isBanned"; +import { modActionsMsgCmd } from "../../types"; const opts = { mod: ct.member({ option: true }), }; -export const UnmuteCmd = modActionsMsgCmd({ +export const UnmuteMsgCmd = modActionsMsgCmd({ trigger: "unmute", permission: "can_mute", description: "Unmute the specified member", @@ -84,6 +84,29 @@ export const UnmuteCmd = modActionsMsgCmd({ return; } - actualUnmuteCmd(pluginData, user, msg, args); + // The moderator who did the action is the message author or, if used, the specified -mod + let mod = msg.member; + let ppId: string | undefined; + + if (args.mod) { + if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { + sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + return; + } + + mod = args.mod; + ppId = msg.author.id; + } + + actualUnmuteCmd( + pluginData, + msg.channel, + user, + [...msg.attachments.values()], + mod, + ppId, + "time" in args ? args.time ?? undefined : undefined, + args.reason, + ); }, }); diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts new file mode 100644 index 00000000..04526be6 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts @@ -0,0 +1,108 @@ +import { slashOptions } from "knub"; +import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { convertDelayStringToMS, resolveMember } from "../../../../utils"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; +import { MutesPlugin } from "../../../Mutes/MutesPlugin"; +import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { isBanned } from "../../functions/isBanned"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "time", description: "The duration of the unmute", required: false }), + slashOptions.string({ name: "reason", description: "The reason", required: false }), + slashOptions.user({ name: "mod", description: "The moderator to unmute as", required: false }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason of the unmute", + }), +]; + +export const UnmuteSlashCmd = { + name: "unmute", + configPermission: "can_mute", + description: "Unmute the specified member", + allowDms: false, + + signature: [slashOptions.user({ name: "user", description: "The user to unmute", required: true }), ...opts], + + async run({ interaction, options, pluginData }) { + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { + sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + const memberToUnmute = await resolveMember(pluginData.client, pluginData.guild, options.user.id); + const mutesPlugin = pluginData.getPlugin(MutesPlugin); + const hasMuteRole = memberToUnmute && mutesPlugin.hasMutedRole(memberToUnmute); + + // Check if they're muted in the first place + if ( + !(await pluginData.state.mutes.isMuted(options.user.id)) && + !hasMuteRole && + !memberToUnmute?.isCommunicationDisabled() + ) { + sendErrorMessage(pluginData, interaction, "Cannot unmute: member is not muted"); + return; + } + + if (!memberToUnmute) { + const banned = await isBanned(pluginData, options.user.id); + const prefix = pluginData.fullConfig.prefix; + if (banned) { + sendErrorMessage( + pluginData, + interaction, + `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.`, + ); + return; + } else { + // Ask the mod if we should upgrade to a forceunmute as the user is not on the server + const reply = await waitForButtonConfirm( + interaction, + { content: "User not on server, forceunmute instead?" }, + { confirmText: "Yes", cancelText: "No", restrictToId: interaction.user.id }, + ); + + if (!reply) { + sendErrorMessage(pluginData, interaction, "User not on server, unmute cancelled by moderator"); + return; + } + } + } + + // Make sure we're allowed to unmute this member + if (memberToUnmute && !canActOn(pluginData, interaction.member, memberToUnmute)) { + sendErrorMessage(pluginData, interaction, "Cannot unmute: insufficient permissions"); + return; + } + + let mod = interaction.member; + let ppId: string | undefined; + const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { + channel: interaction.channel, + member: interaction.member, + }); + + if (options.mod) { + if (!canActAsOther) { + sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + return; + } + + mod = options.mod; + ppId = interaction.user.id; + } + + const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; + if (options.time && !convertedTime) { + sendErrorMessage(pluginData, interaction, `Could not convert ${options.time} to a delay`); + return; + } + + actualUnmuteCmd(pluginData, interaction, options.user, attachments, mod, ppId, options.time, options.reason); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/UpdateCmd.ts b/backend/src/plugins/ModActions/commands/update/UpdateMsgCmd.ts similarity index 57% rename from backend/src/plugins/ModActions/commands/UpdateCmd.ts rename to backend/src/plugins/ModActions/commands/update/UpdateMsgCmd.ts index 59c68b0d..73c74f36 100644 --- a/backend/src/plugins/ModActions/commands/UpdateCmd.ts +++ b/backend/src/plugins/ModActions/commands/update/UpdateMsgCmd.ts @@ -1,8 +1,8 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { updateCase } from "../functions/updateCase"; -import { modActionsMsgCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { updateCase } from "../../functions/updateCase"; +import { modActionsMsgCmd } from "../../types"; -export const UpdateCmd = modActionsMsgCmd({ +export const UpdateMsgCmd = modActionsMsgCmd({ trigger: ["update", "reason"], permission: "can_note", description: @@ -19,6 +19,6 @@ export const UpdateCmd = modActionsMsgCmd({ ], async run({ pluginData, message: msg, args }) { - await updateCase(pluginData, msg, args); + await updateCase(pluginData, msg.channel, msg.author, args.caseNumber, args.note, [...msg.attachments.values()]); }, }); diff --git a/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts b/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts new file mode 100644 index 00000000..4f6fdae2 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts @@ -0,0 +1,33 @@ +import { slashOptions } from "knub"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { updateCase } from "../../functions/updateCase"; +import { NUMBER_ATTACHMENTS_CASE_UPDATE } from "../constants"; + +const opts = [ + slashOptions.string({ name: "case-number", description: "The number of the case to update", required: false }), + slashOptions.string({ name: "reason", description: "The note to add to the case", required: false }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_UPDATE, { + name: "attachment", + description: "An attachment to add to the update", + }), +]; + +export const UpdateSlashCmd = { + name: "update", + configPermission: "can_note", + description: "Update the specified case (or your latest case) by adding more notes to it", + allowDms: false, + + signature: [...opts], + + async run({ interaction, options, pluginData }) { + await updateCase( + pluginData, + interaction, + interaction.user, + options.caseNumber, + options.note, + retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_UPDATE, options, "attachment"), + ); + }, +}; diff --git a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts new file mode 100644 index 00000000..4baeb3c1 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts @@ -0,0 +1,79 @@ +import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { errorMessage, resolveMember, resolveUser } from "../../../../utils"; +import { actualWarnCmd } from "../../functions/actualCommands/actualWarnCmd"; +import { isBanned } from "../../functions/isBanned"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { modActionsMsgCmd } from "../../types"; + +export const WarnMsgCmd = modActionsMsgCmd({ + trigger: "warn", + permission: "can_warn", + description: "Send a warning to the specified user", + + signature: { + user: ct.string(), + reason: ct.string({ catchAll: true }), + + mod: ct.member({ option: true }), + notify: ct.string({ option: true }), + "notify-channel": ct.textChannel({ option: true }), + }, + + async run({ pluginData, message: msg, args }) { + const user = await resolveUser(pluginData.client, args.user); + if (!user.id) { + sendErrorMessage(pluginData, msg.channel, `User not found`); + return; + } + + const memberToWarn = await resolveMember(pluginData.client, pluginData.guild, user.id); + + if (!memberToWarn) { + const _isBanned = await isBanned(pluginData, user.id); + if (_isBanned) { + sendErrorMessage(pluginData, msg.channel, `User is banned`); + } else { + sendErrorMessage(pluginData, msg.channel, `User not found on the server`); + } + + return; + } + + // Make sure we're allowed to warn this member + if (!canActOn(pluginData, msg.member, memberToWarn)) { + sendErrorMessage(pluginData, msg.channel, "Cannot warn: insufficient permissions"); + return; + } + + // The moderator who did the action is the message author or, if used, the specified -mod + let mod = msg.member; + if (args.mod) { + if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { + msg.channel.send(errorMessage("You don't have permission to use -mod")); + return; + } + + mod = args.mod; + } + + let contactMethods; + try { + contactMethods = readContactMethodsFromArgs(args); + } catch (e) { + sendErrorMessage(pluginData, msg.channel, e.message); + return; + } + + actualWarnCmd( + pluginData, + msg.channel, + msg.author.id, + mod, + memberToWarn, + args.reason, + [...msg.attachments.values()], + contactMethods, + ); + }, +}); diff --git a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts new file mode 100644 index 00000000..025f1981 --- /dev/null +++ b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts @@ -0,0 +1,105 @@ +import { ChannelType } from "discord.js"; +import { slashOptions } from "knub"; +import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { UserNotificationMethod, resolveMember } from "../../../../utils"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { actualWarnCmd } from "../../functions/actualCommands/actualWarnCmd"; +import { isBanned } from "../../functions/isBanned"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "reason", description: "The reason", required: false }), + slashOptions.user({ name: "mod", description: "The moderator to warn as", required: false }), + slashOptions.string({ + name: "notify", + description: "How to notify", + required: false, + choices: [ + { name: "DM", value: "dm" }, + { name: "Channel", value: "channel" }, + ], + }), + slashOptions.channel({ + name: "notify-channel", + description: "The channel to notify in", + channelTypes: [ChannelType.GuildText, ChannelType.PrivateThread, ChannelType.PublicThread], + required: false, + }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason of the warn", + }), +]; + +export const WarnSlashCmd = { + name: "warn", + configPermission: "can_warn", + description: "Send a warning to the specified user", + allowDms: false, + + signature: [slashOptions.user({ name: "user", description: "The user to warn", required: true }), ...opts], + + async run({ interaction, options, pluginData }) { + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { + sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + const memberToWarn = await resolveMember(pluginData.client, pluginData.guild, options.user.id); + + if (!memberToWarn) { + const _isBanned = await isBanned(pluginData, options.user.id); + if (_isBanned) { + sendErrorMessage(pluginData, interaction, `User is banned`); + } else { + sendErrorMessage(pluginData, interaction, `User not found on the server`); + } + + return; + } + + // Make sure we're allowed to warn this member + if (!canActOn(pluginData, interaction.member, memberToWarn)) { + sendErrorMessage(pluginData, interaction, "Cannot warn: insufficient permissions"); + return; + } + + let mod = interaction.member; + const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { + channel: interaction.channel, + member: interaction.member, + }); + + if (options.mod) { + if (!canActAsOther) { + sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + return; + } + + mod = options.mod; + } + + let contactMethods: UserNotificationMethod[] | undefined; + try { + contactMethods = readContactMethodsFromArgs(options) ?? undefined; + } catch (e) { + sendErrorMessage(pluginData, interaction, e.message); + return; + } + + actualWarnCmd( + pluginData, + interaction, + interaction.user.id, + mod, + memberToWarn, + options.reason ?? "", + attachments, + contactMethods, + ); + }, +}; diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts new file mode 100644 index 00000000..572d450c --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts @@ -0,0 +1,55 @@ +import { Attachment, ChatInputCommandInteraction, GuildMember, TextBasedChannel, User } from "discord.js"; +import { GuildPluginData } from "knub"; +import { CaseTypes } from "../../../../data/CaseTypes"; +import { Case } from "../../../../data/entities/Case"; +import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { UnknownUser, renderUserUsername, resolveMember } from "../../../../utils"; +import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { LogsPlugin } from "../../../Logs/LogsPlugin"; +import { ModActionsPluginType } from "../../types"; +import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; + +export async function actualAddCaseCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + author: GuildMember, + mod: GuildMember, + attachments: Array, + user: User | UnknownUser, + type: keyof CaseTypes, + reason: string, +) { + // If the user exists as a guild member, make sure we can act on them first + const member = await resolveMember(pluginData.client, pluginData.guild, user.id); + if (member && !canActOn(pluginData, author, member)) { + sendErrorMessage(pluginData, context, "Cannot add case on this user: insufficient permissions"); + return; + } + + const formattedReason = formatReasonWithAttachments(reason, attachments); + + // Create the case + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const theCase: Case = await casesPlugin.createCase({ + userId: user.id, + modId: mod.id, + type: CaseTypes[type], + reason: formattedReason, + ppId: mod.id !== author.id ? author.id : undefined, + }); + + if (user) { + sendSuccessMessage(pluginData, context, `Case #${theCase.case_number} created for **${renderUserUsername(user)}**`); + } else { + sendSuccessMessage(pluginData, context, `Case #${theCase.case_number} created`); + } + + // Log the action + pluginData.getPlugin(LogsPlugin).logCaseCreate({ + mod: mod.user, + userId: user.id, + caseNum: theCase.case_number, + caseType: type.toUpperCase(), + reason: formattedReason, + }); +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts new file mode 100644 index 00000000..5b665884 --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts @@ -0,0 +1,182 @@ +import { Attachment, ChatInputCommandInteraction, GuildMember, TextBasedChannel, User } from "discord.js"; +import humanizeDuration from "humanize-duration"; +import { GuildPluginData } from "knub"; +import { getMemberLevel } from "knub/helpers"; +import { CaseTypes } from "../../../../data/CaseTypes"; +import { clearExpiringTempban, registerExpiringTempban } from "../../../../data/loops/expiringTempbansLoop"; +import { canActOn, isContextInteraction, sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { UnknownUser, UserNotificationMethod, renderUserUsername, resolveMember } from "../../../../utils"; +import { banLock } from "../../../../utils/lockNameHelpers"; +import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; +import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { LogsPlugin } from "../../../Logs/LogsPlugin"; +import { ModActionsPluginType } from "../../types"; +import { banUserId } from "../banUserId"; +import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { isBanned } from "../isBanned"; + +export async function actualBanCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + user: User | UnknownUser, + time: number | null, + reason: string, + attachments: Attachment[], + author: GuildMember, + mod: GuildMember, + contactMethods?: UserNotificationMethod[], + deleteDays?: number, +) { + const memberToBan = await resolveMember(pluginData.client, pluginData.guild, user.id); + const formattedReason = formatReasonWithAttachments(reason, attachments); + + // acquire a lock because of the needed user-inputs below (if banned/not on server) + const lock = await pluginData.locks.acquire(banLock(user)); + let forceban = false; + const existingTempban = await pluginData.state.tempbans.findExistingTempbanForUserId(user.id); + + if (!memberToBan) { + const banned = await isBanned(pluginData, user.id); + + if (!banned) { + // Ask the mod if we should upgrade to a forceban as the user is not on the server + const reply = await waitForButtonConfirm( + context, + { content: "User not on server, forceban instead?" }, + { confirmText: "Yes", cancelText: "No", restrictToId: author.id }, + ); + + if (!reply) { + sendErrorMessage(pluginData, context, "User not on server, ban cancelled by moderator"); + lock.unlock(); + return; + } else { + forceban = true; + } + } + + // Abort if trying to ban user indefinitely if they are already banned indefinitely + if (!existingTempban && !time) { + sendErrorMessage(pluginData, context, `User is already banned indefinitely.`); + return; + } + + // Ask the mod if we should update the existing ban + const reply = await waitForButtonConfirm( + context, + { content: "Failed to message the user. Log the warning anyway?" }, + { confirmText: "Yes", cancelText: "No", restrictToId: author.id }, + ); + + if (!reply) { + sendErrorMessage(pluginData, context, "User already banned, update cancelled by moderator"); + lock.unlock(); + return; + } + + // Update or add new tempban / remove old tempban + if (time && time > 0) { + if (existingTempban) { + await pluginData.state.tempbans.updateExpiryTime(user.id, time, mod.id); + } else { + await pluginData.state.tempbans.addTempban(user.id, time, mod.id); + } + const tempban = (await pluginData.state.tempbans.findExistingTempbanForUserId(user.id))!; + registerExpiringTempban(tempban); + } else if (existingTempban) { + clearExpiringTempban(existingTempban); + pluginData.state.tempbans.clear(user.id); + } + + // Create a new case for the updated ban since we never stored the old case id and log the action + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const createdCase = await casesPlugin.createCase({ + modId: mod.id, + type: CaseTypes.Ban, + userId: user.id, + reason: formattedReason, + noteDetails: [`Ban updated to ${time ? humanizeDuration(time) : "indefinite"}`], + }); + if (time) { + pluginData.getPlugin(LogsPlugin).logMemberTimedBan({ + mod: mod.user, + user, + caseNumber: createdCase.case_number, + reason: formattedReason, + banTime: humanizeDuration(time), + }); + } else { + pluginData.getPlugin(LogsPlugin).logMemberBan({ + mod: mod.user, + user, + caseNumber: createdCase.case_number, + reason: formattedReason, + }); + } + + sendSuccessMessage( + pluginData, + context, + `Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`, + ); + lock.unlock(); + return; + } + + // Make sure we're allowed to ban this member if they are on the server + if (!forceban && !canActOn(pluginData, author, memberToBan!)) { + const ourLevel = getMemberLevel(pluginData, author); + const targetLevel = getMemberLevel(pluginData, memberToBan!); + sendErrorMessage( + pluginData, + context, + `Cannot ban: target permission level is equal or higher to yours, ${targetLevel} >= ${ourLevel}`, + ); + lock.unlock(); + return; + } + + const matchingConfig = await pluginData.config.getMatchingConfig({ + member: author, + channel: isContextInteraction(context) ? context.channel : context, + }); + const deleteMessageDays = deleteDays ?? matchingConfig.ban_delete_message_days; + const banResult = await banUserId( + pluginData, + user.id, + formattedReason, + { + contactMethods, + caseArgs: { + modId: mod.id, + ppId: mod.id !== author.id ? author.id : undefined, + }, + deleteMessageDays, + modId: mod.id, + }, + time ?? undefined, + ); + + if (banResult.status === "failed") { + sendErrorMessage(pluginData, context, `Failed to ban member: ${banResult.error}`); + lock.unlock(); + return; + } + + let forTime = ""; + if (time && time > 0) { + forTime = `for ${humanizeDuration(time)} `; + } + + // Confirm the action to the moderator + let response = ""; + if (!forceban) { + response = `Banned **${renderUserUsername(user)}** ${forTime}(Case #${banResult.case.case_number})`; + if (banResult.notifyResult.text) response += ` (${banResult.notifyResult.text})`; + } else { + response = `Member forcebanned ${forTime}(Case #${banResult.case.case_number})`; + } + + lock.unlock(); + sendSuccessMessage(pluginData, context, response); +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts new file mode 100644 index 00000000..38ddf2bf --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts @@ -0,0 +1,24 @@ +import { ChatInputCommandInteraction, TextBasedChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { sendContextResponse, sendErrorMessage } from "../../../../pluginUtils"; +import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { ModActionsPluginType } from "../../types"; + +export async function actualCaseCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + authorId: string, + caseNumber: number, +) { + const theCase = await pluginData.state.cases.findByCaseNumber(caseNumber); + + if (!theCase) { + sendErrorMessage(pluginData, context, "Case not found"); + return; + } + + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const embed = await casesPlugin.getCaseEmbed(theCase.id, authorId); + + sendContextResponse(context, embed); +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts new file mode 100644 index 00000000..22a16e93 --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts @@ -0,0 +1,258 @@ +import { APIEmbed, ChatInputCommandInteraction, TextBasedChannel, User } from "discord.js"; +import { GuildPluginData } from "knub"; +import { In } from "typeorm"; +import { FindOptionsWhere } from "typeorm/find-options/FindOptionsWhere"; +import { CaseTypes } from "../../../../data/CaseTypes"; +import { Case } from "../../../../data/entities/Case"; +import { sendContextResponse, sendErrorMessage } from "../../../../pluginUtils"; +import { + UnknownUser, + chunkArray, + emptyEmbedValue, + renderUserUsername, + resolveUser, + trimLines, +} from "../../../../utils"; +import { asyncMap } from "../../../../utils/async"; +import { createPaginatedMessage } from "../../../../utils/createPaginatedMessage"; +import { getChunkedEmbedFields } from "../../../../utils/getChunkedEmbedFields"; +import { getGuildPrefix } from "../../../../utils/getGuildPrefix"; +import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { ModActionsPluginType } from "../../types"; + +const casesPerPage = 5; +const maxExpandedCases = 8; + +async function sendExpandedCases( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + casesCount: number, + cases: Case[], +) { + if (casesCount > maxExpandedCases) { + await sendContextResponse(context, "Too many cases for expanded view. Please use compact view instead."); + + return; + } + + const casesPlugin = pluginData.getPlugin(CasesPlugin); + + for (const theCase of cases) { + const embed = await casesPlugin.getCaseEmbed(theCase.id); + await sendContextResponse(context, embed); + } +} + +async function casesUserCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + author: User, + modId: string | null, + user: User | UnknownUser, + modName: string, + typesToShow: CaseTypes[], + hidden: boolean | null, + expand: boolean | null, +) { + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const casesFilters: Omit, "guild_id" | "user_id"> = { type: In(typesToShow) }; + + if (modId) { + casesFilters.mod_id = modId; + } + + const cases = await pluginData.state.cases.with("notes").getByUserId(user.id, casesFilters); + const normalCases = cases.filter((c) => !c.is_hidden); + const hiddenCases = cases.filter((c) => c.is_hidden); + + const userName = + user instanceof UnknownUser && cases.length ? cases[cases.length - 1].user_name : renderUserUsername(user); + + if (cases.length === 0) { + await sendContextResponse(context, `No cases found for **${userName}**${modId ? ` by ${modName}` : ""}.`); + return; + } + + const casesToDisplay = hidden ? cases : normalCases; + + if (!casesToDisplay.length) { + await sendContextResponse( + context, + `No normal cases found for **${userName}**. Use "-hidden" to show ${cases.length} hidden cases.`, + ); + + return; + } + + if (expand) { + sendExpandedCases(pluginData, context, casesToDisplay.length, casesToDisplay); + return; + } + + // Compact view (= regular message with a preview of each case) + const lines = await asyncMap(casesToDisplay, (c) => casesPlugin.getCaseSummary(c, true, author.id)); + + const prefix = getGuildPrefix(pluginData); + const linesPerChunk = 10; + const lineChunks = chunkArray(lines, linesPerChunk); + + const footerField = { + name: emptyEmbedValue, + value: trimLines(` + Use \`${prefix}case \` to see more information about an individual case + `), + }; + + for (const [i, linesInChunk] of lineChunks.entries()) { + const isLastChunk = i === lineChunks.length - 1; + + if (isLastChunk && !hidden && hiddenCases.length) { + if (hiddenCases.length === 1) { + linesInChunk.push(`*+${hiddenCases.length} hidden case, use "-hidden" to show it*`); + } else { + linesInChunk.push(`*+${hiddenCases.length} hidden cases, use "-hidden" to show them*`); + } + } + + const chunkStart = i * linesPerChunk + 1; + const chunkEnd = Math.min((i + 1) * linesPerChunk, lines.length); + + const embed = { + author: { + name: + lineChunks.length === 1 + ? `Cases for ${userName}${modId ? ` by ${modName}` : ""} (${lines.length} total)` + : `Cases ${chunkStart}–${chunkEnd} of ${lines.length} for ${userName}`, + icon_url: user instanceof User ? user.displayAvatarURL() : undefined, + }, + fields: [ + ...getChunkedEmbedFields(emptyEmbedValue, linesInChunk.join("\n")), + ...(isLastChunk ? [footerField] : []), + ], + } satisfies APIEmbed; + + sendContextResponse(context, { embeds: [embed] }); + } +} + +async function casesModCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + author: User, + modId: string | null, + mod: User | UnknownUser, + modName: string, + typesToShow: CaseTypes[], + hidden: boolean | null, + expand: boolean | null, +) { + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const caseFilters = { type: In(typesToShow), is_hidden: !!hidden }; + + const totalCases = await casesPlugin.getTotalCasesByMod(modId ?? author.id, caseFilters); + + if (totalCases === 0) { + sendErrorMessage(pluginData, context, `No cases by **${modName}**`); + return; + } + + const totalPages = Math.max(Math.ceil(totalCases / casesPerPage), 1); + const prefix = getGuildPrefix(pluginData); + + if (expand) { + // Expanded view (= individual case embeds) + const cases = totalCases > 8 ? [] : await casesPlugin.getRecentCasesByMod(modId ?? author.id, 8, 0, caseFilters); + + sendExpandedCases(pluginData, context, totalCases, cases); + return; + } + + createPaginatedMessage( + pluginData.client, + context, + totalPages, + async (page) => { + const cases = await casesPlugin.getRecentCasesByMod( + modId ?? author.id, + casesPerPage, + (page - 1) * casesPerPage, + caseFilters, + ); + + const lines = await asyncMap(cases, (c) => casesPlugin.getCaseSummary(c, true, author.id)); + const firstCaseNum = (page - 1) * casesPerPage + 1; + const lastCaseNum = firstCaseNum - 1 + Math.min(cases.length, casesPerPage); + const title = `Most recent cases ${firstCaseNum}-${lastCaseNum} of ${totalCases} by ${modName}`; + + const embed = { + author: { + name: title, + icon_url: mod instanceof User ? mod.displayAvatarURL() : undefined, + }, + fields: [ + ...getChunkedEmbedFields(emptyEmbedValue, lines.join("\n")), + { + name: emptyEmbedValue, + value: trimLines(` + Use \`${prefix}case \` to see more information about an individual case + Use \`${prefix}cases \` to see a specific user's cases + `), + }, + ], + } satisfies APIEmbed; + + return { embeds: [embed] }; + }, + { + limitToUserId: author.id, + }, + ); +} + +export async function actualCasesCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + modId: string | null, + user: User | UnknownUser | null, + author: User, + notes: boolean | null, + warns: boolean | null, + mutes: boolean | null, + unmutes: boolean | null, + bans: boolean | null, + unbans: boolean | null, + reverseFilters: boolean | null, + hidden: boolean | null, + expand: boolean | null, +) { + const mod = modId ? await resolveUser(pluginData.client, modId) : null; + const modName = modId ? (mod instanceof User ? renderUserUsername(mod) : modId) : renderUserUsername(author); + + let typesToShow: CaseTypes[] = []; + + if (notes) typesToShow.push(CaseTypes.Note); + if (warns) typesToShow.push(CaseTypes.Warn); + if (mutes) typesToShow.push(CaseTypes.Mute); + if (unmutes) typesToShow.push(CaseTypes.Unmute); + if (bans) typesToShow.push(CaseTypes.Ban); + if (unbans) typesToShow.push(CaseTypes.Unban); + + if (typesToShow.length === 0) { + typesToShow = [CaseTypes.Note, CaseTypes.Warn, CaseTypes.Mute, CaseTypes.Unmute, CaseTypes.Ban, CaseTypes.Unban]; + } else { + if (reverseFilters) { + typesToShow = [ + CaseTypes.Note, + CaseTypes.Warn, + CaseTypes.Mute, + CaseTypes.Unmute, + CaseTypes.Ban, + CaseTypes.Unban, + ].filter((t) => !typesToShow.includes(t)); + } + } + + user + ? casesUserCmd(pluginData, context, author, modId!, user, modName, typesToShow, hidden, expand) + : casesModCmd(pluginData, context, author, modId!, mod!, modName, typesToShow, hidden, expand); +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts new file mode 100644 index 00000000..3fac80cf --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts @@ -0,0 +1,95 @@ +import { ChatInputCommandInteraction, GuildMember, TextBasedChannel } from "discord.js"; +import { GuildPluginData, helpers } from "knub"; +import { Case } from "../../../../data/entities/Case"; +import { + isContextInteraction, + sendContextResponse, + sendErrorMessage, + sendSuccessMessage, +} from "../../../../pluginUtils"; +import { SECONDS } from "../../../../utils"; +import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { LogsPlugin } from "../../../Logs/LogsPlugin"; +import { TimeAndDatePlugin } from "../../../TimeAndDate/TimeAndDatePlugin"; +import { ModActionsPluginType } from "../../types"; + +export async function actualDeleteCaseCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + author: GuildMember, + caseNumbers: number[], + force: boolean, +) { + const failed: number[] = []; + const validCases: Case[] = []; + let cancelled = 0; + + for (const num of caseNumbers) { + const theCase = await pluginData.state.cases.findByCaseNumber(num); + if (!theCase) { + failed.push(num); + continue; + } + + validCases.push(theCase); + } + + if (failed.length === caseNumbers.length) { + sendErrorMessage(pluginData, context, "None of the cases were found!"); + return; + } + + for (const theCase of validCases) { + if (!force) { + const cases = pluginData.getPlugin(CasesPlugin); + const embedContent = await cases.getCaseEmbed(theCase); + sendContextResponse(context, { + ...embedContent, + content: "Delete the following case? Answer 'Yes' to continue, 'No' to cancel.", + }); + + const reply = await helpers.waitForReply( + pluginData.client, + isContextInteraction(context) ? context.channel! : context, + author.id, + 15 * SECONDS, + ); + const normalizedReply = (reply?.content || "").toLowerCase().trim(); + if (normalizedReply !== "yes" && normalizedReply !== "y") { + sendContextResponse(context, "Cancelled. Case was not deleted."); + cancelled++; + continue; + } + } + + const deletedByName = author.user.tag; + + const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); + const deletedAt = timeAndDate.inGuildTz().format(timeAndDate.getDateFormat("pretty_datetime")); + + await pluginData.state.cases.softDelete( + theCase.id, + author.id, + deletedByName, + `Case deleted by **${deletedByName}** (\`${author.id}\`) on ${deletedAt}`, + ); + + const logs = pluginData.getPlugin(LogsPlugin); + logs.logCaseDelete({ + mod: author, + case: theCase, + }); + } + + const failedAddendum = + failed.length > 0 + ? `\nThe following cases were not found: ${failed.toString().replace(new RegExp(",", "g"), ", ")}` + : ""; + const amt = validCases.length - cancelled; + if (amt === 0) { + sendErrorMessage(pluginData, context, "All deletions were cancelled, no cases were deleted."); + return; + } + + sendSuccessMessage(pluginData, context, `${amt} case${amt === 1 ? " was" : "s were"} deleted!${failedAddendum}`); +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts new file mode 100644 index 00000000..095e06a7 --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts @@ -0,0 +1,60 @@ +import { Attachment, ChatInputCommandInteraction, GuildMember, Snowflake, TextBasedChannel, User } from "discord.js"; +import { GuildPluginData } from "knub"; +import { CaseTypes } from "../../../../data/CaseTypes"; +import { LogType } from "../../../../data/LogType"; +import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { DAYS, MINUTES, UnknownUser } from "../../../../utils"; +import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { LogsPlugin } from "../../../Logs/LogsPlugin"; +import { IgnoredEventType, ModActionsPluginType } from "../../types"; +import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { ignoreEvent } from "../ignoreEvent"; + +export async function actualForceBanCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + authorId: string, + user: User | UnknownUser, + reason: string, + attachments: Array, + mod: GuildMember, +) { + const formattedReason = formatReasonWithAttachments(reason, attachments); + + ignoreEvent(pluginData, IgnoredEventType.Ban, user.id); + pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, user.id); + + try { + // FIXME: Use banUserId()? + await pluginData.guild.bans.create(user.id as Snowflake, { + deleteMessageSeconds: (1 * DAYS) / MINUTES, + reason: formattedReason ?? undefined, + }); + } catch { + sendErrorMessage(pluginData, context, "Failed to forceban member"); + return; + } + + // Create a case + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const createdCase = await casesPlugin.createCase({ + userId: user.id, + modId: mod.id, + type: CaseTypes.Ban, + reason: formattedReason, + ppId: mod.id !== authorId ? authorId : undefined, + }); + + // Confirm the action + sendSuccessMessage(pluginData, context, `Member forcebanned (Case #${createdCase.case_number})`); + + // Log the action + pluginData.getPlugin(LogsPlugin).logMemberForceban({ + mod, + userId: user.id, + caseNumber: createdCase.case_number, + reason: formattedReason, + }); + + pluginData.state.events.emit("ban", user.id, formattedReason); +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts new file mode 100644 index 00000000..d500ce5f --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts @@ -0,0 +1,38 @@ +import { ChatInputCommandInteraction, TextBasedChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { ModActionsPluginType } from "../../types"; + +export async function actualHideCaseCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + caseNumbers: number[], +) { + const failed: number[] = []; + + for (const num of caseNumbers) { + const theCase = await pluginData.state.cases.findByCaseNumber(num); + if (!theCase) { + failed.push(num); + continue; + } + + await pluginData.state.cases.setHidden(theCase.id, true); + } + + if (failed.length === caseNumbers.length) { + sendErrorMessage(pluginData, context, "None of the cases were found!"); + return; + } + const failedAddendum = + failed.length > 0 + ? `\nThe following cases were not found: ${failed.toString().replace(new RegExp(",", "g"), ", ")}` + : ""; + + const amt = caseNumbers.length - failed.length; + sendSuccessMessage( + pluginData, + context, + `${amt} case${amt === 1 ? " is" : "s are"} now hidden! Use \`unhidecase\` to unhide them.${failedAddendum}`, + ); +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts new file mode 100644 index 00000000..e66383fe --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts @@ -0,0 +1,89 @@ +import { Attachment, ChatInputCommandInteraction, GuildMember, TextBasedChannel, User } from "discord.js"; +import { GuildPluginData } from "knub"; +import { LogType } from "../../../../data/LogType"; +import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { + DAYS, + SECONDS, + UnknownUser, + UserNotificationMethod, + renderUserUsername, + resolveMember, +} from "../../../../utils"; +import { IgnoredEventType, ModActionsPluginType } from "../../types"; +import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { ignoreEvent } from "../ignoreEvent"; +import { isBanned } from "../isBanned"; +import { kickMember } from "../kickMember"; + +export async function actualKickCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + author: GuildMember, + user: User | UnknownUser, + reason: string, + attachments: Attachment[], + mod: GuildMember, + contactMethods?: UserNotificationMethod[], + clean?: boolean, +) { + const memberToKick = await resolveMember(pluginData.client, pluginData.guild, user.id); + + if (!memberToKick) { + const banned = await isBanned(pluginData, user.id); + if (banned) { + sendErrorMessage(pluginData, context, `User is banned`); + } else { + sendErrorMessage(pluginData, context, `User not found on the server`); + } + + return; + } + + // Make sure we're allowed to kick this member + if (!canActOn(pluginData, author, memberToKick)) { + sendErrorMessage(pluginData, context, "Cannot kick: insufficient permissions"); + return; + } + + const formattedReason = formatReasonWithAttachments(reason, attachments); + + const kickResult = await kickMember(pluginData, memberToKick, formattedReason, { + contactMethods, + caseArgs: { + modId: mod.id, + ppId: mod.id !== author.id ? author.id : undefined, + }, + }); + + if (clean) { + pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, memberToKick.id); + ignoreEvent(pluginData, IgnoredEventType.Ban, memberToKick.id); + + try { + await memberToKick.ban({ deleteMessageSeconds: (1 * DAYS) / SECONDS, reason: "kick -clean" }); + } catch { + sendErrorMessage(pluginData, context, "Failed to ban the user to clean messages (-clean)"); + } + + pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, memberToKick.id); + ignoreEvent(pluginData, IgnoredEventType.Unban, memberToKick.id); + + try { + await pluginData.guild.bans.remove(memberToKick.id, "kick -clean"); + } catch { + sendErrorMessage(pluginData, context, "Failed to unban the user after banning them (-clean)"); + } + } + + if (kickResult.status === "failed") { + sendErrorMessage(pluginData, context, `Failed to kick user`); + return; + } + + // Confirm the action to the moderator + let response = `Kicked **${renderUserUsername(memberToKick.user)}** (Case #${kickResult.case.case_number})`; + + if (kickResult.notifyResult.text) response += ` (${kickResult.notifyResult.text})`; + sendSuccessMessage(pluginData, context, response); +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts new file mode 100644 index 00000000..c0abc3a8 --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts @@ -0,0 +1,163 @@ +import { ChatInputCommandInteraction, GuildMember, Snowflake, TextBasedChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { waitForReply } from "knub/helpers"; +import { CaseTypes } from "../../../../data/CaseTypes"; +import { LogType } from "../../../../data/LogType"; +import { humanizeDurationShort } from "../../../../humanizeDurationShort"; +import { + canActOn, + isContextInteraction, + sendContextResponse, + sendErrorMessage, + sendSuccessMessage, +} from "../../../../pluginUtils"; +import { DAYS, MINUTES, SECONDS, noop } from "../../../../utils"; +import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { LogsPlugin } from "../../../Logs/LogsPlugin"; +import { IgnoredEventType, ModActionsPluginType } from "../../types"; +import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { ignoreEvent } from "../ignoreEvent"; + +export async function actualMassBanCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + userIds: string[], + author: GuildMember, +) { + // Limit to 100 users at once (arbitrary?) + if (userIds.length > 100) { + sendErrorMessage(pluginData, context, `Can only massban max 100 users at once`); + return; + } + + // Ask for ban reason (cleaner this way instead of trying to cram it into the args) + sendContextResponse(context, "Ban reason? `cancel` to cancel"); + const banReasonReply = await waitForReply( + pluginData.client, + isContextInteraction(context) ? context.channel! : context, + author.id, + ); + + if (!banReasonReply || !banReasonReply.content || banReasonReply.content.toLowerCase().trim() === "cancel") { + sendErrorMessage(pluginData, context, "Cancelled"); + return; + } + + const banReason = formatReasonWithAttachments(banReasonReply.content, [...banReasonReply.attachments.values()]); + + // Verify we can act on each of the users specified + for (const userId of userIds) { + const member = pluginData.guild.members.cache.get(userId as Snowflake); // TODO: Get members on demand? + if (member && !canActOn(pluginData, author, member)) { + sendErrorMessage(pluginData, context, "Cannot massban one or more users: insufficient permissions"); + return; + } + } + + // Show a loading indicator since this can take a while + const maxWaitTime = pluginData.state.massbanQueue.timeout * pluginData.state.massbanQueue.length; + const maxWaitTimeFormatted = humanizeDurationShort(maxWaitTime, { round: true }); + const initialLoadingText = + pluginData.state.massbanQueue.length === 0 + ? "Banning..." + : `Massban queued. Waiting for previous massban to finish (max wait ${maxWaitTimeFormatted}).`; + const loadingMsg = await sendContextResponse(context, initialLoadingText); + + const waitTimeStart = performance.now(); + const waitingInterval = setInterval(() => { + const waitTime = humanizeDurationShort(performance.now() - waitTimeStart, { round: true }); + loadingMsg + .edit(`Massban queued. Still waiting for previous massban to finish (waited ${waitTime}).`) + .catch(() => clearInterval(waitingInterval)); + }, 1 * MINUTES); + + pluginData.state.massbanQueue.add(async () => { + clearInterval(waitingInterval); + + if (pluginData.state.unloaded) { + void loadingMsg.delete().catch(noop); + return; + } + + void loadingMsg.edit("Banning...").catch(noop); + + // Ban each user and count failed bans (if any) + const startTime = performance.now(); + const failedBans: string[] = []; + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const messageConfig = isContextInteraction(context) + ? await pluginData.config.getForInteraction(context) + : await pluginData.config.getForChannel(context); + const deleteDays = messageConfig.ban_delete_message_days; + + for (const [i, userId] of userIds.entries()) { + if (pluginData.state.unloaded) { + break; + } + + try { + // Ignore automatic ban cases and logs + // We create our own cases below and post a single "mass banned" log instead + ignoreEvent(pluginData, IgnoredEventType.Ban, userId, 30 * MINUTES); + pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, userId, 30 * MINUTES); + + await pluginData.guild.bans.create(userId as Snowflake, { + deleteMessageSeconds: (deleteDays * DAYS) / SECONDS, + reason: banReason, + }); + + await casesPlugin.createCase({ + userId, + modId: author.id, + type: CaseTypes.Ban, + reason: `Mass ban: ${banReason}`, + postInCaseLogOverride: false, + }); + + pluginData.state.events.emit("ban", userId, banReason); + } catch { + failedBans.push(userId); + } + + // Send a status update every 10 bans + if ((i + 1) % 10 === 0) { + loadingMsg.edit(`Banning... ${i + 1}/${userIds.length}`).catch(noop); + } + } + + const totalTime = performance.now() - startTime; + const formattedTimeTaken = humanizeDurationShort(totalTime, { round: true }); + + // Clear loading indicator + loadingMsg.delete().catch(noop); + + const successfulBanCount = userIds.length - failedBans.length; + if (successfulBanCount === 0) { + // All bans failed - don't create a log entry and notify the user + sendErrorMessage(pluginData, context, "All bans failed. Make sure the IDs are valid."); + } else { + // Some or all bans were successful. Create a log entry for the mass ban and notify the user. + pluginData.getPlugin(LogsPlugin).logMassBan({ + mod: author.user, + count: successfulBanCount, + reason: banReason, + }); + + if (failedBans.length) { + sendSuccessMessage( + pluginData, + context, + `Banned ${successfulBanCount} users in ${formattedTimeTaken}, ${failedBans.length} failed: ${failedBans.join( + " ", + )}`, + ); + } else { + sendSuccessMessage( + pluginData, + context, + `Banned ${successfulBanCount} users successfully in ${formattedTimeTaken}`, + ); + } + } + }); +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts new file mode 100644 index 00000000..8dd735ab --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts @@ -0,0 +1,110 @@ +import { ChatInputCommandInteraction, GuildMember, Snowflake, TextBasedChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { waitForReply } from "knub/helpers"; +import { LogType } from "../../../../data/LogType"; +import { logger } from "../../../../logger"; +import { + canActOn, + isContextInteraction, + sendContextResponse, + sendErrorMessage, + sendSuccessMessage, +} from "../../../../pluginUtils"; +import { LogsPlugin } from "../../../Logs/LogsPlugin"; +import { MutesPlugin } from "../../../Mutes/MutesPlugin"; +import { ModActionsPluginType } from "../../types"; +import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; + +export async function actualMassMuteCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + userIds: string[], + author: GuildMember, +) { + // Limit to 100 users at once (arbitrary?) + if (userIds.length > 100) { + sendErrorMessage(pluginData, context, `Can only massmute max 100 users at once`); + return; + } + + // Ask for mute reason + sendContextResponse(context, "Mute reason? `cancel` to cancel"); + const muteReasonReceived = await waitForReply( + pluginData.client, + isContextInteraction(context) ? context.channel! : context, + author.id, + ); + if ( + !muteReasonReceived || + !muteReasonReceived.content || + muteReasonReceived.content.toLowerCase().trim() === "cancel" + ) { + sendErrorMessage(pluginData, context, "Cancelled"); + return; + } + + const muteReason = formatReasonWithAttachments(muteReasonReceived.content, [ + ...muteReasonReceived.attachments.values(), + ]); + + // Verify we can act upon all users + for (const userId of userIds) { + const member = pluginData.guild.members.cache.get(userId as Snowflake); + if (member && !canActOn(pluginData, author, member)) { + sendErrorMessage(pluginData, context, "Cannot massmute one or more users: insufficient permissions"); + return; + } + } + + // Ignore automatic mute cases and logs for these users + // We'll create our own cases below and post a single "mass muted" log instead + userIds.forEach((userId) => { + // Use longer timeouts since this can take a while + pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_MUTE, userId, 120 * 1000); + }); + + // Show loading indicator + const loadingMsg = await sendContextResponse(context, "Muting..."); + + // Mute everyone and count fails + const modId = author.id; + const failedMutes: string[] = []; + const mutesPlugin = pluginData.getPlugin(MutesPlugin); + for (const userId of userIds) { + try { + await mutesPlugin.muteUser(userId, 0, `Mass mute: ${muteReason}`, { + caseArgs: { + modId, + }, + }); + } catch (e) { + logger.info(e); + failedMutes.push(userId); + } + } + + // Clear loading indicator + loadingMsg.delete(); + + const successfulMuteCount = userIds.length - failedMutes.length; + if (successfulMuteCount === 0) { + // All mutes failed + sendErrorMessage(pluginData, context, "All mutes failed. Make sure the IDs are valid."); + } else { + // Success on all or some mutes + pluginData.getPlugin(LogsPlugin).logMassMute({ + mod: author.user, + count: successfulMuteCount, + }); + + if (failedMutes.length) { + sendSuccessMessage( + pluginData, + context, + `Muted ${successfulMuteCount} users, ${failedMutes.length} failed: ${failedMutes.join(" ")}`, + ); + } else { + sendSuccessMessage(pluginData, context, `Muted ${successfulMuteCount} users successfully`); + } + } +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts new file mode 100644 index 00000000..cf829fd7 --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts @@ -0,0 +1,127 @@ +import { ChatInputCommandInteraction, GuildMember, Snowflake, TextBasedChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { waitForReply } from "knub/helpers"; +import { CaseTypes } from "../../../../data/CaseTypes"; +import { LogType } from "../../../../data/LogType"; +import { + isContextInteraction, + sendContextResponse, + sendErrorMessage, + sendSuccessMessage, +} from "../../../../pluginUtils"; +import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { LogsPlugin } from "../../../Logs/LogsPlugin"; +import { IgnoredEventType, ModActionsPluginType } from "../../types"; +import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { ignoreEvent } from "../ignoreEvent"; +import { isBanned } from "../isBanned"; + +export async function actualMassUnbanCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + userIds: string[], + author: GuildMember, +) { + // Limit to 100 users at once (arbitrary?) + if (userIds.length > 100) { + sendErrorMessage(pluginData, context, `Can only mass-unban max 100 users at once`); + return; + } + + // Ask for unban reason (cleaner this way instead of trying to cram it into the args) + sendContextResponse(context, "Unban reason? `cancel` to cancel"); + const unbanReasonReply = await waitForReply( + pluginData.client, + isContextInteraction(context) ? context.channel! : context, + author.id, + ); + if (!unbanReasonReply || !unbanReasonReply.content || unbanReasonReply.content.toLowerCase().trim() === "cancel") { + sendErrorMessage(pluginData, context, "Cancelled"); + return; + } + + const unbanReason = formatReasonWithAttachments(unbanReasonReply.content, [...unbanReasonReply.attachments.values()]); + + // Ignore automatic unban cases and logs for these users + // We'll create our own cases below and post a single "mass unbanned" log instead + userIds.forEach((userId) => { + // Use longer timeouts since this can take a while + ignoreEvent(pluginData, IgnoredEventType.Unban, userId, 120 * 1000); + pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, userId, 120 * 1000); + }); + + // Show a loading indicator since this can take a while + const loadingMsg = await sendContextResponse(context, "Unbanning..."); + + // Unban each user and count failed unbans (if any) + const failedUnbans: Array<{ userId: string; reason: UnbanFailReasons }> = []; + const casesPlugin = pluginData.getPlugin(CasesPlugin); + for (const userId of userIds) { + if (!(await isBanned(pluginData, userId))) { + failedUnbans.push({ userId, reason: UnbanFailReasons.NOT_BANNED }); + continue; + } + + try { + await pluginData.guild.bans.remove(userId as Snowflake, unbanReason ?? undefined); + + await casesPlugin.createCase({ + userId, + modId: author.id, + type: CaseTypes.Unban, + reason: `Mass unban: ${unbanReason}`, + postInCaseLogOverride: false, + }); + } catch { + failedUnbans.push({ userId, reason: UnbanFailReasons.UNBAN_FAILED }); + } + } + + // Clear loading indicator + loadingMsg.delete(); + + const successfulUnbanCount = userIds.length - failedUnbans.length; + if (successfulUnbanCount === 0) { + // All unbans failed - don't create a log entry and notify the user + sendErrorMessage(pluginData, context, "All unbans failed. Make sure the IDs are valid and banned."); + } else { + // Some or all unbans were successful. Create a log entry for the mass unban and notify the user. + pluginData.getPlugin(LogsPlugin).logMassUnban({ + mod: author.user, + count: successfulUnbanCount, + reason: unbanReason, + }); + + if (failedUnbans.length) { + const notBanned = failedUnbans.filter((x) => x.reason === UnbanFailReasons.NOT_BANNED); + const unbanFailed = failedUnbans.filter((x) => x.reason === UnbanFailReasons.UNBAN_FAILED); + + let failedMsg = ""; + if (notBanned.length > 0) { + failedMsg += `${notBanned.length}x ${UnbanFailReasons.NOT_BANNED}:`; + notBanned.forEach((fail) => { + failedMsg += " " + fail.userId; + }); + } + if (unbanFailed.length > 0) { + failedMsg += `\n${unbanFailed.length}x ${UnbanFailReasons.UNBAN_FAILED}:`; + unbanFailed.forEach((fail) => { + failedMsg += " " + fail.userId; + }); + } + + sendSuccessMessage( + pluginData, + context, + `Unbanned ${successfulUnbanCount} users, ${failedUnbans.length} failed:\n${failedMsg}`, + ); + } else { + sendSuccessMessage(pluginData, context, `Unbanned ${successfulUnbanCount} users successfully`); + } + } +} + +enum UnbanFailReasons { + NOT_BANNED = "Not banned", + UNBAN_FAILED = "Unban failed", +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts new file mode 100644 index 00000000..487cf453 --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts @@ -0,0 +1,96 @@ +import { Attachment, ChatInputCommandInteraction, GuildMember, TextBasedChannel, User } from "discord.js"; +import humanizeDuration from "humanize-duration"; +import { GuildPluginData } from "knub"; +import { ERRORS, RecoverablePluginError } from "../../../../RecoverablePluginError"; +import { logger } from "../../../../logger"; +import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { + UnknownUser, + UserNotificationMethod, + asSingleLine, + isDiscordAPIError, + renderUserUsername, +} from "../../../../utils"; +import { MutesPlugin } from "../../../Mutes/MutesPlugin"; +import { MuteResult } from "../../../Mutes/types"; +import { ModActionsPluginType } from "../../types"; +import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; + +/** + * The actual function run by both !mute and !forcemute. + * The only difference between the two commands is in target member validation. + */ +export async function actualMuteCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + user: User | UnknownUser, + attachments: Array, + mod: GuildMember, + ppId?: string, + time?: number, + reason?: string, + contactMethods?: UserNotificationMethod[], +) { + const timeUntilUnmute = time && humanizeDuration(time); + const formattedReason = reason ? formatReasonWithAttachments(reason, attachments) : undefined; + + let muteResult: MuteResult; + const mutesPlugin = pluginData.getPlugin(MutesPlugin); + + try { + muteResult = await mutesPlugin.muteUser(user.id, time, formattedReason, { + contactMethods, + caseArgs: { + modId: mod.id, + ppId, + }, + }); + } catch (e) { + if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { + sendErrorMessage(pluginData, context, "Could not mute the user: no mute role set in config"); + } else if (isDiscordAPIError(e) && e.code === 10007) { + sendErrorMessage(pluginData, context, "Could not mute the user: unknown member"); + } else { + logger.error(`Failed to mute user ${user.id}: ${e.stack}`); + if (user.id == null) { + // FIXME: Debug + // tslint:disable-next-line:no-console + console.trace("[DEBUG] Null user.id for mute"); + } + sendErrorMessage(pluginData, context, "Could not mute the user"); + } + + return; + } + + // Confirm the action to the moderator + let response: string; + if (time) { + if (muteResult.updatedExistingMute) { + response = asSingleLine(` + Updated **${renderUserUsername(user)}**'s + mute to ${timeUntilUnmute} (Case #${muteResult.case.case_number}) + `); + } else { + response = asSingleLine(` + Muted **${renderUserUsername(user)}** + for ${timeUntilUnmute} (Case #${muteResult.case.case_number}) + `); + } + } else { + if (muteResult.updatedExistingMute) { + response = asSingleLine(` + Updated **${renderUserUsername(user)}**'s + mute to indefinite (Case #${muteResult.case.case_number}) + `); + } else { + response = asSingleLine(` + Muted **${renderUserUsername(user)}** + indefinitely (Case #${muteResult.case.case_number}) + `); + } + } + + if (muteResult.notifyResult.text) response += ` (${muteResult.notifyResult.text})`; + sendSuccessMessage(pluginData, context, response); +} diff --git a/backend/src/plugins/ModActions/functions/actualNoteCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts similarity index 71% rename from backend/src/plugins/ModActions/functions/actualNoteCmd.ts rename to backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts index 524a182c..2a29e2df 100644 --- a/backend/src/plugins/ModActions/functions/actualNoteCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts @@ -1,12 +1,12 @@ import { Attachment, ChatInputCommandInteraction, TextBasedChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { sendSuccessMessage } from "../../../pluginUtils"; -import { UnknownUser, renderUserUsername } from "../../../utils"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { ModActionsPluginType } from "../types"; -import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; +import { CaseTypes } from "../../../../data/CaseTypes"; +import { sendSuccessMessage } from "../../../../pluginUtils"; +import { UnknownUser, renderUserUsername } from "../../../../utils"; +import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { LogsPlugin } from "../../../Logs/LogsPlugin"; +import { ModActionsPluginType } from "../../types"; +import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; export async function actualNoteCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts new file mode 100644 index 00000000..94df7d4f --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts @@ -0,0 +1,63 @@ +import { Attachment, ChatInputCommandInteraction, GuildMember, Snowflake, TextBasedChannel, User } from "discord.js"; +import { GuildPluginData } from "knub"; +import { CaseTypes } from "../../../../data/CaseTypes"; +import { LogType } from "../../../../data/LogType"; +import { clearExpiringTempban } from "../../../../data/loops/expiringTempbansLoop"; +import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { UnknownUser } from "../../../../utils"; +import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { LogsPlugin } from "../../../Logs/LogsPlugin"; +import { IgnoredEventType, ModActionsPluginType } from "../../types"; +import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { ignoreEvent } from "../ignoreEvent"; + +export async function actualUnbanCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + authorId: string, + user: User | UnknownUser, + reason: string, + attachments: Array, + mod: GuildMember, +) { + pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, user.id); + const formattedReason = formatReasonWithAttachments(reason, attachments); + + try { + ignoreEvent(pluginData, IgnoredEventType.Unban, user.id); + await pluginData.guild.bans.remove(user.id as Snowflake, formattedReason ?? undefined); + } catch { + sendErrorMessage(pluginData, context, "Failed to unban member; are you sure they're banned?"); + return; + } + + // Create a case + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const createdCase = await casesPlugin.createCase({ + userId: user.id, + modId: mod.id, + type: CaseTypes.Unban, + reason: formattedReason, + ppId: mod.id !== authorId ? authorId : undefined, + }); + + // Delete the tempban, if one exists + const tempban = await pluginData.state.tempbans.findExistingTempbanForUserId(user.id); + if (tempban) { + clearExpiringTempban(tempban); + await pluginData.state.tempbans.clear(user.id); + } + + // Confirm the action + sendSuccessMessage(pluginData, context, `Member unbanned (Case #${createdCase.case_number})`); + + // Log the action + pluginData.getPlugin(LogsPlugin).logMemberUnban({ + mod: mod.user, + userId: user.id, + caseNumber: createdCase.case_number, + reason: formattedReason ?? "", + }); + + pluginData.state.events.emit("unban", user.id); +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts new file mode 100644 index 00000000..3ec2cd9e --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts @@ -0,0 +1,39 @@ +import { ChatInputCommandInteraction, TextBasedChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { ModActionsPluginType } from "../../types"; + +export async function actualUnhideCaseCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + caseNumbers: number[], +) { + const failed: number[] = []; + + for (const num of caseNumbers) { + const theCase = await pluginData.state.cases.findByCaseNumber(num); + if (!theCase) { + failed.push(num); + continue; + } + + await pluginData.state.cases.setHidden(theCase.id, false); + } + + if (failed.length === caseNumbers.length) { + sendErrorMessage(pluginData, context, "None of the cases were found!"); + return; + } + + const failedAddendum = + failed.length > 0 + ? `\nThe following cases were not found: ${failed.toString().replace(new RegExp(",", "g"), ", ")}` + : ""; + + const amt = caseNumbers.length - failed.length; + sendSuccessMessage( + pluginData, + context, + `${amt} case${amt === 1 ? " is" : "s are"} no longer hidden!${failedAddendum}`, + ); +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts new file mode 100644 index 00000000..96804c38 --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts @@ -0,0 +1,55 @@ +import { Attachment, ChatInputCommandInteraction, GuildMember, TextBasedChannel, User } from "discord.js"; +import humanizeDuration from "humanize-duration"; +import { GuildPluginData } from "knub"; +import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { UnknownUser, asSingleLine, renderUserUsername } from "../../../../utils"; +import { MutesPlugin } from "../../../Mutes/MutesPlugin"; +import { ModActionsPluginType } from "../../types"; +import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; + +export async function actualUnmuteCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + user: User | UnknownUser, + attachments: Array, + mod: GuildMember, + ppId?: string, + time?: number, + reason?: string, +) { + const parsedReason = reason ? formatReasonWithAttachments(reason, attachments) : undefined; + + const mutesPlugin = pluginData.getPlugin(MutesPlugin); + const result = await mutesPlugin.unmuteUser(user.id, time, { + modId: mod.id, + ppId: ppId ?? undefined, + reason: parsedReason, + }); + + if (!result) { + sendErrorMessage(pluginData, context, "User is not muted!"); + return; + } + + // Confirm the action to the moderator + if (time) { + const timeUntilUnmute = time && humanizeDuration(time); + sendSuccessMessage( + pluginData, + context, + asSingleLine(` + Unmuting **${renderUserUsername(user)}** + in ${timeUntilUnmute} (Case #${result.case.case_number}) + `), + ); + } else { + sendSuccessMessage( + pluginData, + context, + asSingleLine(` + Unmuted **${renderUserUsername(user)}** + (Case #${result.case.case_number}) + `), + ); + } +} diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts new file mode 100644 index 00000000..5748f72e --- /dev/null +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts @@ -0,0 +1,61 @@ +import { Attachment, ChatInputCommandInteraction, GuildMember, TextBasedChannel } from "discord.js"; +import { GuildPluginData } from "knub"; +import { CaseTypes } from "../../../../data/CaseTypes"; +import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { UserNotificationMethod, renderUserUsername } from "../../../../utils"; +import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; +import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { ModActionsPluginType } from "../../types"; +import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { warnMember } from "../warnMember"; + +export async function actualWarnCmd( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + authorId: string, + mod: GuildMember, + memberToWarn: GuildMember, + reason: string, + attachments: Attachment[], + contactMethods?: UserNotificationMethod[], +) { + const config = pluginData.config.get(); + const formattedReason = formatReasonWithAttachments(reason, attachments); + + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const priorWarnAmount = await casesPlugin.getCaseTypeAmountForUserId(memberToWarn.id, CaseTypes.Warn); + if (config.warn_notify_enabled && priorWarnAmount >= config.warn_notify_threshold) { + const reply = await waitForButtonConfirm( + context, + { content: config.warn_notify_message.replace("{priorWarnings}", `${priorWarnAmount}`) }, + { confirmText: "Yes", cancelText: "No", restrictToId: authorId }, + ); + if (!reply) { + sendErrorMessage(pluginData, context, "Warn cancelled by moderator"); + return; + } + } + + const warnResult = await warnMember(pluginData, memberToWarn, formattedReason, { + contactMethods, + caseArgs: { + modId: mod.id, + ppId: mod.id !== authorId ? authorId : undefined, + reason: formattedReason, + }, + retryPromptContext: context, + }); + + if (warnResult.status === "failed") { + sendErrorMessage(pluginData, context, "Failed to warn user"); + return; + } + + const messageResultText = warnResult.notifyResult.text ? ` (${warnResult.notifyResult.text})` : ""; + + sendSuccessMessage( + pluginData, + context, + `Warned **${renderUserUsername(memberToWarn.user)}** (Case #${warnResult.case.case_number})${messageResultText}`, + ); +} diff --git a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts b/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts deleted file mode 100644 index 73a1e2d9..00000000 --- a/backend/src/plugins/ModActions/functions/actualKickMemberCmd.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { GuildMember, GuildTextBasedChannel } from "discord.js"; -import { GuildPluginData } from "knub"; -import { hasPermission } from "knub/helpers"; -import { LogType } from "../../../data/LogType"; -import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { DAYS, SECONDS, errorMessage, renderUserUsername, resolveMember, resolveUser } from "../../../utils"; -import { IgnoredEventType, ModActionsPluginType } from "../types"; -import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; -import { ignoreEvent } from "./ignoreEvent"; -import { isBanned } from "./isBanned"; -import { kickMember } from "./kickMember"; -import { readContactMethodsFromArgs } from "./readContactMethodsFromArgs"; - -export async function actualKickMemberCmd( - pluginData: GuildPluginData, - msg, - args: { - user: string; - reason: string; - mod: GuildMember; - notify?: string; - "notify-channel"?: GuildTextBasedChannel; - clean?: boolean; - }, -) { - const user = await resolveUser(pluginData.client, args.user); - if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); - return; - } - - const memberToKick = await resolveMember(pluginData.client, pluginData.guild, user.id); - - if (!memberToKick) { - const banned = await isBanned(pluginData, user.id); - if (banned) { - sendErrorMessage(pluginData, msg.channel, `User is banned`); - } else { - sendErrorMessage(pluginData, msg.channel, `User not found on the server`); - } - - return; - } - - // Make sure we're allowed to kick this member - if (!canActOn(pluginData, msg.member, memberToKick)) { - sendErrorMessage(pluginData, msg.channel, "Cannot kick: insufficient permissions"); - return; - } - - // The moderator who did the action is the message author or, if used, the specified -mod - let mod = msg.member; - if (args.mod) { - if (!(await hasPermission(await pluginData.config.getForMessage(msg), "can_act_as_other"))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); - return; - } - - mod = args.mod; - } - - let contactMethods; - try { - contactMethods = readContactMethodsFromArgs(args); - } catch (e) { - sendErrorMessage(pluginData, msg.channel, e.message); - return; - } - - const reason = formatReasonWithAttachments(args.reason, msg.attachments); - - const kickResult = await kickMember(pluginData, memberToKick, reason, { - contactMethods, - caseArgs: { - modId: mod.id, - ppId: mod.id !== msg.author.id ? msg.author.id : null, - }, - }); - - if (args.clean) { - pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, memberToKick.id); - ignoreEvent(pluginData, IgnoredEventType.Ban, memberToKick.id); - - try { - await memberToKick.ban({ deleteMessageSeconds: (1 * DAYS) / SECONDS, reason: "kick -clean" }); - } catch { - sendErrorMessage(pluginData, msg.channel, "Failed to ban the user to clean messages (-clean)"); - } - - pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, memberToKick.id); - ignoreEvent(pluginData, IgnoredEventType.Unban, memberToKick.id); - - try { - await pluginData.guild.bans.remove(memberToKick.id, "kick -clean"); - } catch { - sendErrorMessage(pluginData, msg.channel, "Failed to unban the user after banning them (-clean)"); - } - } - - if (kickResult.status === "failed") { - msg.channel.send(errorMessage(`Failed to kick user`)); - return; - } - - // Confirm the action to the moderator - let response = `Kicked **${renderUserUsername(memberToKick.user)}** (Case #${kickResult.case.case_number})`; - - if (kickResult.notifyResult.text) response += ` (${kickResult.notifyResult.text})`; - sendSuccessMessage(pluginData, msg.channel, response); -} diff --git a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts deleted file mode 100644 index 5c628c4e..00000000 --- a/backend/src/plugins/ModActions/functions/actualMuteUserCmd.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { GuildMember, GuildTextBasedChannel, Message, User } from "discord.js"; -import humanizeDuration from "humanize-duration"; -import { GuildPluginData } from "knub"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { logger } from "../../../logger"; -import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { UnknownUser, asSingleLine, isDiscordAPIError, renderUserUsername } from "../../../utils"; -import { MutesPlugin } from "../../Mutes/MutesPlugin"; -import { MuteResult } from "../../Mutes/types"; -import { ModActionsPluginType } from "../types"; -import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; -import { readContactMethodsFromArgs } from "./readContactMethodsFromArgs"; - -/** - * The actual function run by both !mute and !forcemute. - * The only difference between the two commands is in target member validation. - */ -export async function actualMuteUserCmd( - pluginData: GuildPluginData, - user: User | UnknownUser, - msg: Message, - args: { - time?: number; - reason?: string; - mod: GuildMember; - notify?: string; - "notify-channel"?: GuildTextBasedChannel; - }, -) { - // The moderator who did the action is the message author or, if used, the specified -mod - let mod: GuildMember = msg.member!; - let pp: User | null = null; - - if (args.mod) { - if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); - return; - } - - mod = args.mod; - pp = msg.author; - } - - const timeUntilUnmute = args.time && humanizeDuration(args.time); - const reason = args.reason ? formatReasonWithAttachments(args.reason, [...msg.attachments.values()]) : undefined; - - let muteResult: MuteResult; - const mutesPlugin = pluginData.getPlugin(MutesPlugin); - - let contactMethods; - try { - contactMethods = readContactMethodsFromArgs(args); - } catch (e) { - sendErrorMessage(pluginData, msg.channel, e.message); - return; - } - - try { - muteResult = await mutesPlugin.muteUser(user.id, args.time, reason, { - contactMethods, - caseArgs: { - modId: mod.id, - ppId: pp ? pp.id : undefined, - }, - }); - } catch (e) { - if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_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, "Could not mute the user: unknown member"); - } else { - logger.error(`Failed to mute user ${user.id}: ${e.stack}`); - if (user.id == null) { - // FIXME: Debug - // tslint:disable-next-line:no-console - console.trace("[DEBUG] Null user.id for mute"); - } - sendErrorMessage(pluginData, msg.channel, "Could not mute the user"); - } - - return; - } - - // Confirm the action to the moderator - let response: string; - if (args.time) { - if (muteResult.updatedExistingMute) { - response = asSingleLine(` - Updated **${renderUserUsername(user)}**'s - mute to ${timeUntilUnmute} (Case #${muteResult.case.case_number}) - `); - } else { - response = asSingleLine(` - Muted **${renderUserUsername(user)}** - for ${timeUntilUnmute} (Case #${muteResult.case.case_number}) - `); - } - } else { - if (muteResult.updatedExistingMute) { - response = asSingleLine(` - Updated **${renderUserUsername(user)}**'s - mute to indefinite (Case #${muteResult.case.case_number}) - `); - } else { - response = asSingleLine(` - Muted **${renderUserUsername(user)}** - indefinitely (Case #${muteResult.case.case_number}) - `); - } - } - - if (muteResult.notifyResult.text) response += ` (${muteResult.notifyResult.text})`; - sendSuccessMessage(pluginData, msg.channel, response); -} diff --git a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts b/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts deleted file mode 100644 index d70a219c..00000000 --- a/backend/src/plugins/ModActions/functions/actualUnmuteUserCmd.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { GuildMember, Message, User } from "discord.js"; -import humanizeDuration from "humanize-duration"; -import { GuildPluginData } from "knub"; -import { hasPermission, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; -import { UnknownUser, asSingleLine, renderUserUsername } from "../../../utils"; -import { ModActionsPluginType } from "../types"; -import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; - -export async function actualUnmuteCmd( - pluginData: GuildPluginData, - user: User | UnknownUser, - msg: Message, - args: { time?: number; reason?: string; mod?: GuildMember }, -) { - // The moderator who did the action is the message author or, if used, the specified -mod - let mod = msg.author; - let pp: User | null = null; - - if (args.mod) { - if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg, channelId: msg.channel.id }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); - return; - } - - mod = args.mod.user; - pp = msg.author; - } - - const reason = args.reason ? formatReasonWithAttachments(args.reason, [...msg.attachments.values()]) : undefined; - - const mutesPlugin = pluginData.getPlugin(MutesPlugin); - const result = await mutesPlugin.unmuteUser(user.id, args.time, { - modId: mod.id, - ppId: pp ? pp.id : undefined, - reason, - }); - - if (!result) { - sendErrorMessage(pluginData, msg.channel, "User is not muted!"); - return; - } - - // Confirm the action to the moderator - if (args.time) { - const timeUntilUnmute = args.time && humanizeDuration(args.time); - sendSuccessMessage( - pluginData, - msg.channel, - asSingleLine(` - Unmuting **${renderUserUsername(user)}** - in ${timeUntilUnmute} (Case #${result.case.case_number}) - `), - ); - } else { - sendSuccessMessage( - pluginData, - msg.channel, - asSingleLine(` - Unmuted **${renderUserUsername(user)}** - (Case #${result.case.case_number}) - `), - ); - } -} diff --git a/backend/src/plugins/ModActions/functions/updateCase.ts b/backend/src/plugins/ModActions/functions/updateCase.ts index c19c9d06..d715e263 100644 --- a/backend/src/plugins/ModActions/functions/updateCase.ts +++ b/backend/src/plugins/ModActions/functions/updateCase.ts @@ -1,44 +1,53 @@ -import { Message } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, TextBasedChannel, User } from "discord.js"; +import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { ModActionsPluginType } from "../types"; import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; -export async function updateCase(pluginData, msg: Message, args) { - let theCase: Case | undefined; - if (args.caseNumber != null) { - theCase = await pluginData.state.cases.findByCaseNumber(args.caseNumber); +export async function updateCase( + pluginData: GuildPluginData, + context: TextBasedChannel | ChatInputCommandInteraction, + author: User, + caseNumber?: number, + note?: string, + attachments: Attachment[] = [], +) { + let theCase: Case | null; + if (caseNumber != null) { + theCase = await pluginData.state.cases.findByCaseNumber(caseNumber); } else { - theCase = await pluginData.state.cases.findLatestByModId(msg.author.id); + theCase = await pluginData.state.cases.findLatestByModId(author.id); } if (!theCase) { - sendErrorMessage(pluginData, msg.channel, "Case not found"); + sendErrorMessage(pluginData, context, "Case not found"); return; } - if (!args.note && msg.attachments.size === 0) { - sendErrorMessage(pluginData, msg.channel, "Text or attachment required"); + if (!note && attachments.length === 0) { + sendErrorMessage(pluginData, context, "Text or attachment required"); return; } - const note = formatReasonWithAttachments(args.note, [...msg.attachments.values()]); + const formattedNote = formatReasonWithAttachments(note ?? "", attachments); const casesPlugin = pluginData.getPlugin(CasesPlugin); await casesPlugin.createCaseNote({ caseId: theCase.id, - modId: msg.author.id, - body: note, + modId: author.id, + body: formattedNote, }); pluginData.getPlugin(LogsPlugin).logCaseUpdate({ - mod: msg.author, + mod: author, caseNumber: theCase.case_number, caseType: CaseTypes[theCase.type], - note, + note: formattedNote, }); - sendSuccessMessage(pluginData, msg.channel, `Case \`#${theCase.case_number}\` updated`); + sendSuccessMessage(pluginData, context, `Case \`#${theCase.case_number}\` updated`); } diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts index 9bc0fda9..8f58f915 100644 --- a/backend/src/plugins/ModActions/functions/warnMember.ts +++ b/backend/src/plugins/ModActions/functions/warnMember.ts @@ -1,6 +1,7 @@ import { GuildMember, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; +import { isContextInteraction } from "../../../pluginUtils"; import { TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; import { UserNotificationResult, createUserNotificationError, notifyUser, resolveUser, ucfirst } from "../../../utils"; import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; @@ -39,20 +40,23 @@ export async function warnMember( } if (!notifyResult.success) { - if (warnOptions.retryPromptChannel && pluginData.guild.channels.resolve(warnOptions.retryPromptChannel.id)) { - const reply = await waitForButtonConfirm( - warnOptions.retryPromptChannel, - { content: "Failed to message the user. Log the warning anyway?" }, - { confirmText: "Yes", cancelText: "No", restrictToId: warnOptions.caseArgs?.modId }, - ); + const contextIsChannel = warnOptions.retryPromptContext && !isContextInteraction(warnOptions.retryPromptContext); + const isValidChannel = contextIsChannel && pluginData.guild.channels.resolve(warnOptions.retryPromptContext!.id); - if (!reply) { - return { - status: "failed", - error: "Failed to message user", - }; - } - } else { + if (!warnOptions.retryPromptContext || !isValidChannel) { + return { + status: "failed", + error: "Failed to message user", + }; + } + + const reply = await waitForButtonConfirm( + warnOptions.retryPromptContext, + { content: "Failed to message the user. Log the warning anyway?" }, + { confirmText: "Yes", cancelText: "No", restrictToId: warnOptions.caseArgs?.modId }, + ); + + if (!reply) { return { status: "failed", error: "Failed to message user", diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index c6c1fe70..5a61c342 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -1,4 +1,4 @@ -import { GuildTextBasedChannel } from "discord.js"; +import { ChatInputCommandInteraction, TextBasedChannel } from "discord.js"; import { EventEmitter } from "events"; import * as t from "io-ts"; import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, guildPluginSlashGroup } from "knub"; @@ -127,7 +127,7 @@ export type WarnMemberNotifyRetryCallback = () => boolean | Promise; export interface WarnOptions { caseArgs?: Partial | null; contactMethods?: UserNotificationMethod[] | null; - retryPromptChannel?: GuildTextBasedChannel | null; + retryPromptContext?: TextBasedChannel | ChatInputCommandInteraction | null; isAutomodAction?: boolean; } diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index 18e8f3d0..d1075499 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -1,4 +1,5 @@ import { + ChatInputCommandInteraction, Client, Message, MessageCreateOptions, @@ -9,6 +10,7 @@ import { TextBasedChannel, User, } from "discord.js"; +import { sendContextResponse } from "../pluginUtils"; import { MINUTES, noop } from "../utils"; import { Awaitable } from "./typeUtils"; import Timeout = NodeJS.Timeout; @@ -27,14 +29,14 @@ const defaultOpts: PaginateMessageOpts = { export async function createPaginatedMessage( client: Client, - channel: TextBasedChannel | User, + context: TextBasedChannel | User | ChatInputCommandInteraction, totalPages: number, loadPageFn: LoadPageFn, opts: Partial = {}, ): Promise { const fullOpts = { ...defaultOpts, ...opts } as PaginateMessageOpts; const firstPageContent = await loadPageFn(1); - const message = await channel.send(firstPageContent); + const message = await sendContextResponse(context, firstPageContent); let page = 1; let pageLoadId = 0; // Used to avoid race conditions when rapidly switching pages diff --git a/backend/src/utils/multipleSlashOptions.ts b/backend/src/utils/multipleSlashOptions.ts new file mode 100644 index 00000000..9cdd2eca --- /dev/null +++ b/backend/src/utils/multipleSlashOptions.ts @@ -0,0 +1,20 @@ +import { AttachmentSlashCommandOption, slashOptions } from "knub"; + +type AttachmentSlashOptions = Omit; + +export function generateAttachmentSlashOptions(amount: number, options: AttachmentSlashOptions) { + return new Array(amount).fill(0).map((_, i) => { + return slashOptions.attachment({ + name: amount > 1 ? `${options.name}${i + 1}` : options.name, + description: options.description, + required: options.required ?? false, + }); + }); +} + +export function retrieveMultipleOptions(amount: number, options: any, name: string) { + return new Array(amount) + .fill(0) + .map((_, i) => options[amount > 1 ? `${name}${i + 1}` : name]) + .filter((a) => a); +} diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index 261da4da..64cab738 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -2,22 +2,26 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle, - GuildTextBasedChannel, + ChatInputCommandInteraction, MessageActionRowComponentBuilder, MessageComponentInteraction, MessageCreateOptions, + TextBasedChannel, + User, } from "discord.js"; import moment from "moment"; import { v4 as uuidv4 } from "uuid"; +import { isContextInteraction } from "../pluginUtils"; import { noop } from "../utils"; export async function waitForButtonConfirm( - channel: GuildTextBasedChannel, + context: TextBasedChannel | User | ChatInputCommandInteraction, toPost: MessageCreateOptions, options?: WaitForOptions, ): Promise { return new Promise(async (resolve) => { - const idMod = `${channel.guild.id}-${moment.utc().valueOf()}`; + const contextIsInteraction = isContextInteraction(context); + const idMod = `${context.id}-${moment.utc().valueOf()}`; const row = new ActionRowBuilder().addComponents([ new ButtonBuilder() .setStyle(ButtonStyle.Success) @@ -29,7 +33,9 @@ export async function waitForButtonConfirm( .setLabel(options?.cancelText || "Cancel") .setCustomId(`cancelButton:${idMod}:${uuidv4()}`), ]); - const message = await channel.send({ ...toPost, components: [row] }); + const sendMethod = contextIsInteraction ? (context.replied ? "followUp" : "reply") : "send"; + const extraParameters = contextIsInteraction ? { fetchReply: true } : {}; + const message = await context[sendMethod]({ ...toPost, components: [row], ...extraParameters }); const collector = message.createMessageComponentCollector({ time: 10000 }); From 592d037148e2f4bdad35996b0505541c47ea63fe Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Fri, 16 Feb 2024 11:51:58 +0100 Subject: [PATCH 12/30] Added Discord attachment link reaction, fixed emoji configuration and moved util functions --- backend/src/index.ts | 20 ++- backend/src/pluginUtils.ts | 136 ++++------------ .../commands/DisableAutoReactionsCmd.ts | 6 +- .../commands/NewAutoReactionsCmd.ts | 23 +-- backend/src/plugins/Automod/actions/ban.ts | 1 + backend/src/plugins/Automod/actions/kick.ts | 2 +- backend/src/plugins/Automod/actions/mute.ts | 1 + backend/src/plugins/Automod/actions/warn.ts | 2 +- .../Automod/commands/AntiraidClearCmd.ts | 4 +- .../Automod/commands/SetAntiraidCmd.ts | 6 +- .../plugins/BotControl/BotControlPlugin.ts | 5 +- .../commands/AddDashboardUserCmd.ts | 16 +- .../commands/AddServerFromInviteCmd.ts | 14 +- .../BotControl/commands/AllowServerCmd.ts | 11 +- .../BotControl/commands/ChannelToServerCmd.ts | 5 +- .../BotControl/commands/DisallowServerCmd.ts | 7 +- .../BotControl/commands/EligibleCmd.ts | 8 +- .../BotControl/commands/LeaveServerCmd.ts | 9 +- .../commands/ListDashboardPermsCmd.ts | 22 +-- .../commands/ListDashboardUsersCmd.ts | 17 +- .../commands/RateLimitPerformanceCmd.ts | 5 +- .../commands/ReloadGlobalPluginsCmd.ts | 5 +- .../BotControl/commands/ReloadServerCmd.ts | 9 +- .../commands/RemoveDashboardUserCmd.ts | 16 +- .../commands/ArchiveChannelCmd.ts | 7 +- backend/src/plugins/Common/CommonPlugin.ts | 146 ++++++++++++++++++ .../src/plugins/Common/functions/getEmoji.ts | 10 ++ backend/src/plugins/Common/types.ts | 13 ++ .../src/plugins/ContextMenus/actions/ban.ts | 2 +- .../src/plugins/ContextMenus/actions/mute.ts | 2 +- .../src/plugins/ContextMenus/actions/warn.ts | 2 +- .../Counters/commands/AddCounterCmd.ts | 22 +-- .../Counters/commands/CountersListCmd.ts | 4 +- .../commands/ResetAllCounterValuesCmd.ts | 16 +- .../Counters/commands/ResetCounterCmd.ts | 18 +-- .../Counters/commands/SetCounterCmd.ts | 24 +-- .../Counters/commands/ViewCounterCmd.ts | 18 +-- .../CustomEvents/functions/runEvent.ts | 4 +- .../plugins/LocateUser/commands/FollowCmd.ts | 34 ++-- .../LocateUser/commands/ListFollowCmd.ts | 8 +- .../plugins/LocateUser/utils/moveMember.ts | 10 +- .../src/plugins/LocateUser/utils/sendWhere.ts | 4 +- .../MessageSaver/commands/SaveMessagesToDB.ts | 15 +- .../MessageSaver/commands/SavePinsToDB.ts | 15 +- .../plugins/ModActions/ModActionsPlugin.ts | 23 ++- .../commands/addcase/AddCaseMsgCmd.ts | 11 +- .../commands/addcase/AddCaseSlashCmd.ts | 7 +- .../ModActions/commands/ban/BanMsgCmd.ts | 11 +- .../ModActions/commands/ban/BanSlashCmd.ts | 15 +- .../ModActions/commands/case/CaseMsgCmd.ts | 2 +- .../commands/cases/CasesModMsgCmd.ts | 2 +- .../commands/cases/CasesUserMsgCmd.ts | 6 +- .../commands/deletecase/DeleteCaseMsgCmd.ts | 2 +- .../commands/forceban/ForceBanMsgCmd.ts | 13 +- .../commands/forceban/ForceBanSlashCmd.ts | 13 +- .../commands/forcemute/ForceMuteMsgCmd.ts | 13 +- .../commands/forcemute/ForceMuteSlashCmd.ts | 15 +- .../commands/forceunmute/ForceUnmuteMsgCmd.ts | 13 +- .../forceunmute/ForceUnmuteSlashCmd.ts | 13 +- .../commands/hidecase/HideCaseMsgCmd.ts | 2 +- .../ModActions/commands/kick/KickMsgCmd.ts | 10 +- .../ModActions/commands/kick/KickSlashCmd.ts | 13 +- .../commands/massban/MassBanMsgCmd.ts | 2 +- .../commands/massmute/MassMuteMsgCmd.ts | 2 +- .../commands/massunban/MassUnbanMsgCmd.ts | 2 +- .../ModActions/commands/mute/MuteMsgCmd.ts | 25 ++- .../ModActions/commands/mute/MuteSlashCmd.ts | 29 ++-- .../ModActions/commands/note/NoteMsgCmd.ts | 8 +- .../ModActions/commands/note/NoteSlashCmd.ts | 6 +- .../ModActions/commands/unban/UnbanMsgCmd.ts | 9 +- .../commands/unban/UnbanSlashCmd.ts | 11 +- .../commands/unhidecase/UnhideCaseMsgCmd.ts | 2 +- .../commands/unmute/UnmuteMsgCmd.ts | 25 ++- .../commands/unmute/UnmuteSlashCmd.ts | 29 ++-- .../commands/update/UpdateMsgCmd.ts | 2 +- .../ModActions/commands/warn/WarnMsgCmd.ts | 15 +- .../ModActions/commands/warn/WarnSlashCmd.ts | 19 ++- .../actualCommands/actualAddCaseCmd.ts | 32 ++-- .../functions/actualCommands/actualBanCmd.ts | 54 ++++--- .../functions/actualCommands/actualCaseCmd.ts | 9 +- .../actualCommands/actualCasesCmd.ts | 15 +- .../actualCommands/actualDeleteCaseCmd.ts | 24 +-- .../actualCommands/actualForceBanCmd.ts | 24 ++- .../actualCommands/actualHideCaseCmd.ts | 19 +-- .../functions/actualCommands/actualKickCmd.ts | 35 +++-- .../actualCommands/actualMassBanCmd.ts | 70 +++++---- .../actualCommands/actualMassMuteCmd.ts | 56 +++---- .../actualCommands/actualMassUnbanCmd.ts | 52 ++++--- .../functions/actualCommands/actualMuteCmd.ts | 34 ++-- .../functions/actualCommands/actualNoteCmd.ts | 32 ++-- .../actualCommands/actualUnbanCmd.ts | 21 ++- .../actualCommands/actualUnhideCaseCmd.ts | 16 +- .../actualCommands/actualUnmuteCmd.ts | 28 ++-- .../functions/actualCommands/actualWarnCmd.ts | 33 ++-- .../functions/attachmentLinkReaction.ts | 51 ++++++ .../plugins/ModActions/functions/banUserId.ts | 7 +- .../ModActions/functions/clearTempban.ts | 9 +- .../functions/formatReasonForAttachments.ts | 36 +++++ .../functions/formatReasonWithAttachments.ts | 6 - .../ModActions/functions/kickMember.ts | 5 +- .../ModActions/functions/updateCase.ts | 20 +-- .../ModActions/functions/warnMember.ts | 11 +- backend/src/plugins/ModActions/types.ts | 8 +- .../Mutes/commands/ClearBannedMutesCmd.ts | 4 +- .../plugins/Mutes/commands/ClearMutesCmd.ts | 17 +- .../commands/ClearMutesWithoutRoleCmd.ts | 6 +- .../src/plugins/Mutes/functions/muteUser.ts | 3 +- .../plugins/NameHistory/commands/NamesCmd.ts | 4 +- .../commands/PingableRoleDisableCmd.ts | 14 +- .../commands/PingableRoleEnableCmd.ts | 18 +-- backend/src/plugins/Post/commands/EditCmd.ts | 8 +- .../src/plugins/Post/commands/EditEmbedCmd.ts | 12 +- .../src/plugins/Post/commands/PostEmbedCmd.ts | 10 +- .../Post/commands/ScheduledPostsDeleteCmd.ts | 6 +- .../Post/commands/ScheduledPostsShowCmd.ts | 4 +- .../src/plugins/Post/util/actualPostCmd.ts | 41 +++-- .../commands/ClearReactionRolesCmd.ts | 8 +- .../commands/InitReactionRolesCmd.ts | 34 ++-- .../commands/RefreshReactionRolesCmd.ts | 6 +- .../plugins/Reminders/commands/RemindCmd.ts | 14 +- .../Reminders/commands/RemindersCmd.ts | 4 +- .../Reminders/commands/RemindersDeleteCmd.ts | 6 +- .../RoleButtons/commands/resetButtons.ts | 8 +- .../src/plugins/Roles/commands/AddRoleCmd.ts | 23 +-- .../plugins/Roles/commands/MassAddRoleCmd.ts | 17 +- .../Roles/commands/MassRemoveRoleCmd.ts | 17 +- .../plugins/Roles/commands/RemoveRoleCmd.ts | 23 +-- .../SelfGrantableRoles/commands/RoleAddCmd.ts | 26 ++-- .../commands/RoleRemoveCmd.ts | 50 +++--- .../Slowmode/commands/SlowmodeClearCmd.ts | 30 ++-- .../Slowmode/commands/SlowmodeSetCmd.ts | 51 +++--- .../Slowmode/util/actualDisableSlowmodeCmd.ts | 25 ++- .../Spam/util/logAndDetectMessageSpam.ts | 5 +- .../Spam/util/logAndDetectOtherSpam.ts | 5 +- .../Starboard/commands/MigratePinsCmd.ts | 14 +- .../src/plugins/Tags/commands/TagCreateCmd.ts | 6 +- .../src/plugins/Tags/commands/TagDeleteCmd.ts | 6 +- .../src/plugins/Tags/commands/TagEvalCmd.ts | 6 +- .../src/plugins/Tags/commands/TagSourceCmd.ts | 9 +- .../TimeAndDate/commands/ResetTimezoneCmd.ts | 10 +- .../TimeAndDate/commands/SetTimezoneCmd.ts | 9 +- backend/src/plugins/Utility/UtilityPlugin.ts | 9 +- .../src/plugins/Utility/commands/AvatarCmd.ts | 4 +- .../Utility/commands/ChannelInfoCmd.ts | 4 +- .../src/plugins/Utility/commands/CleanCmd.ts | 57 ++++--- .../plugins/Utility/commands/ContextCmd.ts | 8 +- .../plugins/Utility/commands/EmojiInfoCmd.ts | 6 +- .../src/plugins/Utility/commands/InfoCmd.ts | 32 ++-- .../plugins/Utility/commands/InviteInfoCmd.ts | 4 +- .../src/plugins/Utility/commands/JumboCmd.ts | 6 +- .../Utility/commands/MessageInfoCmd.ts | 13 +- .../plugins/Utility/commands/NicknameCmd.ts | 14 +- .../Utility/commands/NicknameResetCmd.ts | 5 +- .../plugins/Utility/commands/RoleInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/RolesCmd.ts | 4 +- .../plugins/Utility/commands/ServerInfoCmd.ts | 6 +- .../Utility/commands/SnowflakeInfoCmd.ts | 4 +- .../src/plugins/Utility/commands/SourceCmd.ts | 7 +- .../plugins/Utility/commands/UserInfoCmd.ts | 6 +- .../Utility/commands/VcdisconnectCmd.ts | 17 +- .../src/plugins/Utility/commands/VcmoveCmd.ts | 67 ++++---- .../Utility/functions/getChannelInfoEmbed.ts | 1 - .../Utility/functions/getMessageInfoEmbed.ts | 4 - .../Utility/functions/getRoleInfoEmbed.ts | 6 +- .../Utility/functions/getServerInfoEmbed.ts | 1 - .../functions/getSnowflakeInfoEmbed.ts | 9 +- .../Utility/functions/getUserInfoEmbed.ts | 4 - backend/src/plugins/Utility/search.ts | 15 +- backend/src/plugins/availablePlugins.ts | 3 + backend/src/utils.ts | 5 +- backend/src/utils/createPaginatedMessage.ts | 3 +- backend/src/utils/waitForInteraction.ts | 18 ++- dashboard/package-lock.json | 6 +- 173 files changed, 1540 insertions(+), 1170 deletions(-) create mode 100644 backend/src/plugins/Common/CommonPlugin.ts create mode 100644 backend/src/plugins/Common/functions/getEmoji.ts create mode 100644 backend/src/plugins/Common/types.ts create mode 100644 backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts create mode 100644 backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts delete mode 100644 backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts diff --git a/backend/src/index.ts b/backend/src/index.ts index 2fe16c11..146b2297 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -203,7 +203,7 @@ if (env.DEBUG) { } logger.info("Connecting to database"); -connect().then(async (connection) => { +connect().then(async () => { const client = new Client({ partials: [Partials.User, Partials.Channel, Partials.GuildMember, Partials.Message, Partials.Reaction], @@ -315,9 +315,27 @@ connect().then(async (connection) => { if (row) { try { const loaded = loadYamlSafely(row.config); + + if (loaded.success_emoji || loaded.error_emoji) { + const deprecatedKeys = [] as string[]; + const exampleConfig = `plugins:\n common:\n config:\n success_emoji: "👍"\n error_emoji: "👎"`; + + if (loaded.success_emoji) { + deprecatedKeys.push("success_emoji"); + } + + if (loaded.error_emoji) { + deprecatedKeys.push("error_emoji"); + } + + logger.warn(`Deprecated config properties found in "${key}": ${deprecatedKeys.join(", ")}`); + logger.warn(`You can now configure those emojis in the "common" plugin config\n${exampleConfig}`); + } + // Remove deprecated properties some may still have in their config delete loaded.success_emoji; delete loaded.error_emoji; + return loaded; } catch (err) { logger.error(`Error while loading config "${key}": ${err.message}`); diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index 9736c9fe..7f394092 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -7,8 +7,6 @@ import { GuildMember, Message, MessageCreateOptions, - MessageMentionOptions, - ModalSubmitInteraction, PermissionsBitField, TextBasedChannel, User, @@ -23,10 +21,9 @@ import { PluginOverrideCriteria, helpers, } from "knub"; -import { logger } from "./logger"; import { isStaff } from "./staff"; import { TZeppelinKnub } from "./types"; -import { errorMessage, successMessage, tNullable } from "./utils"; +import { tNullable } from "./utils"; import { Tail } from "./utils/typeUtils"; import { StrictValidationError, parseIoTsSchema } from "./validatorUtils"; @@ -103,121 +100,50 @@ export function makeIoTsConfigParser>(schema: Schema) } export function isContextInteraction( - context: TextBasedChannel | User | ChatInputCommandInteraction, + context: TextBasedChannel | Message | User | ChatInputCommandInteraction, ): context is ChatInputCommandInteraction { return "commandId" in context && !!context.commandId; } -export function sendContextResponse( - context: TextBasedChannel | User | ChatInputCommandInteraction, +export function isContextMessage( + context: TextBasedChannel | Message | User | ChatInputCommandInteraction, +): context is Message { + return "content" in context || "embeds" in context; +} + +export async function getContextChannel( + context: TextBasedChannel | Message | User | ChatInputCommandInteraction, +): Promise { + if (isContextInteraction(context)) { + // context is ChatInputCommandInteraction + return context.channel!; + } else if ("username" in context) { + // context is User + return await (context as User).createDM(); + } else if ("send" in context) { + // context is TextBaseChannel + return context as TextBasedChannel; + } else { + // context is Message + return context.channel; + } +} + +export async function sendContextResponse( + context: TextBasedChannel | Message | User | ChatInputCommandInteraction, response: string | Omit, ): Promise { if (isContextInteraction(context)) { const options = { ...(typeof response === "string" ? { content: response } : response), fetchReply: true }; return (context.replied ? context.followUp(options) : context.reply(options)) as Promise; - } else { + } else if ("send" in context) { return context.send(response); + } else { + return (await getContextChannel(context)).send(response); } } -export async function sendSuccessMessage( - pluginData: AnyPluginData, - context: TextBasedChannel | User | ChatInputCommandInteraction, - body: string, - allowedMentions?: MessageMentionOptions, - responseInteraction?: ModalSubmitInteraction, - ephemeral = true, -): Promise { - const emoji = pluginData.fullConfig.success_emoji || undefined; - const formattedBody = successMessage(body, emoji); - const content: MessageCreateOptions = allowedMentions - ? { content: formattedBody, allowedMentions } - : { content: formattedBody }; - - if (responseInteraction) { - await responseInteraction - .editReply({ content: formattedBody, embeds: [], components: [] }) - .catch((err) => logger.error(`Interaction reply failed: ${err}`)); - - return; - } - - if (!isContextInteraction(context)) { - // noinspection TypeScriptValidateJSTypes - return context - .send({ ...content }) // Force line break - .catch((err) => { - const channelInfo = "guild" in context ? `${context.id} (${context.guild.id})` : context.id; - logger.warn(`Failed to send success message to ${channelInfo}): ${err.code} ${err.message}`); - - return undefined; - }); - } - - const replyMethod = context.replied ? "followUp" : "reply"; - - return context[replyMethod]({ - content: formattedBody, - embeds: [], - components: [], - fetchReply: true, - ephemeral, - }).catch((err) => { - logger.error(`Context reply failed: ${err}`); - - return undefined; - }) as Promise; -} - -export async function sendErrorMessage( - pluginData: AnyPluginData, - context: TextBasedChannel | User | ChatInputCommandInteraction, - body: string, - allowedMentions?: MessageMentionOptions, - responseInteraction?: ModalSubmitInteraction, - ephemeral = false, -): Promise { - const emoji = pluginData.fullConfig.error_emoji || undefined; - const formattedBody = errorMessage(body, emoji); - const content: MessageCreateOptions = allowedMentions - ? { content: formattedBody, allowedMentions } - : { content: formattedBody }; - - if (responseInteraction) { - await responseInteraction - .editReply({ content: formattedBody, embeds: [], components: [] }) - .catch((err) => logger.error(`Interaction reply failed: ${err}`)); - - return; - } - - if (!isContextInteraction(context)) { - // noinspection TypeScriptValidateJSTypes - return context - .send({ ...content }) // Force line break - .catch((err) => { - const channelInfo = "guild" in context ? `${context.id} (${context.guild.id})` : context.id; - logger.warn(`Failed to send error message to ${channelInfo}): ${err.code} ${err.message}`); - return undefined; - }); - } - - const replyMethod = context.replied ? "followUp" : "reply"; - - return context[replyMethod]({ - content: formattedBody, - embeds: [], - components: [], - fetchReply: true, - ephemeral, - }).catch((err) => { - logger.error(`Context reply failed: ${err}`); - - return undefined; - }) as Promise; -} - export function getBaseUrl(pluginData: AnyPluginData) { const knub = pluginData.getKnubInstance() as TZeppelinKnub; // @ts-expect-error diff --git a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts index 20f749ea..ec3417d4 100644 --- a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { autoReactionsCmd } from "../types"; export const DisableAutoReactionsCmd = autoReactionsCmd({ @@ -14,12 +14,12 @@ export const DisableAutoReactionsCmd = autoReactionsCmd({ async run({ message: msg, args, pluginData }) { const autoReaction = await pluginData.state.autoReactions.getForChannel(args.channelId); if (!autoReaction) { - sendErrorMessage(pluginData, msg.channel, `Auto-reactions aren't enabled in <#${args.channelId}>`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Auto-reactions aren't enabled in <#${args.channelId}>`); return; } await pluginData.state.autoReactions.removeFromChannel(args.channelId); pluginData.state.cache.delete(args.channelId); - sendSuccessMessage(pluginData, msg.channel, `Auto-reactions disabled in <#${args.channelId}>`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Auto-reactions disabled in <#${args.channelId}>`); }, }); diff --git a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts index a64cb95c..250df4f0 100644 --- a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts @@ -1,10 +1,10 @@ import { PermissionsBitField } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { canUseEmoji, customEmojiRegex, isEmoji } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; import { readChannelPermissions } from "../../../utils/readChannelPermissions"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { autoReactionsCmd } from "../types"; const requiredPermissions = readChannelPermissions | PermissionsBitField.Flags.AddReactions; @@ -25,17 +25,20 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; const missingPermissions = getMissingChannelPermissions(me, args.channel, requiredPermissions); if (missingPermissions) { - sendErrorMessage( - pluginData, - msg.channel, - `Cannot set auto-reactions for that channel. ${missingPermissionError(missingPermissions)}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage( + msg, + `Cannot set auto-reactions for that channel. ${missingPermissionError(missingPermissions)}`, + ); return; } for (const reaction of args.reactions) { if (!isEmoji(reaction)) { - sendErrorMessage(pluginData, msg.channel, "One or more of the specified reactions were invalid!"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, "One or more of the specified reactions were invalid!"); return; } @@ -45,7 +48,9 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ if (customEmojiMatch) { // Custom emoji if (!canUseEmoji(pluginData.client, customEmojiMatch[2])) { - sendErrorMessage(pluginData, msg.channel, "I can only use regular emojis and custom emojis from this server"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, "I can only use regular emojis and custom emojis from this server"); return; } @@ -60,6 +65,6 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ await pluginData.state.autoReactions.set(args.channel.id, finalReactions); pluginData.state.cache.delete(args.channel.id); - sendSuccessMessage(pluginData, msg.channel, `Auto-reactions set for <#${args.channel.id}>`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Auto-reactions set for <#${args.channel.id}>`); }, }); diff --git a/backend/src/plugins/Automod/actions/ban.ts b/backend/src/plugins/Automod/actions/ban.ts index 9cd0fd86..1e63af61 100644 --- a/backend/src/plugins/Automod/actions/ban.ts +++ b/backend/src/plugins/Automod/actions/ban.ts @@ -42,6 +42,7 @@ export const BanAction = automodAction({ await modActions.banUserId( userId, reason, + reason, { contactMethods, caseArgs, diff --git a/backend/src/plugins/Automod/actions/kick.ts b/backend/src/plugins/Automod/actions/kick.ts index 9e6a792d..af95c803 100644 --- a/backend/src/plugins/Automod/actions/kick.ts +++ b/backend/src/plugins/Automod/actions/kick.ts @@ -37,7 +37,7 @@ export const KickAction = automodAction({ const modActions = pluginData.getPlugin(ModActionsPlugin); for (const member of membersToKick) { if (!member) continue; - await modActions.kickMember(member, reason, { contactMethods, caseArgs, isAutomodAction: true }); + await modActions.kickMember(member, reason, reason, { contactMethods, caseArgs, isAutomodAction: true }); } }, }); diff --git a/backend/src/plugins/Automod/actions/mute.ts b/backend/src/plugins/Automod/actions/mute.ts index 3219c712..0afed092 100644 --- a/backend/src/plugins/Automod/actions/mute.ts +++ b/backend/src/plugins/Automod/actions/mute.ts @@ -48,6 +48,7 @@ export const MuteAction = automodAction({ userId, duration, reason, + reason, { contactMethods, caseArgs, isAutomodAction: true }, rolesToRemove, rolesToRestore, diff --git a/backend/src/plugins/Automod/actions/warn.ts b/backend/src/plugins/Automod/actions/warn.ts index 59135cb2..ff79f64f 100644 --- a/backend/src/plugins/Automod/actions/warn.ts +++ b/backend/src/plugins/Automod/actions/warn.ts @@ -37,7 +37,7 @@ export const WarnAction = automodAction({ const modActions = pluginData.getPlugin(ModActionsPlugin); for (const member of membersToWarn) { if (!member) continue; - await modActions.warnMember(member, reason, { contactMethods, caseArgs, isAutomodAction: true }); + await modActions.warnMember(member, reason, reason, { contactMethods, caseArgs, isAutomodAction: true }); } }, }); diff --git a/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts b/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts index fd31d4b1..983a1f99 100644 --- a/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts +++ b/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts @@ -1,5 +1,5 @@ import { guildPluginMessageCommand } from "knub"; -import { sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { setAntiraidLevel } from "../functions/setAntiraidLevel"; import { AutomodPluginType } from "../types"; @@ -9,6 +9,6 @@ export const AntiraidClearCmd = guildPluginMessageCommand()({ async run({ pluginData, message }) { await setAntiraidLevel(pluginData, null, message.author); - sendSuccessMessage(pluginData, message.channel, "Anti-raid turned **off**"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(message, "Anti-raid turned **off**"); }, }); diff --git a/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts b/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts index 159ff576..91cbacd6 100644 --- a/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts +++ b/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts @@ -1,6 +1,6 @@ import { guildPluginMessageCommand } from "knub"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { setAntiraidLevel } from "../functions/setAntiraidLevel"; import { AutomodPluginType } from "../types"; @@ -15,11 +15,11 @@ export const SetAntiraidCmd = guildPluginMessageCommand()({ async run({ pluginData, message, args }) { const config = pluginData.config.get(); if (!config.antiraid_levels.includes(args.level)) { - sendErrorMessage(pluginData, message.channel, "Unknown anti-raid level"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown anti-raid level"); return; } await setAntiraidLevel(pluginData, args.level, message.author); - sendSuccessMessage(pluginData, message.channel, `Anti-raid level set to **${args.level}**`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(message, `Anti-raid level set to **${args.level}**`); }, }); diff --git a/backend/src/plugins/BotControl/BotControlPlugin.ts b/backend/src/plugins/BotControl/BotControlPlugin.ts index 76478ca2..e7d573fc 100644 --- a/backend/src/plugins/BotControl/BotControlPlugin.ts +++ b/backend/src/plugins/BotControl/BotControlPlugin.ts @@ -3,7 +3,8 @@ import { AllowedGuilds } from "../../data/AllowedGuilds"; import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; import { Configs } from "../../data/Configs"; import { GuildArchives } from "../../data/GuildArchives"; -import { makeIoTsConfigParser, sendSuccessMessage } from "../../pluginUtils"; +import { makeIoTsConfigParser } from "../../pluginUtils"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { zeppelinGlobalPlugin } from "../ZeppelinPluginBlueprint"; import { getActiveReload, resetActiveReload } from "./activeReload"; import { AddDashboardUserCmd } from "./commands/AddDashboardUserCmd"; @@ -77,7 +78,7 @@ export const BotControlPlugin = zeppelinGlobalPlugin()({ if (guild) { const channel = guild.channels.cache.get(channelId as Snowflake); if (channel instanceof TextChannel) { - sendSuccessMessage(pluginData, channel, "Global plugins reloaded!"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(channel, "Global plugins reloaded!"); } } } diff --git a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts index c1259594..1e88d679 100644 --- a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts @@ -1,7 +1,8 @@ import { ApiPermissions } from "@shared/apiPermissions"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { isStaffPreFilter } from "../../../pluginUtils"; import { renderUserUsername } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const AddDashboardUserCmd = botControlCmd({ @@ -19,7 +20,7 @@ export const AddDashboardUserCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - sendErrorMessage(pluginData, msg.channel, "Server is not using Zeppelin"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is not using Zeppelin"); return; } @@ -36,10 +37,11 @@ export const AddDashboardUserCmd = botControlCmd({ } const userNameList = args.users.map((user) => `<@!${user.id}> (**${renderUserUsername(user)}**, \`${user.id}\`)`); - sendSuccessMessage( - pluginData, - msg.channel, - `The following users were given dashboard access for **${guild.name}**:\n\n${userNameList}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + msg, + `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 cbf53bf4..97944c1d 100644 --- a/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts @@ -1,8 +1,8 @@ import { ApiPermissions } from "@shared/apiPermissions"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { DBDateFormat, isGuildInvite, resolveInvite } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { isEligible } from "../functions/isEligible"; import { botControlCmd } from "../types"; @@ -18,19 +18,21 @@ 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, "Could not resolve invite"); // :D + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Could not resolve invite"); // :D return; } const existing = await pluginData.state.allowedGuilds.find(invite.guild.id); if (existing) { - sendErrorMessage(pluginData, msg.channel, "Server is already allowed!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is already allowed!"); return; } const { result, explanation } = await isEligible(pluginData, args.user, invite); if (!result) { - sendErrorMessage(pluginData, msg.channel, `Could not add server because it's not eligible: ${explanation}`); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `Could not add server because it's not eligible: ${explanation}`); return; } @@ -51,6 +53,8 @@ export const AddServerFromInviteCmd = botControlCmd({ ); } - sendSuccessMessage(pluginData, msg.channel, "Server was eligible and is now allowed to use Zeppelin!"); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, "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 ce2c3b0c..36e2d17a 100644 --- a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts @@ -1,8 +1,9 @@ import { ApiPermissions } from "@shared/apiPermissions"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { isStaffPreFilter } from "../../../pluginUtils"; import { DBDateFormat, isSnowflake } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const AllowServerCmd = botControlCmd({ @@ -20,17 +21,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, "Server is already allowed!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is already allowed!"); return; } if (!isSnowflake(args.guildId)) { - sendErrorMessage(pluginData, msg.channel, "Invalid server ID!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid server ID!"); return; } if (args.userId && !isSnowflake(args.userId)) { - sendErrorMessage(pluginData, msg.channel, "Invalid user ID!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid user ID!"); return; } @@ -51,6 +52,6 @@ export const AllowServerCmd = botControlCmd({ ); } - sendSuccessMessage(pluginData, msg.channel, "Server is now allowed to use Zeppelin!"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "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 11d3a487..939077e2 100644 --- a/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts @@ -1,5 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter, sendErrorMessage } from "../../../pluginUtils"; +import { isStaffPreFilter } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const ChannelToServerCmd = botControlCmd({ @@ -16,7 +17,7 @@ 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, "Channel not found in cache!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Channel not found in cache!"); return; } diff --git a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts index 06bc1b14..69ba0b4c 100644 --- a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts @@ -1,7 +1,8 @@ import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { isStaffPreFilter } from "../../../pluginUtils"; import { noop } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const DisallowServerCmd = botControlCmd({ @@ -18,7 +19,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, "That server is not allowed in the first place!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "That server is not allowed in the first place!"); return; } @@ -27,6 +28,6 @@ export const DisallowServerCmd = botControlCmd({ .get(args.guildId as Snowflake) ?.leave() .catch(noop); - sendSuccessMessage(pluginData, msg.channel, "Server removed!"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Server removed!"); }, }); diff --git a/backend/src/plugins/BotControl/commands/EligibleCmd.ts b/backend/src/plugins/BotControl/commands/EligibleCmd.ts index face42a8..bbcd5c5d 100644 --- a/backend/src/plugins/BotControl/commands/EligibleCmd.ts +++ b/backend/src/plugins/BotControl/commands/EligibleCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { isGuildInvite, resolveInvite } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { isEligible } from "../functions/isEligible"; import { botControlCmd } from "../types"; @@ -16,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, "Could not resolve invite"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Could not resolve invite"); return; } const { result, explanation } = await isEligible(pluginData, args.user, invite); if (result) { - sendSuccessMessage(pluginData, msg.channel, `Server is eligible: ${explanation}`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Server is eligible: ${explanation}`); return; } - sendErrorMessage(pluginData, msg.channel, `Server is **NOT** eligible: ${explanation}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Server is **NOT** eligible: ${explanation}`); }, }); diff --git a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts index 14aaf833..0066a916 100644 --- a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts @@ -1,6 +1,7 @@ import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { isStaffPreFilter } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const LeaveServerCmd = botControlCmd({ @@ -16,7 +17,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, "I am not in that guild"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "I am not in that guild"); return; } @@ -26,10 +27,10 @@ export const LeaveServerCmd = botControlCmd({ try { await pluginData.client.guilds.cache.get(args.guildId as Snowflake)?.leave(); } catch (e) { - sendErrorMessage(pluginData, msg.channel, `Failed to leave guild: ${e.message}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Failed to leave guild: ${e.message}`); return; } - sendSuccessMessage(pluginData, msg.channel, `Left guild **${guildName}**`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Left guild **${guildName}**`); }, }); diff --git a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts index 18c7d0d7..ecab5434 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts @@ -1,8 +1,8 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { AllowedGuild } from "../../../data/entities/AllowedGuild"; import { ApiPermissionAssignment } from "../../../data/entities/ApiPermissionAssignment"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { renderUserUsername, resolveUser } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const ListDashboardPermsCmd = botControlCmd({ @@ -16,7 +16,7 @@ export const ListDashboardPermsCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { if (!args.user && !args.guildId) { - sendErrorMessage(pluginData, msg.channel, "Must specify at least guildId, user, or both."); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Must specify at least guildId, user, or both."); return; } @@ -24,7 +24,7 @@ export const ListDashboardPermsCmd = botControlCmd({ if (args.guildId) { guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - sendErrorMessage(pluginData, msg.channel, "Server is not using Zeppelin"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is not using Zeppelin"); return; } } @@ -33,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, "The user has no assigned permissions."); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "The user has no assigned permissions."); return; } } @@ -54,11 +54,9 @@ export const ListDashboardPermsCmd = botControlCmd({ } if (finalMessage === "") { - sendErrorMessage( - pluginData, - msg.channel, - `The user ${userInfo} has no assigned permissions on the specified server.`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `The user ${userInfo} has no assigned permissions on the specified server.`); return; } // Else display all users that have permissions on the specified guild @@ -67,7 +65,9 @@ export const ListDashboardPermsCmd = botControlCmd({ const existingGuildAssignment = await pluginData.state.apiPermissionAssignments.getByGuildId(guild.id); if (existingGuildAssignment.length === 0) { - sendErrorMessage(pluginData, msg.channel, `The server ${guildInfo} has no assigned permissions.`); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `The server ${guildInfo} has no assigned permissions.`); return; } @@ -80,6 +80,6 @@ export const ListDashboardPermsCmd = botControlCmd({ } } - await sendSuccessMessage(pluginData, msg.channel, finalMessage.trim(), {}); + await pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, finalMessage.trim(), {}); }, }); diff --git a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts index 36f1432f..f233e1f7 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { renderUserUsername, resolveUser } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const ListDashboardUsersCmd = botControlCmd({ @@ -14,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, "Server is not using Zeppelin"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is not using Zeppelin"); return; } @@ -30,11 +30,12 @@ export const ListDashboardUsersCmd = botControlCmd({ `<@!${user.id}> (**${renderUserUsername(user)}**, \`${user.id}\`): ${permission.permissions.join(", ")}`, ); - sendSuccessMessage( - pluginData, - msg.channel, - `The following users have dashboard access for **${guild.name}**:\n\n${userNameList.join("\n")}`, - {}, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + msg, + `The following users have dashboard access for **${guild.name}**:\n\n${userNameList.join("\n")}`, + {}, + ); }, }); diff --git a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts index 46d2a0e0..9ac5499d 100644 --- a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts +++ b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts @@ -1,7 +1,8 @@ import moment from "moment-timezone"; import { GuildArchives } from "../../../data/GuildArchives"; -import { getBaseUrl, sendSuccessMessage } from "../../../pluginUtils"; +import { getBaseUrl } from "../../../pluginUtils"; import { getRateLimitStats } from "../../../rateLimitStats"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const RateLimitPerformanceCmd = botControlCmd({ @@ -13,7 +14,7 @@ export const RateLimitPerformanceCmd = botControlCmd({ async run({ pluginData, message: msg }) { const logItems = getRateLimitStats(); if (logItems.length === 0) { - sendSuccessMessage(pluginData, msg.channel, `No rate limits hit`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `No rate limits hit`); return; } diff --git a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts index 4f59f8a2..ea51dc00 100644 --- a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts @@ -1,4 +1,5 @@ -import { isStaffPreFilter, sendErrorMessage } from "../../../pluginUtils"; +import { isStaffPreFilter } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { getActiveReload, setActiveReload } from "../activeReload"; import { botControlCmd } from "../types"; @@ -14,7 +15,7 @@ export const ReloadGlobalPluginsCmd = botControlCmd({ 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"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "This command can only be used in a server"); return; } diff --git a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts index 0440129b..8481682e 100644 --- a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts @@ -1,6 +1,7 @@ import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { isStaffPreFilter } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const ReloadServerCmd = botControlCmd({ @@ -16,18 +17,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, "I am not in that guild"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "I am not in that guild"); return; } try { await pluginData.getKnubInstance().reloadGuild(args.guildId); } catch (e) { - sendErrorMessage(pluginData, msg.channel, `Failed to reload guild: ${e.message}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Failed to reload guild: ${e.message}`); return; } const guild = await pluginData.client.guilds.fetch(args.guildId as Snowflake); - sendSuccessMessage(pluginData, msg.channel, `Reloaded guild **${guild?.name || "???"}**`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Reloaded guild **${guild?.name || "???"}**`); }, }); diff --git a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts index 3a90683c..350891a9 100644 --- a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts @@ -1,6 +1,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { isStaffPreFilter } from "../../../pluginUtils"; import { renderUserUsername } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const RemoveDashboardUserCmd = botControlCmd({ @@ -18,7 +19,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, "Server is not using Zeppelin"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is not using Zeppelin"); return; } @@ -35,10 +36,11 @@ export const RemoveDashboardUserCmd = botControlCmd({ } const userNameList = args.users.map((user) => `<@!${user.id}> (**${renderUserUsername(user)}**, \`${user.id}\`)`); - sendSuccessMessage( - pluginData, - msg.channel, - `The following users were removed from the dashboard for **${guild.name}**:\n\n${userNameList}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + msg, + `The following users were removed from the dashboard for **${guild.name}**:\n\n${userNameList}`, + ); }, }); diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index 3fc1b72b..ad9a8f85 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -1,8 +1,9 @@ import { Snowflake } from "discord.js"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isOwner, sendErrorMessage } from "../../../pluginUtils"; +import { isOwner } from "../../../pluginUtils"; import { SECONDS, confirm, noop, renderUsername } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { rehostAttachment } from "../rehostAttachment"; import { channelArchiverCmd } from "../types"; @@ -32,12 +33,12 @@ export const ArchiveChannelCmd = channelArchiverCmd({ async run({ message: msg, args, pluginData }) { if (!args["attachment-channel"]) { - const confirmed = await confirm(msg.channel, msg.author.id, { + const confirmed = await confirm(msg, msg.author.id, { content: "No `-attachment-channel` specified. Continue? Attachments will not be available in the log if their message is deleted.", }); if (!confirmed) { - sendErrorMessage(pluginData, msg.channel, "Canceled"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Canceled"); return; } } diff --git a/backend/src/plugins/Common/CommonPlugin.ts b/backend/src/plugins/Common/CommonPlugin.ts new file mode 100644 index 00000000..a8935907 --- /dev/null +++ b/backend/src/plugins/Common/CommonPlugin.ts @@ -0,0 +1,146 @@ +import { + ChatInputCommandInteraction, + Message, + MessageCreateOptions, + MessageMentionOptions, + ModalSubmitInteraction, + TextBasedChannel, + User, +} from "discord.js"; +import { PluginOptions } from "knub"; +import { logger } from "../../logger"; +import { isContextInteraction, makeIoTsConfigParser, sendContextResponse } from "../../pluginUtils"; +import { errorMessage, successMessage } from "../../utils"; +import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; +import { getErrorEmoji, getSuccessEmoji } from "./functions/getEmoji"; +import { CommonPluginType, ConfigSchema } from "./types"; + +const defaultOptions: PluginOptions = { + config: { + success_emoji: "✅", + error_emoji: "❌", + }, +}; + +export const CommonPlugin = zeppelinGuildPlugin()({ + name: "common", + showInDocs: false, + info: { + prettyName: "Common", + }, + + dependencies: () => [], + configParser: makeIoTsConfigParser(ConfigSchema), + defaultOptions, + public: { + getSuccessEmoji(pluginData) { + return () => getSuccessEmoji(pluginData); + }, + + getErrorEmoji(pluginData) { + return () => getErrorEmoji(pluginData); + }, + + sendSuccessMessage(pluginData) { + return async ( + context: TextBasedChannel | Message | User | ChatInputCommandInteraction, + body: string, + allowedMentions?: MessageMentionOptions, + responseInteraction?: ModalSubmitInteraction, + ephemeral = true, + ): Promise => { + const emoji = getSuccessEmoji(pluginData); + const formattedBody = successMessage(body, emoji); + const content: MessageCreateOptions = allowedMentions + ? { content: formattedBody, allowedMentions } + : { content: formattedBody }; + + if (responseInteraction) { + await responseInteraction + .editReply({ content: formattedBody, embeds: [], components: [] }) + .catch((err) => logger.error(`Interaction reply failed: ${err}`)); + + return; + } + + if (!isContextInteraction(context)) { + // noinspection TypeScriptValidateJSTypes + return sendContextResponse(context, { ...content }) // Force line break + .catch((err) => { + const channelInfo = + "guild" in context && context.guild ? `${context.id} (${context.guild.id})` : context.id; + + logger.warn(`Failed to send success message to ${channelInfo}): ${err.code} ${err.message}`); + + return undefined; + }); + } + + const replyMethod = context.replied ? "followUp" : "reply"; + + return context[replyMethod]({ + content: formattedBody, + embeds: [], + components: [], + fetchReply: true, + ephemeral, + }).catch((err) => { + logger.error(`Context reply failed: ${err}`); + + return undefined; + }) as Promise; + }; + }, + + sendErrorMessage(pluginData) { + return async ( + context: TextBasedChannel | Message | User | ChatInputCommandInteraction, + body: string, + allowedMentions?: MessageMentionOptions, + responseInteraction?: ModalSubmitInteraction, + ephemeral = false, + ): Promise => { + const emoji = getErrorEmoji(pluginData); + const formattedBody = errorMessage(body, emoji); + const content: MessageCreateOptions = allowedMentions + ? { content: formattedBody, allowedMentions } + : { content: formattedBody }; + + if (responseInteraction) { + await responseInteraction + .editReply({ content: formattedBody, embeds: [], components: [] }) + .catch((err) => logger.error(`Interaction reply failed: ${err}`)); + + return; + } + + if (!isContextInteraction(context)) { + // noinspection TypeScriptValidateJSTypes + return sendContextResponse(context, { ...content }) // Force line break + .catch((err) => { + const channelInfo = + "guild" in context && context.guild ? `${context.id} (${context.guild.id})` : context.id; + + logger.warn(`Failed to send error message to ${channelInfo}): ${err.code} ${err.message}`); + + return undefined; + }); + } + + const replyMethod = context.replied ? "followUp" : "reply"; + + return context[replyMethod]({ + content: formattedBody, + embeds: [], + components: [], + fetchReply: true, + ephemeral, + }).catch((err) => { + logger.error(`Context reply failed: ${err}`); + + return undefined; + }) as Promise; + }; + }, + }, +}); diff --git a/backend/src/plugins/Common/functions/getEmoji.ts b/backend/src/plugins/Common/functions/getEmoji.ts new file mode 100644 index 00000000..c1910250 --- /dev/null +++ b/backend/src/plugins/Common/functions/getEmoji.ts @@ -0,0 +1,10 @@ +import { GuildPluginData } from "knub"; +import { CommonPluginType } from "../types"; + +export function getSuccessEmoji(pluginData: GuildPluginData) { + return pluginData.config.get().success_emoji ?? "✅"; +} + +export function getErrorEmoji(pluginData: GuildPluginData) { + return pluginData.config.get().error_emoji ?? "❌"; +} diff --git a/backend/src/plugins/Common/types.ts b/backend/src/plugins/Common/types.ts new file mode 100644 index 00000000..d0c8df85 --- /dev/null +++ b/backend/src/plugins/Common/types.ts @@ -0,0 +1,13 @@ +import * as t from "io-ts"; +import { BasePluginType } from "knub"; + +export const ConfigSchema = t.type({ + success_emoji: t.string, + error_emoji: t.string, +}); + +export type TConfigSchema = t.TypeOf; + +export interface CommonPluginType extends BasePluginType { + config: TConfigSchema; +} diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts index f2b391cc..9848f5d5 100644 --- a/backend/src/plugins/ContextMenus/actions/ban.ts +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -55,7 +55,7 @@ async function banAction( }; const durationMs = duration ? convertDelayStringToMS(duration)! : undefined; - const result = await modactions.banUserId(target, reason, { caseArgs }, durationMs); + const result = await modactions.banUserId(target, reason, reason, { caseArgs }, durationMs); if (result.status === "failed") { await interactionToReply .editReply({ content: "Error: Failed to ban user", embeds: [], components: [] }) diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index 58457cb0..5959f6d7 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -68,7 +68,7 @@ async function muteAction( const durationMs = duration ? convertDelayStringToMS(duration)! : undefined; try { - const result = await mutes.muteUser(target, durationMs, reason, { caseArgs }); + const result = await mutes.muteUser(target, durationMs, reason, reason, { caseArgs }); const messageResultText = result.notifyResult.text ? ` (${result.notifyResult.text})` : ""; const muteMessage = `Muted **${result.case.user_name}** ${ diff --git a/backend/src/plugins/ContextMenus/actions/warn.ts b/backend/src/plugins/ContextMenus/actions/warn.ts index 6fbd40f3..b467ed61 100644 --- a/backend/src/plugins/ContextMenus/actions/warn.ts +++ b/backend/src/plugins/ContextMenus/actions/warn.ts @@ -60,7 +60,7 @@ async function warnAction( modId: executingMember.id, }; - const result = await modactions.warnMember(targetMember, reason, { caseArgs }); + const result = await modactions.warnMember(targetMember, reason, reason, { caseArgs }); if (result.status === "failed") { await interactionToReply .editReply({ content: "Error: Failed to warn user", embeds: [], components: [] }) diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index a71418df..0eb68f2b 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -2,8 +2,8 @@ import { Snowflake, TextChannel } from "discord.js"; import { guildPluginMessageCommand } from "knub"; import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { UnknownUser, resolveUser } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { changeCounterValue } from "../functions/changeCounterValue"; import { CountersPluginType } from "../types"; @@ -45,22 +45,22 @@ export const AddCounterCmd = guildPluginMessageCommand()({ const counter = config.counters[args.counterName]; const counterId = pluginData.state.counterIds[args.counterName]; if (!counter || !counterId) { - sendErrorMessage(pluginData, message.channel, `Unknown counter: ${args.counterName}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Unknown counter: ${args.counterName}`); return; } if (counter.can_edit === false) { - sendErrorMessage(pluginData, message.channel, `Missing permissions to edit this counter's value`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Missing permissions to edit this counter's value`); return; } if (args.channel && !counter.per_channel) { - sendErrorMessage(pluginData, message.channel, `This counter is not per-channel`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-channel`); return; } if (args.user && !counter.per_user) { - sendErrorMessage(pluginData, message.channel, `This counter is not per-user`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-user`); return; } @@ -69,13 +69,13 @@ export const AddCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which channel's counter value would you like to add to?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - sendErrorMessage(pluginData, message.channel, "Cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); return; } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { - sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Channel is not a text channel, cancelling"); return; } @@ -87,13 +87,13 @@ export const AddCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which user's counter value would you like to add to?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - sendErrorMessage(pluginData, message.channel, "Cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); return; } const potentialUser = await resolveUser(pluginData.client, reply.content); if (!potentialUser || potentialUser instanceof UnknownUser) { - sendErrorMessage(pluginData, message.channel, "Unknown user, cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown user, cancelling"); return; } @@ -105,13 +105,13 @@ export const AddCounterCmd = guildPluginMessageCommand()({ message.channel.send("How much would you like to add to the counter's value?"); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - sendErrorMessage(pluginData, message.channel, "Cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); return; } const potentialAmount = parseInt(reply.content, 10); if (!potentialAmount) { - sendErrorMessage(pluginData, message.channel, "Not a number, cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Not a number, cancelling"); return; } diff --git a/backend/src/plugins/Counters/commands/CountersListCmd.ts b/backend/src/plugins/Counters/commands/CountersListCmd.ts index 84a0a272..db83812e 100644 --- a/backend/src/plugins/Counters/commands/CountersListCmd.ts +++ b/backend/src/plugins/Counters/commands/CountersListCmd.ts @@ -1,7 +1,7 @@ import { guildPluginMessageCommand } from "knub"; -import { sendErrorMessage } from "../../../pluginUtils"; import { trimMultilineString, ucfirst } from "../../../utils"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { CountersPluginType } from "../types"; export const CountersListCmd = guildPluginMessageCommand()({ @@ -15,7 +15,7 @@ export const CountersListCmd = guildPluginMessageCommand()({ const countersToShow = Array.from(Object.values(config.counters)).filter((c) => c.can_view !== false); if (!countersToShow.length) { - sendErrorMessage(pluginData, message.channel, "No counters are configured for this server"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "No counters are configured for this server"); return; } diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index 3a44ecaa..e413cf21 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -1,7 +1,7 @@ import { guildPluginMessageCommand } from "knub"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { confirm, noop, trimMultilineString } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { resetAllCounterValues } from "../functions/resetAllCounterValues"; import { CountersPluginType } from "../types"; @@ -18,17 +18,19 @@ export const ResetAllCounterValuesCmd = guildPluginMessageCommand()({ const counter = config.counters[args.counterName]; const counterId = pluginData.state.counterIds[args.counterName]; if (!counter || !counterId) { - sendErrorMessage(pluginData, message.channel, `Unknown counter: ${args.counterName}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Unknown counter: ${args.counterName}`); return; } if (counter.can_edit === false) { - sendErrorMessage(pluginData, message.channel, `Missing permissions to reset this counter's value`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Missing permissions to reset this counter's value`); return; } if (args.channel && !counter.per_channel) { - sendErrorMessage(pluginData, message.channel, `This counter is not per-channel`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-channel`); return; } if (args.user && !counter.per_user) { - sendErrorMessage(pluginData, message.channel, `This counter is not per-user`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-user`); return; } @@ -64,13 +64,13 @@ export const ResetCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which channel's counter value would you like to reset?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - sendErrorMessage(pluginData, message.channel, "Cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); return; } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { - sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Channel is not a text channel, cancelling"); return; } @@ -82,13 +82,13 @@ export const ResetCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which user's counter value would you like to reset?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - sendErrorMessage(pluginData, message.channel, "Cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); return; } const potentialUser = await resolveUser(pluginData.client, reply.content); if (!potentialUser || potentialUser instanceof UnknownUser) { - sendErrorMessage(pluginData, message.channel, "Unknown user, cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown user, cancelling"); return; } diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index ba6fbc3a..3cc62c54 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -2,8 +2,8 @@ import { Snowflake, TextChannel } from "discord.js"; import { guildPluginMessageCommand } from "knub"; import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { UnknownUser, resolveUser } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { setCounterValue } from "../functions/setCounterValue"; import { CountersPluginType } from "../types"; @@ -45,22 +45,22 @@ export const SetCounterCmd = guildPluginMessageCommand()({ const counter = config.counters[args.counterName]; const counterId = pluginData.state.counterIds[args.counterName]; if (!counter || !counterId) { - sendErrorMessage(pluginData, message.channel, `Unknown counter: ${args.counterName}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Unknown counter: ${args.counterName}`); return; } if (counter.can_edit === false) { - sendErrorMessage(pluginData, message.channel, `Missing permissions to edit this counter's value`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Missing permissions to edit this counter's value`); return; } if (args.channel && !counter.per_channel) { - sendErrorMessage(pluginData, message.channel, `This counter is not per-channel`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-channel`); return; } if (args.user && !counter.per_user) { - sendErrorMessage(pluginData, message.channel, `This counter is not per-user`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-user`); return; } @@ -69,13 +69,13 @@ export const SetCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which channel's counter value would you like to change?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - sendErrorMessage(pluginData, message.channel, "Cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); return; } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { - sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Channel is not a text channel, cancelling"); return; } @@ -87,13 +87,13 @@ export const SetCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which user's counter value would you like to change?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - sendErrorMessage(pluginData, message.channel, "Cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); return; } const potentialUser = await resolveUser(pluginData.client, reply.content); if (!potentialUser || potentialUser instanceof UnknownUser) { - sendErrorMessage(pluginData, message.channel, "Unknown user, cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown user, cancelling"); return; } @@ -105,13 +105,13 @@ export const SetCounterCmd = guildPluginMessageCommand()({ message.channel.send("What would you like to set the counter's value to?"); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - sendErrorMessage(pluginData, message.channel, "Cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); return; } const potentialValue = parseInt(reply.content, 10); if (Number.isNaN(potentialValue)) { - sendErrorMessage(pluginData, message.channel, "Not a number, cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Not a number, cancelling"); return; } @@ -119,7 +119,7 @@ export const SetCounterCmd = guildPluginMessageCommand()({ } if (value < 0) { - sendErrorMessage(pluginData, message.channel, "Cannot set counter value below 0"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cannot set counter value below 0"); return; } diff --git a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts index d2715c0c..1c037e69 100644 --- a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts @@ -2,8 +2,8 @@ import { Snowflake } from "discord.js"; import { guildPluginMessageCommand } from "knub"; import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { resolveUser, UnknownUser } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { CountersPluginType } from "../types"; export const ViewCounterCmd = guildPluginMessageCommand()({ @@ -39,22 +39,22 @@ export const ViewCounterCmd = guildPluginMessageCommand()({ const counter = config.counters[args.counterName]; const counterId = pluginData.state.counterIds[args.counterName]; if (!counter || !counterId) { - sendErrorMessage(pluginData, message.channel, `Unknown counter: ${args.counterName}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Unknown counter: ${args.counterName}`); return; } if (counter.can_view === false) { - sendErrorMessage(pluginData, message.channel, `Missing permissions to view this counter's value`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Missing permissions to view this counter's value`); return; } if (args.channel && !counter.per_channel) { - sendErrorMessage(pluginData, message.channel, `This counter is not per-channel`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-channel`); return; } if (args.user && !counter.per_user) { - sendErrorMessage(pluginData, message.channel, `This counter is not per-user`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-user`); return; } @@ -63,13 +63,13 @@ export const ViewCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which channel's counter value would you like to view?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - sendErrorMessage(pluginData, message.channel, "Cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); return; } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel?.isTextBased()) { - sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Channel is not a text channel, cancelling"); return; } @@ -81,13 +81,13 @@ export const ViewCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which user's counter value would you like to view?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - sendErrorMessage(pluginData, message.channel, "Cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); return; } const potentialUser = await resolveUser(pluginData.client, reply.content); if (!potentialUser || potentialUser instanceof UnknownUser) { - sendErrorMessage(pluginData, message.channel, "Unknown user, cancelling"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown user, cancelling"); return; } diff --git a/backend/src/plugins/CustomEvents/functions/runEvent.ts b/backend/src/plugins/CustomEvents/functions/runEvent.ts index 8e38b9ab..5ea3ceca 100644 --- a/backend/src/plugins/CustomEvents/functions/runEvent.ts +++ b/backend/src/plugins/CustomEvents/functions/runEvent.ts @@ -1,7 +1,7 @@ import { Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { sendErrorMessage } from "../../../pluginUtils"; import { TemplateSafeValueContainer } from "../../../templateFormatter"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { ActionError } from "../ActionError"; import { addRoleAction } from "../actions/addRoleAction"; import { createCaseAction } from "../actions/createCaseAction"; @@ -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, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage((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/LocateUser/commands/FollowCmd.ts b/backend/src/plugins/LocateUser/commands/FollowCmd.ts index 1011f771..a214241b 100644 --- a/backend/src/plugins/LocateUser/commands/FollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/FollowCmd.ts @@ -2,8 +2,8 @@ import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { registerExpiringVCAlert } from "../../../data/loops/expiringVCAlertsLoop"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { MINUTES, SECONDS } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { locateUserCmd } from "../types"; export const FollowCmd = locateUserCmd({ @@ -27,7 +27,9 @@ export const FollowCmd = locateUserCmd({ const active = args.active || false; if (time < 30 * SECONDS) { - sendErrorMessage(pluginData, msg.channel, "Sorry, but the minimum duration for an alert is 30 seconds!"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, "Sorry, but the minimum duration for an alert is 30 seconds!"); return; } @@ -46,19 +48,23 @@ export const FollowCmd = locateUserCmd({ } if (active) { - sendSuccessMessage( - pluginData, - msg.channel, - `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration( - time, - )} i will notify and move you.\nPlease make sure to be in a voice channel, otherwise i cannot move you!`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + msg, + `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration( + time, + )} i will notify and move you.\nPlease make sure to be in a voice channel, otherwise i cannot move you!`, + ); } else { - sendSuccessMessage( - pluginData, - msg.channel, - `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration(time)} i will notify you`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + msg, + `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration( + time, + )} i will notify you`, + ); } }, }); diff --git a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts index d598d8a9..271b401d 100644 --- a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts @@ -1,7 +1,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { clearExpiringVCAlert } from "../../../data/loops/expiringVCAlertsLoop"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { createChunkedMessage, sorter } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { locateUserCmd } from "../types"; export const ListFollowCmd = locateUserCmd({ @@ -13,7 +13,7 @@ export const ListFollowCmd = locateUserCmd({ async run({ message: msg, pluginData }) { const alerts = await pluginData.state.alerts.getAlertsByRequestorId(msg.member.id); if (alerts.length === 0) { - sendErrorMessage(pluginData, msg.channel, "You have no active alerts!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You have no active alerts!"); return; } @@ -46,7 +46,7 @@ export const DeleteFollowCmd = locateUserCmd({ alerts.sort(sorter("expires_at")); if (args.num > alerts.length || args.num <= 0) { - sendErrorMessage(pluginData, msg.channel, "Unknown alert!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown alert!"); return; } @@ -54,6 +54,6 @@ export const DeleteFollowCmd = locateUserCmd({ clearExpiringVCAlert(toDelete); await pluginData.state.alerts.delete(toDelete.id); - sendSuccessMessage(pluginData, msg.channel, "Alert deleted"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Alert deleted"); }, }); diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts index 8d044d59..f6dbd96b 100644 --- a/backend/src/plugins/LocateUser/utils/moveMember.ts +++ b/backend/src/plugins/LocateUser/utils/moveMember.ts @@ -1,6 +1,6 @@ import { GuildMember, GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { sendErrorMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { LocateUserPluginType } from "../types"; export async function moveMember( @@ -16,10 +16,14 @@ export async function moveMember( channel: target.voice.channelId, }); } catch { - sendErrorMessage(pluginData, errorChannel, "Failed to move you. Are you in a voice channel?"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(errorChannel, "Failed to move you. Are you in a voice channel?"); return; } } else { - sendErrorMessage(pluginData, errorChannel, "Failed to move you. Are you in a voice channel?"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(errorChannel, "Failed to move you. Are you in a voice channel?"); } } diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts index 7faaad80..8d40e99c 100644 --- a/backend/src/plugins/LocateUser/utils/sendWhere.ts +++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts @@ -1,7 +1,7 @@ import { GuildMember, GuildTextBasedChannel, Invite, VoiceChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { getInviteLink } from "knub/helpers"; -import { sendErrorMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { LocateUserPluginType } from "../types"; import { createOrReuseInvite } from "./createOrReuseInvite"; @@ -22,7 +22,7 @@ export async function sendWhere( try { invite = await createOrReuseInvite(voice); } catch { - sendErrorMessage(pluginData, channel, "Cannot create an invite to that channel!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(channel, "Cannot create an invite to that channel!"); return; } channel.send({ diff --git a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts index 3d2456e8..6b9211f1 100644 --- a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { saveMessagesToDB } from "../saveMessagesToDB"; import { messageSaverCmd } from "../types"; @@ -18,13 +18,14 @@ export const SaveMessagesToDBCmd = messageSaverCmd({ const { savedCount, failed } = await saveMessagesToDB(pluginData, args.channel, args.ids.trim().split(" ")); if (failed.length) { - sendSuccessMessage( - pluginData, - msg.channel, - `Saved ${savedCount} messages. The following messages could not be saved: ${failed.join(", ")}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + msg, + `Saved ${savedCount} messages. The following messages could not be saved: ${failed.join(", ")}`, + ); } else { - sendSuccessMessage(pluginData, msg.channel, `Saved ${savedCount} messages!`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Saved ${savedCount} messages!`); } }, }); diff --git a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts index e81c73fe..92c5393d 100644 --- a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { saveMessagesToDB } from "../saveMessagesToDB"; import { messageSaverCmd } from "../types"; @@ -19,13 +19,14 @@ export const SavePinsToDBCmd = messageSaverCmd({ const { savedCount, failed } = await saveMessagesToDB(pluginData, args.channel, [...pins.keys()]); if (failed.length) { - sendSuccessMessage( - pluginData, - msg.channel, - `Saved ${savedCount} messages. The following messages could not be saved: ${failed.join(", ")}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + msg, + `Saved ${savedCount} messages. The following messages could not be saved: ${failed.join(", ")}`, + ); } else { - sendSuccessMessage(pluginData, msg.channel, `Saved ${savedCount} messages!`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Saved ${savedCount} messages!`); } }, }); diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index d9b08381..12eb729e 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -72,6 +72,7 @@ import { onModActionsEvent } from "./functions/onModActionsEvent"; import { updateCase } from "./functions/updateCase"; import { warnMember } from "./functions/warnMember"; import { + AttachmentLinkReactionType, BanOptions, ConfigSchema, KickOptions, @@ -100,6 +101,8 @@ const defaultOptions = { warn_notify_message: "The user already has **{priorWarnings}** warnings!\n Please check their prior cases and assess whether or not to warn anyways.\n Proceed with the warning?", ban_delete_message_days: 1, + attachment_link_reaction: "warn" as AttachmentLinkReactionType, + attachment_storing_channel: null, can_note: false, can_warn: false, @@ -217,26 +220,32 @@ export const ModActionsPlugin = zeppelinGuildPlugin()({ public: { warnMember(pluginData) { - return (member: GuildMember, reason: string, warnOptions?: WarnOptions) => { - return warnMember(pluginData, member, reason, warnOptions); + return (member: GuildMember, reason: string, reasonWithAttachments: string, warnOptions?: WarnOptions) => { + return warnMember(pluginData, member, reason, reasonWithAttachments, warnOptions); }; }, kickMember(pluginData) { - return (member: GuildMember, reason: string, kickOptions?: KickOptions) => { - kickMember(pluginData, member, reason, kickOptions); + return (member: GuildMember, reason: string, reasonWithAttachments: string, kickOptions?: KickOptions) => { + kickMember(pluginData, member, reason, reasonWithAttachments, kickOptions); }; }, banUserId(pluginData) { - return (userId: string, reason?: string, banOptions?: BanOptions, banTime?: number) => { - return banUserId(pluginData, userId, reason, banOptions, banTime); + return ( + userId: string, + reason?: string, + reasonWithAttachments?: string, + banOptions?: BanOptions, + banTime?: number, + ) => { + return banUserId(pluginData, userId, reason, reasonWithAttachments, banOptions, banTime); }; }, updateCase(pluginData) { return (msg: Message, caseNumber: number | null, note: string) => { - updateCase(pluginData, msg.channel, msg.author, caseNumber ?? undefined, note, [...msg.attachments.values()]); + updateCase(pluginData, msg, msg.author, caseNumber ?? undefined, note, [...msg.attachments.values()]); }; }, diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts index 41c2a380..beb4cc3d 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts @@ -1,7 +1,8 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { CaseTypes } from "../../../../data/CaseTypes"; -import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { hasPermission } from "../../../../pluginUtils"; import { resolveUser } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualAddCaseCmd } from "../../functions/actualCommands/actualAddCaseCmd"; import { modActionsMsgCmd } from "../../types"; @@ -27,7 +28,7 @@ export const AddCaseMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } @@ -35,7 +36,7 @@ export const AddCaseMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -45,13 +46,13 @@ export const AddCaseMsgCmd = modActionsMsgCmd({ // Verify the case type is valid const type: string = args.type[0].toUpperCase() + args.type.slice(1).toLowerCase(); if (!CaseTypes[type]) { - sendErrorMessage(pluginData, msg.channel, "Cannot add case: invalid case type"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot add case: invalid case type"); return; } actualAddCaseCmd( pluginData, - msg.channel, + msg, msg.member, mod, [...msg.attachments.values()], diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts index b5fbfc5f..c83a6b42 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts @@ -1,7 +1,8 @@ import { slashOptions } from "knub"; import { CaseTypes } from "../../../../data/CaseTypes"; -import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { hasPermission } from "../../../../pluginUtils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualAddCaseCmd } from "../../functions/actualCommands/actualAddCaseCmd"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -44,7 +45,9 @@ export const AddCaseSlashCmd = { if (options.mod) { if (!canActAsOther) { - sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts index efea59d7..10b4344c 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts @@ -1,6 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, resolveUser } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualBanCmd } from "../../functions/actualCommands/actualBanCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -37,7 +38,7 @@ export const BanMsgCmd = modActionsMsgCmd({ const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } @@ -45,7 +46,7 @@ export const BanMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -56,13 +57,13 @@ export const BanMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args) ?? undefined; } catch (e) { - sendErrorMessage(pluginData, msg.channel, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); return; } actualBanCmd( pluginData, - msg.channel, + msg, user, args["time"] ? args["time"] : null, args.reason || "", diff --git a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts index acd19a43..dd86a546 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts @@ -1,8 +1,9 @@ import { ChannelType } from "discord.js"; import { slashOptions } from "knub"; -import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualBanCmd } from "../../functions/actualCommands/actualBanCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -49,7 +50,9 @@ export const BanSlashCmd = { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -62,7 +65,9 @@ export const BanSlashCmd = { if (options.mod) { if (!canActAsOther) { - sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } @@ -73,13 +78,13 @@ export const BanSlashCmd = { try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - sendErrorMessage(pluginData, interaction, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); return; } const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; if (options.time && !convertedTime) { - sendErrorMessage(pluginData, interaction, `Could not convert ${options.time} to a delay`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } diff --git a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts index 6521e327..914cec0f 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts @@ -14,6 +14,6 @@ export const CaseMsgCmd = modActionsMsgCmd({ ], async run({ pluginData, message: msg, args }) { - actualCaseCmd(pluginData, msg.channel, msg.author.id, args.caseNumber); + actualCaseCmd(pluginData, msg, msg.author.id, args.caseNumber); }, }); diff --git a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts index b9e496b7..717ea531 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts @@ -29,7 +29,7 @@ export const CasesModMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { return actualCasesCmd( pluginData, - msg.channel, + msg, args.mod, null, msg.author, diff --git a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts index 765524df..dd50a5de 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { sendErrorMessage } from "../../../../pluginUtils"; import { resolveUser } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualCasesCmd } from "../../functions/actualCommands/actualCasesCmd"; import { modActionsMsgCmd } from "../../types"; @@ -33,13 +33,13 @@ export const CasesUserMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } return actualCasesCmd( pluginData, - msg.channel, + msg, args.mod, user, msg.author, diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts index 70dbc92f..b4c96a68 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts @@ -18,6 +18,6 @@ export const DeleteCaseMsgCmd = modActionsMsgCmd({ }, async run({ pluginData, message, args }) { - actualDeleteCaseCmd(pluginData, message.channel, message.member, args.caseNumber, args.force); + actualDeleteCaseCmd(pluginData, message, message.member, args.caseNumber, args.force); }, }); diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts index ee0e4fa7..e15f3c13 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts @@ -1,6 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualForceBanCmd } from "../../functions/actualCommands/actualForceBanCmd"; import { isBanned } from "../../functions/isBanned"; import { modActionsMsgCmd } from "../../types"; @@ -26,21 +27,21 @@ export const ForceBanMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } // If the user exists as a guild member, make sure we can act on them first const member = await resolveMember(pluginData.client, pluginData.guild, user.id); if (member && !canActOn(pluginData, msg.member, member)) { - sendErrorMessage(pluginData, msg.channel, "Cannot forceban this user: insufficient permissions"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot forceban this user: insufficient permissions"); return; } // Make sure the user isn't already banned const banned = await isBanned(pluginData, user.id); if (banned) { - sendErrorMessage(pluginData, msg.channel, `User is already banned`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User is already banned`); return; } @@ -48,13 +49,13 @@ export const ForceBanMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); return; } mod = args.mod; } - actualForceBanCmd(pluginData, msg.channel, msg.author.id, user, args.reason, [...msg.attachments.values()], mod); + actualForceBanCmd(pluginData, msg, msg.author.id, user, args.reason, [...msg.attachments.values()], mod); }, }); diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts index c1722fcc..c246982e 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts @@ -1,7 +1,8 @@ import { slashOptions } from "knub"; -import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { hasPermission } from "../../../../pluginUtils"; import { convertDelayStringToMS } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualForceBanCmd } from "../../functions/actualCommands/actualForceBanCmd"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -26,7 +27,9 @@ export const ForceBanSlashCmd = { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -39,7 +42,9 @@ export const ForceBanSlashCmd = { if (options.mod) { if (!canActAsOther) { - sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } @@ -48,7 +53,7 @@ export const ForceBanSlashCmd = { const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; if (options.time && !convertedTime) { - sendErrorMessage(pluginData, interaction, `Could not convert ${options.time} to a delay`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts index 9ecbae61..9c2a9cbb 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts @@ -1,6 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -35,7 +36,7 @@ export const ForceMuteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } @@ -43,7 +44,7 @@ export const ForceMuteMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to mute this user if (memberToMute && !canActOn(pluginData, msg.member, memberToMute)) { - sendErrorMessage(pluginData, msg.channel, "Cannot mute: insufficient permissions"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot mute: insufficient permissions"); return; } @@ -53,7 +54,7 @@ export const ForceMuteMsgCmd = modActionsMsgCmd({ if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -65,13 +66,13 @@ export const ForceMuteMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - sendErrorMessage(pluginData, msg.channel, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); return; } actualMuteCmd( pluginData, - msg.channel, + msg, user, [...msg.attachments.values()], mod, diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts index b32cde4f..6d6c2fb9 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts @@ -1,8 +1,9 @@ import { ChannelType } from "discord.js"; import { slashOptions } from "knub"; -import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -44,7 +45,9 @@ export const ForceMuteSlashCmd = { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -58,7 +61,9 @@ export const ForceMuteSlashCmd = { if (options.mod) { if (!canActAsOther) { - sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } @@ -68,7 +73,7 @@ export const ForceMuteSlashCmd = { const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; if (options.time && !convertedTime) { - sendErrorMessage(pluginData, interaction, `Could not convert ${options.time} to a delay`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } @@ -76,7 +81,7 @@ export const ForceMuteSlashCmd = { try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - sendErrorMessage(pluginData, interaction, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts index c1b97351..f9351d8f 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts @@ -1,6 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; import { modActionsMsgCmd } from "../../types"; @@ -32,13 +33,13 @@ export const ForceUnmuteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } // Check if they're muted in the first place if (!(await pluginData.state.mutes.isMuted(user.id))) { - sendErrorMessage(pluginData, msg.channel, "Cannot unmute: member is not muted"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot unmute: member is not muted"); return; } @@ -47,7 +48,7 @@ export const ForceUnmuteMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to unmute this member if (memberToUnmute && !canActOn(pluginData, msg.member, memberToUnmute)) { - sendErrorMessage(pluginData, msg.channel, "Cannot unmute: insufficient permissions"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot unmute: insufficient permissions"); return; } @@ -57,7 +58,7 @@ export const ForceUnmuteMsgCmd = modActionsMsgCmd({ if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -67,7 +68,7 @@ export const ForceUnmuteMsgCmd = modActionsMsgCmd({ actualUnmuteCmd( pluginData, - msg.channel, + msg, user, [...msg.attachments.values()], mod, diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts index 107151a8..3c68a64e 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts @@ -1,7 +1,8 @@ import { slashOptions } from "knub"; -import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { hasPermission } from "../../../../pluginUtils"; import { convertDelayStringToMS } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -27,7 +28,9 @@ export const ForceUnmuteSlashCmd = { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -41,7 +44,9 @@ export const ForceUnmuteSlashCmd = { if (options.mod) { if (!canActAsOther) { - sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } @@ -51,7 +56,7 @@ export const ForceUnmuteSlashCmd = { const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; if (options.time && !convertedTime) { - sendErrorMessage(pluginData, interaction, `Could not convert ${options.time} to a delay`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts index e7701d4a..3d160d5f 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts @@ -14,6 +14,6 @@ export const HideCaseMsgCmd = modActionsMsgCmd({ ], async run({ pluginData, message: msg, args }) { - actualHideCaseCmd(pluginData, msg.channel, args.caseNum); + actualHideCaseCmd(pluginData, msg, args.caseNum); }, }); diff --git a/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts index bab6064d..fb2754e0 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts @@ -1,7 +1,7 @@ import { hasPermission } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { sendErrorMessage } from "../../../../pluginUtils"; import { resolveUser } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualKickCmd } from "../../functions/actualCommands/actualKickCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -30,7 +30,7 @@ export const KickMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } @@ -38,7 +38,7 @@ export const KickMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(await pluginData.config.getForMessage(msg), "can_act_as_other"))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -49,13 +49,13 @@ export const KickMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - sendErrorMessage(pluginData, msg.channel, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); return; } actualKickCmd( pluginData, - msg.channel, + msg, msg.member, user, args.reason, diff --git a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts index 46041006..961445ec 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts @@ -1,8 +1,9 @@ import { ChannelType } from "discord.js"; import { slashOptions } from "knub"; -import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualKickCmd } from "../../functions/actualCommands/actualKickCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -48,7 +49,9 @@ export const KickSlashCmd = { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -61,7 +64,9 @@ export const KickSlashCmd = { if (options.mod) { if (!canActAsOther) { - sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } @@ -72,7 +77,7 @@ export const KickSlashCmd = { try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - sendErrorMessage(pluginData, interaction, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts index 222dbacc..d607224a 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts @@ -14,6 +14,6 @@ export const MassBanMsgCmd = modActionsMsgCmd({ ], async run({ pluginData, message: msg, args }) { - actualMassBanCmd(pluginData, msg.channel, args.userIds, msg.member); + actualMassBanCmd(pluginData, msg, args.userIds, msg.member); }, }); diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts index 0d7793ce..a09a5f26 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts @@ -14,6 +14,6 @@ export const MassMuteMsgCmd = modActionsMsgCmd({ ], async run({ pluginData, message: msg, args }) { - actualMassMuteCmd(pluginData, msg.channel, args.userIds, msg.member); + actualMassMuteCmd(pluginData, msg, args.userIds, msg.member); }, }); diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts index 8508b00e..72713ad5 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts @@ -14,6 +14,6 @@ export const MassUnbanMsgCmd = modActionsMsgCmd({ ], async run({ pluginData, message: msg, args }) { - actualMassBanCmd(pluginData, msg.channel, args.userIds, msg.member); + actualMassBanCmd(pluginData, msg, args.userIds, msg.member); }, }); diff --git a/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts index 16a5343f..469d7162 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts @@ -1,7 +1,8 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; @@ -37,7 +38,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } @@ -47,22 +48,20 @@ export const MuteMsgCmd = modActionsMsgCmd({ const _isBanned = await isBanned(pluginData, user.id); const prefix = pluginData.fullConfig.prefix; if (_isBanned) { - sendErrorMessage( - pluginData, - msg.channel, - `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.`); return; } else { // Ask the mod if we should upgrade to a forcemute as the user is not on the server const reply = await waitForButtonConfirm( - msg.channel, + msg, { content: "User not found on the server, forcemute instead?" }, { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, ); if (!reply) { - sendErrorMessage(pluginData, msg.channel, "User not on server, mute cancelled by moderator"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "User not on server, mute cancelled by moderator"); return; } } @@ -70,7 +69,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to mute this member if (memberToMute && !canActOn(pluginData, msg.member, memberToMute)) { - sendErrorMessage(pluginData, msg.channel, "Cannot mute: insufficient permissions"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot mute: insufficient permissions"); return; } @@ -80,7 +79,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -92,13 +91,13 @@ export const MuteMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - sendErrorMessage(pluginData, msg.channel, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); return; } actualMuteCmd( pluginData, - msg.channel, + msg, user, [...msg.attachments.values()], mod, diff --git a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts index c17200fc..c84ce9ef 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts @@ -1,9 +1,10 @@ import { ChannelType } from "discord.js"; import { slashOptions } from "knub"; -import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { canActOn, hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; @@ -46,7 +47,9 @@ export const MuteSlashCmd = { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -57,11 +60,9 @@ export const MuteSlashCmd = { const _isBanned = await isBanned(pluginData, options.user.id); const prefix = pluginData.fullConfig.prefix; if (_isBanned) { - sendErrorMessage( - pluginData, - interaction, - `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.`); return; } else { // Ask the mod if we should upgrade to a forcemute as the user is not on the server @@ -72,7 +73,9 @@ export const MuteSlashCmd = { ); if (!reply) { - sendErrorMessage(pluginData, interaction, "User not on server, mute cancelled by moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "User not on server, mute cancelled by moderator"); return; } } @@ -80,7 +83,7 @@ export const MuteSlashCmd = { // Make sure we're allowed to mute this member if (memberToMute && !canActOn(pluginData, interaction.member, memberToMute)) { - sendErrorMessage(pluginData, interaction, "Cannot mute: insufficient permissions"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot mute: insufficient permissions"); return; } @@ -93,7 +96,9 @@ export const MuteSlashCmd = { if (options.mod) { if (!canActAsOther) { - sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } @@ -103,7 +108,7 @@ export const MuteSlashCmd = { const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; if (options.time && !convertedTime) { - sendErrorMessage(pluginData, interaction, `Could not convert ${options.time} to a delay`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } @@ -111,7 +116,7 @@ export const MuteSlashCmd = { try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - sendErrorMessage(pluginData, interaction, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts index 14336d89..9861702f 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { sendErrorMessage } from "../../../../pluginUtils"; import { resolveUser } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualNoteCmd } from "../../functions/actualCommands/actualNoteCmd"; import { modActionsMsgCmd } from "../../types"; @@ -17,15 +17,15 @@ export const NoteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } if (!args.note && msg.attachments.size === 0) { - sendErrorMessage(pluginData, msg.channel, "Text or attachment required"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Text or attachment required"); return; } - actualNoteCmd(pluginData, msg.channel, msg.author, [...msg.attachments.values()], user, args.note || ""); + actualNoteCmd(pluginData, msg, msg.author, [...msg.attachments.values()], user, args.note || ""); }, }); diff --git a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts index 50fd2735..9647d861 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts @@ -1,6 +1,6 @@ import { slashOptions } from "knub"; -import { sendErrorMessage } from "../../../../pluginUtils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualNoteCmd } from "../../functions/actualCommands/actualNoteCmd"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -24,7 +24,9 @@ export const NoteSlashCmd = { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.note || options.note.trim() === "") && attachments.length < 1) { - sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts index 1d9bd37d..531efc4a 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts @@ -1,6 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { hasPermission } from "../../../../pluginUtils"; import { resolveUser } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualUnbanCmd } from "../../functions/actualCommands/actualUnbanCmd"; import { modActionsMsgCmd } from "../../types"; @@ -25,7 +26,7 @@ export const UnbanMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } @@ -33,13 +34,13 @@ export const UnbanMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg, channelId: msg.channel.id }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); return; } mod = args.mod; } - actualUnbanCmd(pluginData, msg.channel, msg.author.id, user, args.reason, [...msg.attachments.values()], mod); + actualUnbanCmd(pluginData, msg, msg.author.id, user, args.reason, [...msg.attachments.values()], mod); }, }); diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts index e85cfdfb..abc969de 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts @@ -1,6 +1,7 @@ import { slashOptions } from "knub"; -import { hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { hasPermission } from "../../../../pluginUtils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualUnbanCmd } from "../../functions/actualCommands/actualUnbanCmd"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -25,7 +26,9 @@ export const UnbanSlashCmd = { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -38,7 +41,9 @@ export const UnbanSlashCmd = { if (options.mod) { if (!canActAsOther) { - sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts index 94c029a2..8e71c8e3 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts @@ -14,6 +14,6 @@ export const UnhideCaseMsgCmd = modActionsMsgCmd({ ], async run({ pluginData, message: msg, args }) { - actualHideCaseCmd(pluginData, msg.channel, args.caseNum); + actualHideCaseCmd(pluginData, msg, args.caseNum); }, }); diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts index 8d7e111a..b917d83b 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts @@ -1,7 +1,8 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; import { isBanned } from "../../functions/isBanned"; @@ -35,7 +36,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } @@ -49,7 +50,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ !hasMuteRole && !memberToUnmute?.isCommunicationDisabled() ) { - sendErrorMessage(pluginData, msg.channel, "Cannot unmute: member is not muted"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot unmute: member is not muted"); return; } @@ -57,22 +58,20 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ const banned = await isBanned(pluginData, user.id); const prefix = pluginData.fullConfig.prefix; if (banned) { - sendErrorMessage( - pluginData, - msg.channel, - `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.`); return; } else { // Ask the mod if we should upgrade to a forceunmute as the user is not on the server const reply = await waitForButtonConfirm( - msg.channel, + msg, { content: "User not on server, forceunmute instead?" }, { confirmText: "Yes", cancelText: "No", restrictToId: msg.member.id }, ); if (!reply) { - sendErrorMessage(pluginData, msg.channel, "User not on server, unmute cancelled by moderator"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "User not on server, unmute cancelled by moderator"); return; } } @@ -80,7 +79,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to unmute this member if (memberToUnmute && !canActOn(pluginData, msg.member, memberToUnmute)) { - sendErrorMessage(pluginData, msg.channel, "Cannot unmute: insufficient permissions"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot unmute: insufficient permissions"); return; } @@ -90,7 +89,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - sendErrorMessage(pluginData, msg.channel, "You don't have permission to use -mod"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -100,7 +99,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ actualUnmuteCmd( pluginData, - msg.channel, + msg, user, [...msg.attachments.values()], mod, diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts index 04526be6..97163b2b 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts @@ -1,8 +1,9 @@ import { slashOptions } from "knub"; -import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { canActOn, hasPermission } from "../../../../pluginUtils"; import { convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; import { isBanned } from "../../functions/isBanned"; @@ -30,7 +31,9 @@ export const UnmuteSlashCmd = { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -45,7 +48,7 @@ export const UnmuteSlashCmd = { !hasMuteRole && !memberToUnmute?.isCommunicationDisabled() ) { - sendErrorMessage(pluginData, interaction, "Cannot unmute: member is not muted"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot unmute: member is not muted"); return; } @@ -53,11 +56,9 @@ export const UnmuteSlashCmd = { const banned = await isBanned(pluginData, options.user.id); const prefix = pluginData.fullConfig.prefix; if (banned) { - sendErrorMessage( - pluginData, - interaction, - `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.`); return; } else { // Ask the mod if we should upgrade to a forceunmute as the user is not on the server @@ -68,7 +69,9 @@ export const UnmuteSlashCmd = { ); if (!reply) { - sendErrorMessage(pluginData, interaction, "User not on server, unmute cancelled by moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "User not on server, unmute cancelled by moderator"); return; } } @@ -76,7 +79,7 @@ export const UnmuteSlashCmd = { // Make sure we're allowed to unmute this member if (memberToUnmute && !canActOn(pluginData, interaction.member, memberToUnmute)) { - sendErrorMessage(pluginData, interaction, "Cannot unmute: insufficient permissions"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot unmute: insufficient permissions"); return; } @@ -89,7 +92,9 @@ export const UnmuteSlashCmd = { if (options.mod) { if (!canActAsOther) { - sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } @@ -99,7 +104,7 @@ export const UnmuteSlashCmd = { const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; if (options.time && !convertedTime) { - sendErrorMessage(pluginData, interaction, `Could not convert ${options.time} to a delay`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } diff --git a/backend/src/plugins/ModActions/commands/update/UpdateMsgCmd.ts b/backend/src/plugins/ModActions/commands/update/UpdateMsgCmd.ts index 73c74f36..c0c186a9 100644 --- a/backend/src/plugins/ModActions/commands/update/UpdateMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/update/UpdateMsgCmd.ts @@ -19,6 +19,6 @@ export const UpdateMsgCmd = modActionsMsgCmd({ ], async run({ pluginData, message: msg, args }) { - await updateCase(pluginData, msg.channel, msg.author, args.caseNumber, args.note, [...msg.attachments.values()]); + await updateCase(pluginData, msg, msg.author, args.caseNumber, args.note, [...msg.attachments.values()]); }, }); diff --git a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts index 4baeb3c1..cd8533b6 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts @@ -1,6 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { canActOn, hasPermission } from "../../../../pluginUtils"; import { errorMessage, resolveMember, resolveUser } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualWarnCmd } from "../../functions/actualCommands/actualWarnCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; @@ -23,7 +24,7 @@ export const WarnMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - sendErrorMessage(pluginData, msg.channel, `User not found`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } @@ -32,9 +33,9 @@ export const WarnMsgCmd = modActionsMsgCmd({ if (!memberToWarn) { const _isBanned = await isBanned(pluginData, user.id); if (_isBanned) { - sendErrorMessage(pluginData, msg.channel, `User is banned`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User is banned`); } else { - sendErrorMessage(pluginData, msg.channel, `User not found on the server`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found on the server`); } return; @@ -42,7 +43,7 @@ export const WarnMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to warn this member if (!canActOn(pluginData, msg.member, memberToWarn)) { - sendErrorMessage(pluginData, msg.channel, "Cannot warn: insufficient permissions"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot warn: insufficient permissions"); return; } @@ -61,13 +62,13 @@ export const WarnMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - sendErrorMessage(pluginData, msg.channel, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); return; } actualWarnCmd( pluginData, - msg.channel, + msg, msg.author.id, mod, memberToWarn, diff --git a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts index 025f1981..c34e91e0 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts @@ -1,8 +1,9 @@ import { ChannelType } from "discord.js"; import { slashOptions } from "knub"; -import { canActOn, hasPermission, sendErrorMessage } from "../../../../pluginUtils"; +import { canActOn, hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualWarnCmd } from "../../functions/actualCommands/actualWarnCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; @@ -44,7 +45,9 @@ export const WarnSlashCmd = { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - sendErrorMessage(pluginData, interaction, "Text or attachment required", undefined, undefined, true); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -54,9 +57,9 @@ export const WarnSlashCmd = { if (!memberToWarn) { const _isBanned = await isBanned(pluginData, options.user.id); if (_isBanned) { - sendErrorMessage(pluginData, interaction, `User is banned`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `User is banned`); } else { - sendErrorMessage(pluginData, interaction, `User not found on the server`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `User not found on the server`); } return; @@ -64,7 +67,7 @@ export const WarnSlashCmd = { // Make sure we're allowed to warn this member if (!canActOn(pluginData, interaction.member, memberToWarn)) { - sendErrorMessage(pluginData, interaction, "Cannot warn: insufficient permissions"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot warn: insufficient permissions"); return; } @@ -76,7 +79,9 @@ export const WarnSlashCmd = { if (options.mod) { if (!canActAsOther) { - sendErrorMessage(pluginData, interaction, "You don't have permission to act as another moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } @@ -87,7 +92,7 @@ export const WarnSlashCmd = { try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - sendErrorMessage(pluginData, interaction, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts index 572d450c..25ce2fbb 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts @@ -1,17 +1,19 @@ -import { Attachment, ChatInputCommandInteraction, GuildMember, TextBasedChannel, User } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, GuildMember, Message, User } from "discord.js"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../../data/CaseTypes"; import { Case } from "../../../../data/entities/Case"; -import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { canActOn } from "../../../../pluginUtils"; import { UnknownUser, renderUserUsername, resolveMember } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../../types"; -import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; export async function actualAddCaseCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, author: GuildMember, mod: GuildMember, attachments: Array, @@ -19,14 +21,20 @@ export async function actualAddCaseCmd( type: keyof CaseTypes, reason: string, ) { - // If the user exists as a guild member, make sure we can act on them first - const member = await resolveMember(pluginData.client, pluginData.guild, user.id); - if (member && !canActOn(pluginData, author, member)) { - sendErrorMessage(pluginData, context, "Cannot add case on this user: insufficient permissions"); + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { return; } - const formattedReason = formatReasonWithAttachments(reason, attachments); + // If the user exists as a guild member, make sure we can act on them first + const member = await resolveMember(pluginData.client, pluginData.guild, user.id); + if (member && !canActOn(pluginData, author, member)) { + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(context, "Cannot add case on this user: insufficient permissions"); + return; + } + + const formattedReason = await formatReasonWithMessageLinkForAttachments(pluginData, reason, context, attachments); // Create the case const casesPlugin = pluginData.getPlugin(CasesPlugin); @@ -39,9 +47,11 @@ export async function actualAddCaseCmd( }); if (user) { - sendSuccessMessage(pluginData, context, `Case #${theCase.case_number} created for **${renderUserUsername(user)}**`); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(context, `Case #${theCase.case_number} created for **${renderUserUsername(user)}**`); } else { - sendSuccessMessage(pluginData, context, `Case #${theCase.case_number} created`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, `Case #${theCase.case_number} created`); } // Log the action diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts index 5b665884..fa9b7c94 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts @@ -1,23 +1,25 @@ -import { Attachment, ChatInputCommandInteraction, GuildMember, TextBasedChannel, User } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, GuildMember, Message, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { getMemberLevel } from "knub/helpers"; import { CaseTypes } from "../../../../data/CaseTypes"; import { clearExpiringTempban, registerExpiringTempban } from "../../../../data/loops/expiringTempbansLoop"; -import { canActOn, isContextInteraction, sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { canActOn, getContextChannel } from "../../../../pluginUtils"; import { UnknownUser, UserNotificationMethod, renderUserUsername, resolveMember } from "../../../../utils"; import { banLock } from "../../../../utils/lockNameHelpers"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../../types"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; import { banUserId } from "../banUserId"; -import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; import { isBanned } from "../isBanned"; export async function actualBanCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, user: User | UnknownUser, time: number | null, reason: string, @@ -27,8 +29,13 @@ export async function actualBanCmd( contactMethods?: UserNotificationMethod[], deleteDays?: number, ) { + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { + return; + } + const memberToBan = await resolveMember(pluginData.client, pluginData.guild, user.id); - const formattedReason = formatReasonWithAttachments(reason, attachments); + const formattedReason = await formatReasonWithMessageLinkForAttachments(pluginData, reason, context, attachments); + const formattedReasonWithAttachments = formatReasonWithAttachments(reason, attachments); // acquire a lock because of the needed user-inputs below (if banned/not on server) const lock = await pluginData.locks.acquire(banLock(user)); @@ -47,7 +54,7 @@ export async function actualBanCmd( ); if (!reply) { - sendErrorMessage(pluginData, context, "User not on server, ban cancelled by moderator"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "User not on server, ban cancelled by moderator"); lock.unlock(); return; } else { @@ -57,7 +64,7 @@ export async function actualBanCmd( // Abort if trying to ban user indefinitely if they are already banned indefinitely if (!existingTempban && !time) { - sendErrorMessage(pluginData, context, `User is already banned indefinitely.`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `User is already banned indefinitely.`); return; } @@ -69,7 +76,9 @@ export async function actualBanCmd( ); if (!reply) { - sendErrorMessage(pluginData, context, "User already banned, update cancelled by moderator"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(context, "User already banned, update cancelled by moderator"); lock.unlock(); return; } @@ -114,11 +123,12 @@ export async function actualBanCmd( }); } - sendSuccessMessage( - pluginData, - context, - `Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + context, + `Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`, + ); lock.unlock(); return; } @@ -127,24 +137,26 @@ export async function actualBanCmd( if (!forceban && !canActOn(pluginData, author, memberToBan!)) { const ourLevel = getMemberLevel(pluginData, author); const targetLevel = getMemberLevel(pluginData, memberToBan!); - sendErrorMessage( - pluginData, - context, - `Cannot ban: target permission level is equal or higher to yours, ${targetLevel} >= ${ourLevel}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage( + context, + `Cannot ban: target permission level is equal or higher to yours, ${targetLevel} >= ${ourLevel}`, + ); lock.unlock(); return; } const matchingConfig = await pluginData.config.getMatchingConfig({ member: author, - channel: isContextInteraction(context) ? context.channel : context, + channel: await getContextChannel(context), }); const deleteMessageDays = deleteDays ?? matchingConfig.ban_delete_message_days; const banResult = await banUserId( pluginData, user.id, formattedReason, + formattedReasonWithAttachments, { contactMethods, caseArgs: { @@ -158,7 +170,7 @@ export async function actualBanCmd( ); if (banResult.status === "failed") { - sendErrorMessage(pluginData, context, `Failed to ban member: ${banResult.error}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Failed to ban member: ${banResult.error}`); lock.unlock(); return; } @@ -178,5 +190,5 @@ export async function actualBanCmd( } lock.unlock(); - sendSuccessMessage(pluginData, context, response); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, response); } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts index 38ddf2bf..eabd8333 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts @@ -1,19 +1,20 @@ -import { ChatInputCommandInteraction, TextBasedChannel } from "discord.js"; +import { ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { sendContextResponse, sendErrorMessage } from "../../../../pluginUtils"; +import { sendContextResponse } from "../../../../pluginUtils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; export async function actualCaseCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, authorId: string, caseNumber: number, ) { const theCase = await pluginData.state.cases.findByCaseNumber(caseNumber); if (!theCase) { - sendErrorMessage(pluginData, context, "Case not found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Case not found"); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts index 22a16e93..a3707003 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts @@ -1,10 +1,10 @@ -import { APIEmbed, ChatInputCommandInteraction, TextBasedChannel, User } from "discord.js"; +import { APIEmbed, ChatInputCommandInteraction, Message, User } from "discord.js"; import { GuildPluginData } from "knub"; import { In } from "typeorm"; import { FindOptionsWhere } from "typeorm/find-options/FindOptionsWhere"; import { CaseTypes } from "../../../../data/CaseTypes"; import { Case } from "../../../../data/entities/Case"; -import { sendContextResponse, sendErrorMessage } from "../../../../pluginUtils"; +import { sendContextResponse } from "../../../../pluginUtils"; import { UnknownUser, chunkArray, @@ -18,6 +18,7 @@ import { createPaginatedMessage } from "../../../../utils/createPaginatedMessage import { getChunkedEmbedFields } from "../../../../utils/getChunkedEmbedFields"; import { getGuildPrefix } from "../../../../utils/getGuildPrefix"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; const casesPerPage = 5; @@ -25,7 +26,7 @@ const maxExpandedCases = 8; async function sendExpandedCases( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, casesCount: number, cases: Case[], ) { @@ -45,7 +46,7 @@ async function sendExpandedCases( async function casesUserCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, author: User, modId: string | null, user: User | UnknownUser, @@ -137,7 +138,7 @@ async function casesUserCmd( async function casesModCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, author: User, modId: string | null, mod: User | UnknownUser, @@ -152,7 +153,7 @@ async function casesModCmd( const totalCases = await casesPlugin.getTotalCasesByMod(modId ?? author.id, caseFilters); if (totalCases === 0) { - sendErrorMessage(pluginData, context, `No cases by **${modName}**`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `No cases by **${modName}**`); return; } @@ -211,7 +212,7 @@ async function casesModCmd( export async function actualCasesCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, modId: string | null, user: User | UnknownUser | null, author: User, diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts index 3fac80cf..66240913 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts @@ -1,21 +1,17 @@ -import { ChatInputCommandInteraction, GuildMember, TextBasedChannel } from "discord.js"; +import { ChatInputCommandInteraction, GuildMember, Message } from "discord.js"; import { GuildPluginData, helpers } from "knub"; import { Case } from "../../../../data/entities/Case"; -import { - isContextInteraction, - sendContextResponse, - sendErrorMessage, - sendSuccessMessage, -} from "../../../../pluginUtils"; +import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; import { SECONDS } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../../../TimeAndDate/TimeAndDatePlugin"; import { ModActionsPluginType } from "../../types"; export async function actualDeleteCaseCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, author: GuildMember, caseNumbers: number[], force: boolean, @@ -35,7 +31,7 @@ export async function actualDeleteCaseCmd( } if (failed.length === caseNumbers.length) { - sendErrorMessage(pluginData, context, "None of the cases were found!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "None of the cases were found!"); return; } @@ -50,7 +46,7 @@ export async function actualDeleteCaseCmd( const reply = await helpers.waitForReply( pluginData.client, - isContextInteraction(context) ? context.channel! : context, + await getContextChannel(context), author.id, 15 * SECONDS, ); @@ -87,9 +83,13 @@ export async function actualDeleteCaseCmd( : ""; const amt = validCases.length - cancelled; if (amt === 0) { - sendErrorMessage(pluginData, context, "All deletions were cancelled, no cases were deleted."); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(context, "All deletions were cancelled, no cases were deleted."); return; } - sendSuccessMessage(pluginData, context, `${amt} case${amt === 1 ? " was" : "s were"} deleted!${failedAddendum}`); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(context, `${amt} case${amt === 1 ? " was" : "s were"} deleted!${failedAddendum}`); } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts index 095e06a7..c093306f 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts @@ -1,25 +1,31 @@ -import { Attachment, ChatInputCommandInteraction, GuildMember, Snowflake, TextBasedChannel, User } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, GuildMember, Message, Snowflake, User } from "discord.js"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../../data/CaseTypes"; import { LogType } from "../../../../data/LogType"; -import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; import { DAYS, MINUTES, UnknownUser } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; import { ignoreEvent } from "../ignoreEvent"; export async function actualForceBanCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, authorId: string, user: User | UnknownUser, reason: string, attachments: Array, mod: GuildMember, ) { - const formattedReason = formatReasonWithAttachments(reason, attachments); + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { + return; + } + + const formattedReason = await formatReasonWithMessageLinkForAttachments(pluginData, reason, context, attachments); + const formattedReasonWithAttachments = formatReasonWithAttachments(reason, attachments); ignoreEvent(pluginData, IgnoredEventType.Ban, user.id); pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_BAN, user.id); @@ -28,10 +34,10 @@ export async function actualForceBanCmd( // FIXME: Use banUserId()? await pluginData.guild.bans.create(user.id as Snowflake, { deleteMessageSeconds: (1 * DAYS) / MINUTES, - reason: formattedReason ?? undefined, + reason: formattedReasonWithAttachments ?? undefined, }); } catch { - sendErrorMessage(pluginData, context, "Failed to forceban member"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Failed to forceban member"); return; } @@ -46,7 +52,9 @@ export async function actualForceBanCmd( }); // Confirm the action - sendSuccessMessage(pluginData, context, `Member forcebanned (Case #${createdCase.case_number})`); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(context, `Member forcebanned (Case #${createdCase.case_number})`); // Log the action pluginData.getPlugin(LogsPlugin).logMemberForceban({ diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts index d500ce5f..28527b4d 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts @@ -1,11 +1,11 @@ -import { ChatInputCommandInteraction, TextBasedChannel } from "discord.js"; +import { ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; export async function actualHideCaseCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, caseNumbers: number[], ) { const failed: number[] = []; @@ -21,7 +21,7 @@ export async function actualHideCaseCmd( } if (failed.length === caseNumbers.length) { - sendErrorMessage(pluginData, context, "None of the cases were found!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "None of the cases were found!"); return; } const failedAddendum = @@ -30,9 +30,10 @@ export async function actualHideCaseCmd( : ""; const amt = caseNumbers.length - failed.length; - sendSuccessMessage( - pluginData, - context, - `${amt} case${amt === 1 ? " is" : "s are"} now hidden! Use \`unhidecase\` to unhide them.${failedAddendum}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + context, + `${amt} case${amt === 1 ? " is" : "s are"} now hidden! Use \`unhidecase\` to unhide them.${failedAddendum}`, + ); } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts index e66383fe..9a85965b 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts @@ -1,7 +1,7 @@ -import { Attachment, ChatInputCommandInteraction, GuildMember, TextBasedChannel, User } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, GuildMember, Message, User } from "discord.js"; import { GuildPluginData } from "knub"; import { LogType } from "../../../../data/LogType"; -import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { canActOn } from "../../../../pluginUtils"; import { DAYS, SECONDS, @@ -10,15 +10,17 @@ import { renderUserUsername, resolveMember, } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; import { ignoreEvent } from "../ignoreEvent"; import { isBanned } from "../isBanned"; import { kickMember } from "../kickMember"; export async function actualKickCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, author: GuildMember, user: User | UnknownUser, reason: string, @@ -27,14 +29,18 @@ export async function actualKickCmd( contactMethods?: UserNotificationMethod[], clean?: boolean, ) { + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { + return; + } + const memberToKick = await resolveMember(pluginData.client, pluginData.guild, user.id); if (!memberToKick) { const banned = await isBanned(pluginData, user.id); if (banned) { - sendErrorMessage(pluginData, context, `User is banned`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `User is banned`); } else { - sendErrorMessage(pluginData, context, `User not found on the server`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `User not found on the server`); } return; @@ -42,13 +48,14 @@ export async function actualKickCmd( // Make sure we're allowed to kick this member if (!canActOn(pluginData, author, memberToKick)) { - sendErrorMessage(pluginData, context, "Cannot kick: insufficient permissions"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Cannot kick: insufficient permissions"); return; } - const formattedReason = formatReasonWithAttachments(reason, attachments); + const formattedReason = await formatReasonWithMessageLinkForAttachments(pluginData, reason, context, attachments); + const formattedReasonWithAttachments = formatReasonWithAttachments(reason, attachments); - const kickResult = await kickMember(pluginData, memberToKick, formattedReason, { + const kickResult = await kickMember(pluginData, memberToKick, formattedReason, formattedReasonWithAttachments, { contactMethods, caseArgs: { modId: mod.id, @@ -63,7 +70,7 @@ export async function actualKickCmd( try { await memberToKick.ban({ deleteMessageSeconds: (1 * DAYS) / SECONDS, reason: "kick -clean" }); } catch { - sendErrorMessage(pluginData, context, "Failed to ban the user to clean messages (-clean)"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Failed to ban the user to clean messages (-clean)"); } pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, memberToKick.id); @@ -72,12 +79,14 @@ export async function actualKickCmd( try { await pluginData.guild.bans.remove(memberToKick.id, "kick -clean"); } catch { - sendErrorMessage(pluginData, context, "Failed to unban the user after banning them (-clean)"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(context, "Failed to unban the user after banning them (-clean)"); } } if (kickResult.status === "failed") { - sendErrorMessage(pluginData, context, `Failed to kick user`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Failed to kick user`); return; } @@ -85,5 +94,5 @@ export async function actualKickCmd( let response = `Kicked **${renderUserUsername(memberToKick.user)}** (Case #${kickResult.case.case_number})`; if (kickResult.notifyResult.text) response += ` (${kickResult.notifyResult.text})`; - sendSuccessMessage(pluginData, context, response); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, response); } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts index c0abc3a8..2b35c51a 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts @@ -1,55 +1,58 @@ -import { ChatInputCommandInteraction, GuildMember, Snowflake, TextBasedChannel } from "discord.js"; +import { ChatInputCommandInteraction, GuildMember, Message, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { waitForReply } from "knub/helpers"; import { CaseTypes } from "../../../../data/CaseTypes"; import { LogType } from "../../../../data/LogType"; import { humanizeDurationShort } from "../../../../humanizeDurationShort"; -import { - canActOn, - isContextInteraction, - sendContextResponse, - sendErrorMessage, - sendSuccessMessage, -} from "../../../../pluginUtils"; +import { canActOn, getContextChannel, isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; import { DAYS, MINUTES, SECONDS, noop } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; import { ignoreEvent } from "../ignoreEvent"; export async function actualMassBanCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, userIds: string[], author: GuildMember, ) { // Limit to 100 users at once (arbitrary?) if (userIds.length > 100) { - sendErrorMessage(pluginData, context, `Can only massban max 100 users at once`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Can only massban max 100 users at once`); return; } // Ask for ban reason (cleaner this way instead of trying to cram it into the args) sendContextResponse(context, "Ban reason? `cancel` to cancel"); - const banReasonReply = await waitForReply( - pluginData.client, - isContextInteraction(context) ? context.channel! : context, - author.id, - ); + const banReasonReply = await waitForReply(pluginData.client, await getContextChannel(context), author.id); if (!banReasonReply || !banReasonReply.content || banReasonReply.content.toLowerCase().trim() === "cancel") { - sendErrorMessage(pluginData, context, "Cancelled"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Cancelled"); return; } - const banReason = formatReasonWithAttachments(banReasonReply.content, [...banReasonReply.attachments.values()]); + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, banReasonReply.content)) { + return; + } + + const banReason = await formatReasonWithMessageLinkForAttachments(pluginData, banReasonReply.content, context, [ + ...banReasonReply.attachments.values(), + ]); + const banReasonWithAttachments = formatReasonWithAttachments(banReasonReply.content, [ + ...banReasonReply.attachments.values(), + ]); // Verify we can act on each of the users specified for (const userId of userIds) { const member = pluginData.guild.members.cache.get(userId as Snowflake); // TODO: Get members on demand? if (member && !canActOn(pluginData, author, member)) { - sendErrorMessage(pluginData, context, "Cannot massban one or more users: insufficient permissions"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(context, "Cannot massban one or more users: insufficient permissions"); return; } } @@ -87,7 +90,7 @@ export async function actualMassBanCmd( const casesPlugin = pluginData.getPlugin(CasesPlugin); const messageConfig = isContextInteraction(context) ? await pluginData.config.getForInteraction(context) - : await pluginData.config.getForChannel(context); + : await pluginData.config.getForChannel(await getContextChannel(context)); const deleteDays = messageConfig.ban_delete_message_days; for (const [i, userId] of userIds.entries()) { @@ -103,7 +106,7 @@ export async function actualMassBanCmd( await pluginData.guild.bans.create(userId as Snowflake, { deleteMessageSeconds: (deleteDays * DAYS) / SECONDS, - reason: banReason, + reason: banReasonWithAttachments, }); await casesPlugin.createCase({ @@ -134,7 +137,7 @@ export async function actualMassBanCmd( const successfulBanCount = userIds.length - failedBans.length; if (successfulBanCount === 0) { // All bans failed - don't create a log entry and notify the user - sendErrorMessage(pluginData, context, "All bans failed. Make sure the IDs are valid."); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "All bans failed. Make sure the IDs are valid."); } else { // Some or all bans were successful. Create a log entry for the mass ban and notify the user. pluginData.getPlugin(LogsPlugin).logMassBan({ @@ -144,19 +147,18 @@ export async function actualMassBanCmd( }); if (failedBans.length) { - sendSuccessMessage( - pluginData, - context, - `Banned ${successfulBanCount} users in ${formattedTimeTaken}, ${failedBans.length} failed: ${failedBans.join( - " ", - )}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + context, + `Banned ${successfulBanCount} users in ${formattedTimeTaken}, ${ + failedBans.length + } failed: ${failedBans.join(" ")}`, + ); } else { - sendSuccessMessage( - pluginData, - context, - `Banned ${successfulBanCount} users successfully in ${formattedTimeTaken}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(context, `Banned ${successfulBanCount} users successfully in ${formattedTimeTaken}`); } } }); diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts index 8dd735ab..2d8086cb 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts @@ -1,49 +1,48 @@ -import { ChatInputCommandInteraction, GuildMember, Snowflake, TextBasedChannel } from "discord.js"; +import { ChatInputCommandInteraction, GuildMember, Message, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { waitForReply } from "knub/helpers"; import { LogType } from "../../../../data/LogType"; import { logger } from "../../../../logger"; -import { - canActOn, - isContextInteraction, - sendContextResponse, - sendErrorMessage, - sendSuccessMessage, -} from "../../../../pluginUtils"; +import { canActOn, getContextChannel, sendContextResponse } from "../../../../pluginUtils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { ModActionsPluginType } from "../../types"; -import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; export async function actualMassMuteCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, userIds: string[], author: GuildMember, ) { // Limit to 100 users at once (arbitrary?) if (userIds.length > 100) { - sendErrorMessage(pluginData, context, `Can only massmute max 100 users at once`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Can only massmute max 100 users at once`); return; } // Ask for mute reason sendContextResponse(context, "Mute reason? `cancel` to cancel"); - const muteReasonReceived = await waitForReply( - pluginData.client, - isContextInteraction(context) ? context.channel! : context, - author.id, - ); + const muteReasonReceived = await waitForReply(pluginData.client, await getContextChannel(context), author.id); if ( !muteReasonReceived || !muteReasonReceived.content || muteReasonReceived.content.toLowerCase().trim() === "cancel" ) { - sendErrorMessage(pluginData, context, "Cancelled"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Cancelled"); return; } - const muteReason = formatReasonWithAttachments(muteReasonReceived.content, [ + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, muteReasonReceived.content)) { + return; + } + + const muteReason = await formatReasonWithMessageLinkForAttachments(pluginData, muteReasonReceived.content, context, [ + ...muteReasonReceived.attachments.values(), + ]); + const muteReasonWithAttachments = formatReasonWithAttachments(muteReasonReceived.content, [ ...muteReasonReceived.attachments.values(), ]); @@ -51,7 +50,9 @@ export async function actualMassMuteCmd( for (const userId of userIds) { const member = pluginData.guild.members.cache.get(userId as Snowflake); if (member && !canActOn(pluginData, author, member)) { - sendErrorMessage(pluginData, context, "Cannot massmute one or more users: insufficient permissions"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(context, "Cannot massmute one or more users: insufficient permissions"); return; } } @@ -72,7 +73,7 @@ export async function actualMassMuteCmd( const mutesPlugin = pluginData.getPlugin(MutesPlugin); for (const userId of userIds) { try { - await mutesPlugin.muteUser(userId, 0, `Mass mute: ${muteReason}`, { + await mutesPlugin.muteUser(userId, 0, `Mass mute: ${muteReason}`, `Mass mute: ${muteReasonWithAttachments}`, { caseArgs: { modId, }, @@ -89,7 +90,7 @@ export async function actualMassMuteCmd( const successfulMuteCount = userIds.length - failedMutes.length; if (successfulMuteCount === 0) { // All mutes failed - sendErrorMessage(pluginData, context, "All mutes failed. Make sure the IDs are valid."); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "All mutes failed. Make sure the IDs are valid."); } else { // Success on all or some mutes pluginData.getPlugin(LogsPlugin).logMassMute({ @@ -98,13 +99,14 @@ export async function actualMassMuteCmd( }); if (failedMutes.length) { - sendSuccessMessage( - pluginData, - context, - `Muted ${successfulMuteCount} users, ${failedMutes.length} failed: ${failedMutes.join(" ")}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + context, + `Muted ${successfulMuteCount} users, ${failedMutes.length} failed: ${failedMutes.join(" ")}`, + ); } else { - sendSuccessMessage(pluginData, context, `Muted ${successfulMuteCount} users successfully`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, `Muted ${successfulMuteCount} users successfully`); } } } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts index cf829fd7..bfb57111 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts @@ -1,46 +1,45 @@ -import { ChatInputCommandInteraction, GuildMember, Snowflake, TextBasedChannel } from "discord.js"; +import { ChatInputCommandInteraction, GuildMember, Message, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { waitForReply } from "knub/helpers"; import { CaseTypes } from "../../../../data/CaseTypes"; import { LogType } from "../../../../data/LogType"; -import { - isContextInteraction, - sendContextResponse, - sendErrorMessage, - sendSuccessMessage, -} from "../../../../pluginUtils"; +import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; import { ignoreEvent } from "../ignoreEvent"; import { isBanned } from "../isBanned"; export async function actualMassUnbanCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, userIds: string[], author: GuildMember, ) { // Limit to 100 users at once (arbitrary?) if (userIds.length > 100) { - sendErrorMessage(pluginData, context, `Can only mass-unban max 100 users at once`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Can only mass-unban max 100 users at once`); return; } // Ask for unban reason (cleaner this way instead of trying to cram it into the args) sendContextResponse(context, "Unban reason? `cancel` to cancel"); - const unbanReasonReply = await waitForReply( - pluginData.client, - isContextInteraction(context) ? context.channel! : context, - author.id, - ); + const unbanReasonReply = await waitForReply(pluginData.client, await getContextChannel(context), author.id); if (!unbanReasonReply || !unbanReasonReply.content || unbanReasonReply.content.toLowerCase().trim() === "cancel") { - sendErrorMessage(pluginData, context, "Cancelled"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Cancelled"); return; } - const unbanReason = formatReasonWithAttachments(unbanReasonReply.content, [...unbanReasonReply.attachments.values()]); + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, unbanReasonReply.content)) { + return; + } + + const unbanReason = await formatReasonWithMessageLinkForAttachments(pluginData, unbanReasonReply.content, context, [ + ...unbanReasonReply.attachments.values(), + ]); // Ignore automatic unban cases and logs for these users // We'll create our own cases below and post a single "mass unbanned" log instead @@ -83,7 +82,9 @@ export async function actualMassUnbanCmd( const successfulUnbanCount = userIds.length - failedUnbans.length; if (successfulUnbanCount === 0) { // All unbans failed - don't create a log entry and notify the user - sendErrorMessage(pluginData, context, "All unbans failed. Make sure the IDs are valid and banned."); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(context, "All unbans failed. Make sure the IDs are valid and banned."); } else { // Some or all unbans were successful. Create a log entry for the mass unban and notify the user. pluginData.getPlugin(LogsPlugin).logMassUnban({ @@ -110,13 +111,16 @@ export async function actualMassUnbanCmd( }); } - sendSuccessMessage( - pluginData, - context, - `Unbanned ${successfulUnbanCount} users, ${failedUnbans.length} failed:\n${failedMsg}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + context, + `Unbanned ${successfulUnbanCount} users, ${failedUnbans.length} failed:\n${failedMsg}`, + ); } else { - sendSuccessMessage(pluginData, context, `Unbanned ${successfulUnbanCount} users successfully`); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(context, `Unbanned ${successfulUnbanCount} users successfully`); } } } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts index 487cf453..7a136a32 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts @@ -1,9 +1,8 @@ -import { Attachment, ChatInputCommandInteraction, GuildMember, TextBasedChannel, User } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, GuildMember, Message, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { ERRORS, RecoverablePluginError } from "../../../../RecoverablePluginError"; import { logger } from "../../../../logger"; -import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; import { UnknownUser, UserNotificationMethod, @@ -11,10 +10,12 @@ import { isDiscordAPIError, renderUserUsername, } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { MuteResult } from "../../../Mutes/types"; import { ModActionsPluginType } from "../../types"; -import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; /** * The actual function run by both !mute and !forcemute. @@ -22,23 +23,32 @@ import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; */ export async function actualMuteCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, user: User | UnknownUser, - attachments: Array, + attachments: Attachment[], mod: GuildMember, ppId?: string, time?: number, reason?: string, contactMethods?: UserNotificationMethod[], ) { + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { + return; + } + const timeUntilUnmute = time && humanizeDuration(time); - const formattedReason = reason ? formatReasonWithAttachments(reason, attachments) : undefined; + const formattedReason = + reason || attachments.length > 0 + ? await formatReasonWithMessageLinkForAttachments(pluginData, reason ?? "", context, attachments) + : undefined; + const formattedReasonWithAttachments = + reason || attachments.length > 0 ? formatReasonWithAttachments(reason ?? "", attachments) : undefined; let muteResult: MuteResult; const mutesPlugin = pluginData.getPlugin(MutesPlugin); try { - muteResult = await mutesPlugin.muteUser(user.id, time, formattedReason, { + muteResult = await mutesPlugin.muteUser(user.id, time, formattedReason, formattedReasonWithAttachments, { contactMethods, caseArgs: { modId: mod.id, @@ -47,9 +57,11 @@ export async function actualMuteCmd( }); } catch (e) { if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { - sendErrorMessage(pluginData, context, "Could not mute the user: no mute role set in config"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(context, "Could not mute the user: no mute role set in config"); } else if (isDiscordAPIError(e) && e.code === 10007) { - sendErrorMessage(pluginData, context, "Could not mute the user: unknown member"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Could not mute the user: unknown member"); } else { logger.error(`Failed to mute user ${user.id}: ${e.stack}`); if (user.id == null) { @@ -57,7 +69,7 @@ export async function actualMuteCmd( // tslint:disable-next-line:no-console console.trace("[DEBUG] Null user.id for mute"); } - sendErrorMessage(pluginData, context, "Could not mute the user"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Could not mute the user"); } return; @@ -92,5 +104,5 @@ export async function actualMuteCmd( } if (muteResult.notifyResult.text) response += ` (${muteResult.notifyResult.text})`; - sendSuccessMessage(pluginData, context, response); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, response); } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts index 2a29e2df..7b2e4831 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts @@ -1,23 +1,28 @@ -import { Attachment, ChatInputCommandInteraction, TextBasedChannel, User } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, Message, User } from "discord.js"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../../data/CaseTypes"; -import { sendSuccessMessage } from "../../../../pluginUtils"; import { UnknownUser, renderUserUsername } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../../types"; -import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; export async function actualNoteCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, author: User, attachments: Array, user: User | UnknownUser, note: string, ) { + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, note)) { + return; + } + const userName = renderUserUsername(user); - const reason = formatReasonWithAttachments(note, attachments); + const reason = await formatReasonWithMessageLinkForAttachments(pluginData, note, context, attachments); const casesPlugin = pluginData.getPlugin(CasesPlugin); const createdCase = await casesPlugin.createCase({ @@ -34,14 +39,15 @@ export async function actualNoteCmd( reason, }); - sendSuccessMessage( - pluginData, - context, - `Note added on **${userName}** (Case #${createdCase.case_number})`, - undefined, - undefined, - true, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + context, + `Note added on **${userName}** (Case #${createdCase.case_number})`, + undefined, + undefined, + true, + ); pluginData.state.events.emit("note", user.id, reason); } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts index 94df7d4f..85f9abba 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts @@ -1,33 +1,40 @@ -import { Attachment, ChatInputCommandInteraction, GuildMember, Snowflake, TextBasedChannel, User } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, GuildMember, Message, Snowflake, User } from "discord.js"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../../data/CaseTypes"; import { LogType } from "../../../../data/LogType"; import { clearExpiringTempban } from "../../../../data/loops/expiringTempbansLoop"; -import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; import { UnknownUser } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; import { ignoreEvent } from "../ignoreEvent"; export async function actualUnbanCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, authorId: string, user: User | UnknownUser, reason: string, attachments: Array, mod: GuildMember, ) { + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { + return; + } + pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, user.id); - const formattedReason = formatReasonWithAttachments(reason, attachments); + const formattedReason = await formatReasonWithMessageLinkForAttachments(pluginData, reason, context, attachments); try { ignoreEvent(pluginData, IgnoredEventType.Unban, user.id); await pluginData.guild.bans.remove(user.id as Snowflake, formattedReason ?? undefined); } catch { - sendErrorMessage(pluginData, context, "Failed to unban member; are you sure they're banned?"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(context, "Failed to unban member; are you sure they're banned?"); return; } @@ -49,7 +56,7 @@ export async function actualUnbanCmd( } // Confirm the action - sendSuccessMessage(pluginData, context, `Member unbanned (Case #${createdCase.case_number})`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, `Member unbanned (Case #${createdCase.case_number})`); // Log the action pluginData.getPlugin(LogsPlugin).logMemberUnban({ diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts index 3ec2cd9e..313261ee 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts @@ -1,11 +1,11 @@ -import { ChatInputCommandInteraction, TextBasedChannel } from "discord.js"; +import { ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; export async function actualUnhideCaseCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, caseNumbers: number[], ) { const failed: number[] = []; @@ -21,7 +21,7 @@ export async function actualUnhideCaseCmd( } if (failed.length === caseNumbers.length) { - sendErrorMessage(pluginData, context, "None of the cases were found!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "None of the cases were found!"); return; } @@ -31,9 +31,7 @@ export async function actualUnhideCaseCmd( : ""; const amt = caseNumbers.length - failed.length; - sendSuccessMessage( - pluginData, - context, - `${amt} case${amt === 1 ? " is" : "s are"} no longer hidden!${failedAddendum}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(context, `${amt} case${amt === 1 ? " is" : "s are"} no longer hidden!${failedAddendum}`); } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts index 96804c38..0f945a0f 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts @@ -1,15 +1,16 @@ -import { Attachment, ChatInputCommandInteraction, GuildMember, TextBasedChannel, User } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, GuildMember, Message, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; import { UnknownUser, asSingleLine, renderUserUsername } from "../../../../utils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { ModActionsPluginType } from "../../types"; -import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; export async function actualUnmuteCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, user: User | UnknownUser, attachments: Array, mod: GuildMember, @@ -17,25 +18,31 @@ export async function actualUnmuteCmd( time?: number, reason?: string, ) { - const parsedReason = reason ? formatReasonWithAttachments(reason, attachments) : undefined; + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { + return; + } + + const formattedReason = + reason || attachments.length > 0 + ? await formatReasonWithMessageLinkForAttachments(pluginData, reason ?? "", context, attachments) + : undefined; const mutesPlugin = pluginData.getPlugin(MutesPlugin); const result = await mutesPlugin.unmuteUser(user.id, time, { modId: mod.id, ppId: ppId ?? undefined, - reason: parsedReason, + reason: formattedReason, }); if (!result) { - sendErrorMessage(pluginData, context, "User is not muted!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "User is not muted!"); return; } // Confirm the action to the moderator if (time) { const timeUntilUnmute = time && humanizeDuration(time); - sendSuccessMessage( - pluginData, + pluginData.getPlugin(CommonPlugin).sendSuccessMessage( context, asSingleLine(` Unmuting **${renderUserUsername(user)}** @@ -43,8 +50,7 @@ export async function actualUnmuteCmd( `), ); } else { - sendSuccessMessage( - pluginData, + pluginData.getPlugin(CommonPlugin).sendSuccessMessage( context, asSingleLine(` Unmuted **${renderUserUsername(user)}** diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts index 5748f72e..0349b6da 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts @@ -1,17 +1,18 @@ -import { Attachment, ChatInputCommandInteraction, GuildMember, TextBasedChannel } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, GuildMember, Message } from "discord.js"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../../data/CaseTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../../pluginUtils"; import { UserNotificationMethod, renderUserUsername } from "../../../../utils"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; -import { formatReasonWithAttachments } from "../formatReasonWithAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; import { warnMember } from "../warnMember"; export async function actualWarnCmd( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, authorId: string, mod: GuildMember, memberToWarn: GuildMember, @@ -19,8 +20,13 @@ export async function actualWarnCmd( attachments: Attachment[], contactMethods?: UserNotificationMethod[], ) { + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { + return; + } + const config = pluginData.config.get(); - const formattedReason = formatReasonWithAttachments(reason, attachments); + const formattedReason = await formatReasonWithMessageLinkForAttachments(pluginData, reason, context, attachments); + const formattedReasonWithAttachments = formatReasonWithAttachments(reason, attachments); const casesPlugin = pluginData.getPlugin(CasesPlugin); const priorWarnAmount = await casesPlugin.getCaseTypeAmountForUserId(memberToWarn.id, CaseTypes.Warn); @@ -31,12 +37,12 @@ export async function actualWarnCmd( { confirmText: "Yes", cancelText: "No", restrictToId: authorId }, ); if (!reply) { - sendErrorMessage(pluginData, context, "Warn cancelled by moderator"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Warn cancelled by moderator"); return; } } - const warnResult = await warnMember(pluginData, memberToWarn, formattedReason, { + const warnResult = await warnMember(pluginData, memberToWarn, formattedReason, formattedReasonWithAttachments, { contactMethods, caseArgs: { modId: mod.id, @@ -47,15 +53,16 @@ export async function actualWarnCmd( }); if (warnResult.status === "failed") { - sendErrorMessage(pluginData, context, "Failed to warn user"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Failed to warn user"); return; } const messageResultText = warnResult.notifyResult.text ? ` (${warnResult.notifyResult.text})` : ""; - sendSuccessMessage( - pluginData, - context, - `Warned **${renderUserUsername(memberToWarn.user)}** (Case #${warnResult.case.case_number})${messageResultText}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + context, + `Warned **${renderUserUsername(memberToWarn.user)}** (Case #${warnResult.case.case_number})${messageResultText}`, + ); } diff --git a/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts b/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts new file mode 100644 index 00000000..868786ed --- /dev/null +++ b/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts @@ -0,0 +1,51 @@ +import { ChatInputCommandInteraction, Message, TextBasedChannel } from "discord.js"; +import { AnyPluginData, GuildPluginData } from "knub"; +import { CommonPlugin } from "../../Common/CommonPlugin"; +import { ModActionsPluginType } from "../types"; + +export function shouldReactToAttachmentLink(pluginData: GuildPluginData) { + const config = pluginData.config.get(); + + return !config.attachment_link_reaction || config.attachment_link_reaction !== "none"; +} + +export function attachmentLinkShouldRestrict(pluginData: GuildPluginData) { + return pluginData.config.get().attachment_link_reaction === "restrict"; +} + +export function detectAttachmentLink(reason: string | null | undefined) { + return reason && /https:\/\/(cdn|media)\.discordapp\.(com|net)\/(ephemeral-)?attachments/gu.test(reason); +} + +export function sendAttachmentLinkDetectionErrorMessage( + pluginData: AnyPluginData, + context: TextBasedChannel | Message | ChatInputCommandInteraction, + restricted = false, +) { + const emoji = pluginData.getPlugin(CommonPlugin).getErrorEmoji(); + + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage( + context, + "You manually added a Discord attachment link to the reason. This link will only work for a limited time.\n" + + "You should instead **re-upload** the attachment with the command, in the same message.\n\n" + + (restricted ? `${emoji} **Command canceled.** ${emoji}` : "").trim(), + ); +} + +export async function handleAttachmentLinkDetectionAndGetRestriction( + pluginData: GuildPluginData, + context: TextBasedChannel | Message | ChatInputCommandInteraction, + reason: string | null | undefined, +) { + if (!shouldReactToAttachmentLink(pluginData) || !detectAttachmentLink(reason)) { + return false; + } + + const restricted = attachmentLinkShouldRestrict(pluginData); + + sendAttachmentLinkDetectionErrorMessage(pluginData, context, restricted); + + return restricted; +} diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts index d9d1454b..55cc0049 100644 --- a/backend/src/plugins/ModActions/functions/banUserId.ts +++ b/backend/src/plugins/ModActions/functions/banUserId.ts @@ -30,6 +30,7 @@ export async function banUserId( pluginData: GuildPluginData, userId: string, reason?: string, + reasonWithAttachments?: string, banOptions: BanOptions = {}, banTime?: number, ): Promise { @@ -45,7 +46,7 @@ export async function banUserId( // Attempt to message the user *before* banning them, as doing it after may not be possible const member = await resolveMember(pluginData.client, pluginData.guild, userId); let notifyResult: UserNotificationResult = { method: null, success: true }; - if (reason && member) { + if (reasonWithAttachments && member) { const contactMethods = banOptions?.contactMethods ? banOptions.contactMethods : getDefaultContactMethods(pluginData, "ban"); @@ -56,7 +57,7 @@ export async function banUserId( config.ban_message, new TemplateSafeValueContainer({ guildName: pluginData.guild.name, - reason, + reason: reasonWithAttachments, moderator: banOptions.caseArgs?.modId ? userToTemplateSafeUser(await resolveUser(pluginData.client, banOptions.caseArgs.modId)) : null, @@ -69,7 +70,7 @@ export async function banUserId( config.tempban_message, new TemplateSafeValueContainer({ guildName: pluginData.guild.name, - reason, + reason: reasonWithAttachments, moderator: banOptions.caseArgs?.modId ? userToTemplateSafeUser(await resolveUser(pluginData.client, banOptions.caseArgs.modId)) : null, diff --git a/backend/src/plugins/ModActions/functions/clearTempban.ts b/backend/src/plugins/ModActions/functions/clearTempban.ts index 25807df8..1b196db0 100644 --- a/backend/src/plugins/ModActions/functions/clearTempban.ts +++ b/backend/src/plugins/ModActions/functions/clearTempban.ts @@ -10,7 +10,6 @@ import { resolveUser } from "../../../utils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../types"; -import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; import { ignoreEvent } from "./ignoreEvent"; import { isBanned } from "./isBanned"; @@ -21,11 +20,9 @@ export async function clearTempban(pluginData: GuildPluginData, + reason: string, + context: Message | ChatInputCommandInteraction, + attachments: Attachment[], +) { + if (isContextMessage(context)) { + return context.attachments.size > 0 ? ((reason || "") + " " + context.url).trim() : reason; + } + + if (attachments.length < 1) { + return reason; + } + + const attachmentChannelId = pluginData.config.get().attachment_storing_channel; + const channel = attachmentChannelId + ? (pluginData.guild.channels.cache.get(attachmentChannelId) as TextBasedChannel) ?? context.channel + : context.channel; + + const message = await channel!.send({ + content: `Storing ${attachments.length} attachment${attachments.length === 1 ? "" : "s"}`, + files: attachments.map((a) => a.url), + }); + + return ((reason || "") + " " + message.url).trim(); +} + +export function formatReasonWithAttachments(reason: string, attachments: Attachment[]) { + const attachmentUrls = attachments.map((a) => a.url); + return ((reason || "") + " " + attachmentUrls.join(" ")).trim(); +} diff --git a/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts b/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts deleted file mode 100644 index 3fd92ee8..00000000 --- a/backend/src/plugins/ModActions/functions/formatReasonWithAttachments.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Attachment } from "discord.js"; - -export function formatReasonWithAttachments(reason: string, attachments: Attachment[]) { - const attachmentUrls = attachments.map((a) => a.url); - return ((reason || "") + " " + attachmentUrls.join(" ")).trim(); -} diff --git a/backend/src/plugins/ModActions/functions/kickMember.ts b/backend/src/plugins/ModActions/functions/kickMember.ts index d54dfd15..22c6eb63 100644 --- a/backend/src/plugins/ModActions/functions/kickMember.ts +++ b/backend/src/plugins/ModActions/functions/kickMember.ts @@ -18,13 +18,14 @@ export async function kickMember( pluginData: GuildPluginData, member: GuildMember, reason?: string, + reasonWithAttachments?: string, kickOptions: KickOptions = {}, ): Promise { const config = pluginData.config.get(); // Attempt to message the user *before* kicking them, as doing it after may not be possible let notifyResult: UserNotificationResult = { method: null, success: true }; - if (reason && member) { + if (reasonWithAttachments && member) { const contactMethods = kickOptions?.contactMethods ? kickOptions.contactMethods : getDefaultContactMethods(pluginData, "kick"); @@ -35,7 +36,7 @@ export async function kickMember( config.kick_message, new TemplateSafeValueContainer({ guildName: pluginData.guild.name, - reason, + reason: reasonWithAttachments, moderator: kickOptions.caseArgs?.modId ? userToTemplateSafeUser(await resolveUser(pluginData.client, kickOptions.caseArgs.modId)) : null, diff --git a/backend/src/plugins/ModActions/functions/updateCase.ts b/backend/src/plugins/ModActions/functions/updateCase.ts index d715e263..78b5d6f4 100644 --- a/backend/src/plugins/ModActions/functions/updateCase.ts +++ b/backend/src/plugins/ModActions/functions/updateCase.ts @@ -1,19 +1,19 @@ -import { Attachment, ChatInputCommandInteraction, TextBasedChannel, User } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, Message, User } from "discord.js"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../types"; -import { formatReasonWithAttachments } from "./formatReasonWithAttachments"; +import { formatReasonWithMessageLinkForAttachments } from "./formatReasonForAttachments"; export async function updateCase( pluginData: GuildPluginData, - context: TextBasedChannel | ChatInputCommandInteraction, + context: Message | ChatInputCommandInteraction, author: User, caseNumber?: number, - note?: string, + note = "", attachments: Attachment[] = [], ) { let theCase: Case | null; @@ -24,16 +24,16 @@ export async function updateCase( } if (!theCase) { - sendErrorMessage(pluginData, context, "Case not found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Case not found"); return; } - if (!note && attachments.length === 0) { - sendErrorMessage(pluginData, context, "Text or attachment required"); + if (note.length === 0 && attachments.length === 0) { + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Text or attachment required"); return; } - const formattedNote = formatReasonWithAttachments(note ?? "", attachments); + const formattedNote = await formatReasonWithMessageLinkForAttachments(pluginData, note, context, attachments); const casesPlugin = pluginData.getPlugin(CasesPlugin); await casesPlugin.createCaseNote({ @@ -49,5 +49,5 @@ export async function updateCase( note: formattedNote, }); - sendSuccessMessage(pluginData, context, `Case \`#${theCase.case_number}\` updated`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, `Case \`#${theCase.case_number}\` updated`); } diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts index 8f58f915..004caf7f 100644 --- a/backend/src/plugins/ModActions/functions/warnMember.ts +++ b/backend/src/plugins/ModActions/functions/warnMember.ts @@ -1,7 +1,7 @@ import { GuildMember, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; -import { isContextInteraction } from "../../../pluginUtils"; +import { getContextChannel, isContextInteraction } from "../../../pluginUtils"; import { TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; import { UserNotificationResult, createUserNotificationError, notifyUser, resolveUser, ucfirst } from "../../../utils"; import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; @@ -15,6 +15,7 @@ export async function warnMember( pluginData: GuildPluginData, member: GuildMember, reason: string, + reasonWithAttachments: string, warnOptions: WarnOptions = {}, ): Promise { const config = pluginData.config.get(); @@ -25,7 +26,7 @@ export async function warnMember( config.warn_message, new TemplateSafeValueContainer({ guildName: pluginData.guild.name, - reason, + reason: reasonWithAttachments, moderator: warnOptions.caseArgs?.modId ? userToTemplateSafeUser(await resolveUser(pluginData.client, warnOptions.caseArgs.modId)) : null, @@ -40,8 +41,10 @@ export async function warnMember( } if (!notifyResult.success) { - const contextIsChannel = warnOptions.retryPromptContext && !isContextInteraction(warnOptions.retryPromptContext); - const isValidChannel = contextIsChannel && pluginData.guild.channels.resolve(warnOptions.retryPromptContext!.id); + const contextIsNotInteraction = + warnOptions.retryPromptContext && !isContextInteraction(warnOptions.retryPromptContext); + const contextChannel = contextIsNotInteraction ? await getContextChannel(warnOptions.retryPromptContext!) : null; + const isValidChannel = contextIsNotInteraction && pluginData.guild.channels.resolve(contextChannel!.id); if (!warnOptions.retryPromptContext || !isValidChannel) { return { diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index 5a61c342..68a0acda 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -1,4 +1,4 @@ -import { ChatInputCommandInteraction, TextBasedChannel } from "discord.js"; +import { ChatInputCommandInteraction, Message } from "discord.js"; import { EventEmitter } from "events"; import * as t from "io-ts"; import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, guildPluginSlashGroup } from "knub"; @@ -11,6 +11,8 @@ import { Case } from "../../data/entities/Case"; import { UserNotificationMethod, UserNotificationResult, tNullable } from "../../utils"; import { CaseArgs } from "../Cases/types"; +export type AttachmentLinkReactionType = "none" | "warn" | "restrict" | null | undefined; + export const ConfigSchema = t.type({ dm_on_warn: t.boolean, dm_on_kick: t.boolean, @@ -29,6 +31,8 @@ export const ConfigSchema = t.type({ warn_notify_threshold: t.number, warn_notify_message: t.string, ban_delete_message_days: t.number, + attachment_link_reaction: tNullable(t.union([t.literal("none"), t.literal("warn"), t.literal("restrict")])), + attachment_storing_channel: tNullable(t.string), can_note: t.boolean, can_warn: t.boolean, can_mute: t.boolean, @@ -127,7 +131,7 @@ export type WarnMemberNotifyRetryCallback = () => boolean | Promise; export interface WarnOptions { caseArgs?: Partial | null; contactMethods?: UserNotificationMethod[] | null; - retryPromptContext?: TextBasedChannel | ChatInputCommandInteraction | null; + retryPromptContext?: Message | ChatInputCommandInteraction | null; isAutomodAction?: boolean; } diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts index 29f9dc28..3884ae89 100644 --- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord.js"; -import { sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { mutesCmd } from "../types"; export const ClearBannedMutesCmd = mutesCmd({ @@ -25,6 +25,6 @@ export const ClearBannedMutesCmd = mutesCmd({ } } - sendSuccessMessage(pluginData, msg.channel, `Cleared ${cleared} mutes from banned users!`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Cleared ${cleared} mutes from banned users!`); }, }); diff --git a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts index 3021a7a7..a71dc402 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { mutesCmd } from "../types"; export const ClearMutesCmd = mutesCmd({ @@ -23,15 +23,18 @@ export const ClearMutesCmd = mutesCmd({ } if (failed.length !== args.userIds.length) { - sendSuccessMessage(pluginData, msg.channel, `**${args.userIds.length - failed.length} active mute(s) cleared**`); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `**${args.userIds.length - failed.length} active mute(s) cleared**`); } if (failed.length) { - sendErrorMessage( - pluginData, - msg.channel, - `**${failed.length}/${args.userIds.length} IDs failed**, they are not muted: ${failed.join(" ")}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage( + msg, + `**${failed.length}/${args.userIds.length} IDs failed**, they are not muted: ${failed.join(" ")}`, + ); } }, }); diff --git a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts index 0dbef291..1e52f6b3 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts @@ -1,6 +1,6 @@ import { Snowflake } from "discord.js"; -import { sendSuccessMessage } from "../../../pluginUtils"; import { resolveMember } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { mutesCmd } from "../types"; export const ClearMutesWithoutRoleCmd = mutesCmd({ @@ -26,6 +26,8 @@ export const ClearMutesWithoutRoleCmd = mutesCmd({ } } - sendSuccessMessage(pluginData, msg.channel, `Cleared ${cleared} mutes from members that don't have the mute role`); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `Cleared ${cleared} mutes from members that don't have the mute role`); }, }); diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index 575f96fb..2dd5a3d1 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -35,6 +35,7 @@ export async function muteUser( userId: string, muteTime?: number, reason?: string, + reasonWithAttachments?: string, muteOptions: MuteOptions = {}, removeRolesOnMuteOverride: boolean | string[] | null = null, restoreRolesOnMuteOverride: boolean | string[] | null = null, @@ -193,7 +194,7 @@ export async function muteUser( template, new TemplateSafeValueContainer({ guildName: pluginData.guild.name, - reason: reason || "None", + reason: reasonWithAttachments || "None", time: timeUntilUnmuteStr, moderator: muteOptions.caseArgs?.modId ? userToTemplateSafeUser(await resolveUser(pluginData.client, muteOptions.caseArgs.modId)) diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts index 373f1671..d7ef50b0 100644 --- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts +++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts @@ -4,8 +4,8 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { MAX_NICKNAME_ENTRIES_PER_USER } from "../../../data/GuildNicknameHistory"; import { MAX_USERNAME_ENTRIES_PER_USER } from "../../../data/UsernameHistory"; import { NICKNAME_RETENTION_PERIOD } from "../../../data/cleanup/nicknames"; -import { sendErrorMessage } from "../../../pluginUtils"; import { DAYS, renderUserUsername } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { nameHistoryCmd } from "../types"; export const NamesCmd = nameHistoryCmd({ @@ -21,7 +21,7 @@ export const NamesCmd = nameHistoryCmd({ const usernames = await pluginData.state.usernameHistory.getByUserId(args.userId); if (nicknames.length === 0 && usernames.length === 0) { - sendErrorMessage(pluginData, msg.channel, "No name history found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No name history found"); return; } diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts index 41709ffc..00006cee 100644 --- a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts +++ b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { pingableRolesCmd } from "../types"; export const PingableRoleDisableCmd = pingableRolesCmd({ @@ -14,17 +14,17 @@ export const PingableRoleDisableCmd = pingableRolesCmd({ async run({ message: msg, args, pluginData }) { const pingableRole = await pluginData.state.pingableRoles.getByChannelAndRoleId(args.channelId, args.role.id); if (!pingableRole) { - sendErrorMessage(pluginData, msg.channel, `**${args.role.name}** is not set as pingable in <#${args.channelId}>`); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `**${args.role.name}** is not set as pingable in <#${args.channelId}>`); return; } await pluginData.state.pingableRoles.delete(args.channelId, args.role.id); pluginData.state.cache.delete(args.channelId); - sendSuccessMessage( - pluginData, - msg.channel, - `**${args.role.name}** is no longer set as pingable in <#${args.channelId}>`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `**${args.role.name}** is no longer set as pingable in <#${args.channelId}>`); }, }); diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts index 30077e09..7a93990f 100644 --- a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts +++ b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { pingableRolesCmd } from "../types"; export const PingableRoleEnableCmd = pingableRolesCmd({ @@ -17,21 +17,17 @@ export const PingableRoleEnableCmd = pingableRolesCmd({ args.role.id, ); if (existingPingableRole) { - sendErrorMessage( - pluginData, - msg.channel, - `**${args.role.name}** is already set as pingable in <#${args.channelId}>`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `**${args.role.name}** is already set as pingable in <#${args.channelId}>`); return; } await pluginData.state.pingableRoles.add(args.channelId, args.role.id); pluginData.state.cache.delete(args.channelId); - sendSuccessMessage( - pluginData, - msg.channel, - `**${args.role.name}** has been set as pingable in <#${args.channelId}>`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `**${args.role.name}** has been set as pingable in <#${args.channelId}>`); }, }); diff --git a/backend/src/plugins/Post/commands/EditCmd.ts b/backend/src/plugins/Post/commands/EditCmd.ts index 47ae07d7..cd607aa6 100644 --- a/backend/src/plugins/Post/commands/EditCmd.ts +++ b/backend/src/plugins/Post/commands/EditCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { postCmd } from "../types"; import { formatContent } from "../util/formatContent"; @@ -15,18 +15,18 @@ export const EditCmd = postCmd({ async run({ message: msg, args, pluginData }) { const targetMessage = await args.message.channel.messages.fetch(args.message.messageId); if (!targetMessage) { - sendErrorMessage(pluginData, msg.channel, "Unknown message"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown message"); return; } if (targetMessage.author.id !== pluginData.client.user!.id) { - sendErrorMessage(pluginData, msg.channel, "Message wasn't posted by me"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Message wasn't posted by me"); return; } targetMessage.channel.messages.edit(targetMessage.id, { content: formatContent(args.content), }); - sendSuccessMessage(pluginData, msg.channel, "Message edited"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Message edited"); }, }); diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts index 2ac364f1..7d42c040 100644 --- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts @@ -1,9 +1,9 @@ import { APIEmbed } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { isValidEmbed, trimLines } from "../../../utils"; import { parseColor } from "../../../utils/parseColor"; import { rgbToInt } from "../../../utils/rgbToInt"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { postCmd } from "../types"; import { formatContent } from "../util/formatContent"; @@ -30,14 +30,14 @@ export const EditEmbedCmd = postCmd({ if (colorRgb) { color = rgbToInt(colorRgb); } else { - sendErrorMessage(pluginData, msg.channel, "Invalid color specified"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid color specified"); return; } } const targetMessage = await args.message.channel.messages.fetch(args.message.messageId); if (!targetMessage) { - sendErrorMessage(pluginData, msg.channel, "Unknown message"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown message"); return; } @@ -51,12 +51,12 @@ export const EditEmbedCmd = postCmd({ try { parsed = JSON.parse(content); } catch (e) { - sendErrorMessage(pluginData, msg.channel, `Syntax error in embed JSON: ${e.message}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Syntax error in embed JSON: ${e.message}`); return; } if (!isValidEmbed(parsed)) { - sendErrorMessage(pluginData, msg.channel, "Embed is not valid"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Embed is not valid"); return; } @@ -69,7 +69,7 @@ export const EditEmbedCmd = postCmd({ args.message.channel.messages.edit(targetMessage.id, { embeds: [embed], }); - await sendSuccessMessage(pluginData, msg.channel, "Embed edited"); + await pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Embed edited"); if (args.content) { const prefix = pluginData.fullConfig.prefix || "!"; diff --git a/backend/src/plugins/Post/commands/PostEmbedCmd.ts b/backend/src/plugins/Post/commands/PostEmbedCmd.ts index e605402b..a78abacb 100644 --- a/backend/src/plugins/Post/commands/PostEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/PostEmbedCmd.ts @@ -1,9 +1,9 @@ import { APIEmbed } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { isValidEmbed, trimLines } from "../../../utils"; import { parseColor } from "../../../utils/parseColor"; import { rgbToInt } from "../../../utils/rgbToInt"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { postCmd } from "../types"; import { actualPostCmd } from "../util/actualPostCmd"; import { formatContent } from "../util/formatContent"; @@ -31,7 +31,7 @@ export const PostEmbedCmd = postCmd({ const content = args.content || args.maincontent; if (!args.title && !content) { - sendErrorMessage(pluginData, msg.channel, "Title or content required"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Title or content required"); return; } @@ -41,7 +41,7 @@ export const PostEmbedCmd = postCmd({ if (colorRgb) { color = rgbToInt(colorRgb); } else { - sendErrorMessage(pluginData, msg.channel, "Invalid color specified"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid color specified"); return; } } @@ -56,12 +56,12 @@ export const PostEmbedCmd = postCmd({ try { parsed = JSON.parse(content); } catch (e) { - sendErrorMessage(pluginData, msg.channel, `Syntax error in embed JSON: ${e.message}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Syntax error in embed JSON: ${e.message}`); return; } if (!isValidEmbed(parsed)) { - sendErrorMessage(pluginData, msg.channel, "Embed is not valid"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Embed is not valid"); return; } diff --git a/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts index 78becae8..565135e6 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts @@ -1,7 +1,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { clearUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { sorter } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { postCmd } from "../types"; export const ScheduledPostsDeleteCmd = postCmd({ @@ -17,12 +17,12 @@ export const ScheduledPostsDeleteCmd = postCmd({ scheduledPosts.sort(sorter("post_at")); const post = scheduledPosts[args.num - 1]; if (!post) { - sendErrorMessage(pluginData, msg.channel, "Scheduled post not found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Scheduled post not found"); return; } clearUpcomingScheduledPost(post); await pluginData.state.scheduledPosts.delete(post.id); - sendSuccessMessage(pluginData, msg.channel, "Scheduled post deleted!"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Scheduled post deleted!"); }, }); diff --git a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts index 990bfbae..2895cc68 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { sorter } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { postCmd } from "../types"; import { postMessage } from "../util/postMessage"; @@ -17,7 +17,7 @@ export const ScheduledPostsShowCmd = postCmd({ scheduledPosts.sort(sorter("post_at")); const post = scheduledPosts[args.num - 1]; if (!post) { - sendErrorMessage(pluginData, msg.channel, "Scheduled post not found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Scheduled post not found"); return; } diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index c73a672b..fb564499 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -3,8 +3,8 @@ import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { registerUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { DBDateFormat, MINUTES, StrictMessageContent, errorMessage } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { PostPluginType } from "../types"; @@ -40,11 +40,15 @@ export async function actualPostCmd( if (opts.repeat) { if (opts.repeat < MIN_REPEAT_TIME) { - sendErrorMessage(pluginData, msg.channel, `Minimum time for -repeat is ${humanizeDuration(MIN_REPEAT_TIME)}`); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `Minimum time for -repeat is ${humanizeDuration(MIN_REPEAT_TIME)}`); return; } if (opts.repeat > MAX_REPEAT_TIME) { - sendErrorMessage(pluginData, msg.channel, `Max time for -repeat is ${humanizeDuration(MAX_REPEAT_TIME)}`); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `Max time for -repeat is ${humanizeDuration(MAX_REPEAT_TIME)}`); return; } } @@ -55,7 +59,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, "Invalid schedule time"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid schedule time"); return; } } else if (opts.repeat) { @@ -72,36 +76,41 @@ export async function actualPostCmd( // Invalid time if (!repeatUntil) { - sendErrorMessage(pluginData, msg.channel, "Invalid time specified for -repeat-until"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid time specified for -repeat-until"); return; } if (repeatUntil.isBefore(moment.utc())) { - sendErrorMessage(pluginData, msg.channel, "You can't set -repeat-until in the past"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You can't set -repeat-until in the past"); return; } if (repeatUntil.isAfter(MAX_REPEAT_UNTIL)) { - sendErrorMessage( - pluginData, - msg.channel, - "Unfortunately, -repeat-until can only be at most 100 years into the future. Maybe 99 years would be enough?", - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage( + msg, + "Unfortunately, -repeat-until can only be at most 100 years into the future. Maybe 99 years would be enough?", + ); return; } } else if (opts["repeat-times"]) { repeatTimes = opts["repeat-times"]; if (repeatTimes <= 0) { - sendErrorMessage(pluginData, msg.channel, "-repeat-times must be 1 or more"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "-repeat-times must be 1 or more"); return; } } if (repeatUntil && repeatTimes) { - sendErrorMessage(pluginData, msg.channel, "You can only use one of -repeat-until or -repeat-times at once"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, "You can only use one of -repeat-until or -repeat-times at once"); return; } if (opts.repeat && !repeatUntil && !repeatTimes) { - sendErrorMessage(pluginData, msg.channel, "You must specify -repeat-until or -repeat-times for repeated messages"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, "You must specify -repeat-until or -repeat-times for repeated messages"); return; } @@ -116,7 +125,7 @@ export async function actualPostCmd( // Save schedule/repeat information in DB if (postAt) { if (postAt < moment.utc()) { - sendErrorMessage(pluginData, msg.channel, "Post can't be scheduled to be posted in the past"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Post can't be scheduled to be posted in the past"); return; } @@ -192,6 +201,6 @@ export async function actualPostCmd( } if (targetChannel.id !== msg.channel.id || opts.schedule || opts.repeat) { - sendSuccessMessage(pluginData, msg.channel, successMessage); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, successMessage); } } diff --git a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts index ff88b194..1dc632a7 100644 --- a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts @@ -1,7 +1,7 @@ import { Message } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { isDiscordAPIError } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { reactionRolesCmd } from "../types"; export const ClearReactionRolesCmd = reactionRolesCmd({ @@ -15,7 +15,7 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ async run({ message: msg, args, pluginData }) { const existingReactionRoles = pluginData.state.reactionRoles.getForMessage(args.message.messageId); if (!existingReactionRoles) { - sendErrorMessage(pluginData, msg.channel, "Message doesn't have reaction roles on it"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Message doesn't have reaction roles on it"); return; } @@ -26,7 +26,7 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ targetMessage = await args.message.channel.messages.fetch(args.message.messageId); } catch (err) { if (isDiscordAPIError(err) && err.code === 50001) { - sendErrorMessage(pluginData, msg.channel, "Missing access to the specified message"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Missing access to the specified message"); return; } @@ -35,6 +35,6 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ await targetMessage.reactions.removeAll(); - sendSuccessMessage(pluginData, msg.channel, "Reaction roles cleared"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Reaction roles cleared"); }, }); diff --git a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts index fefc166e..26d49039 100644 --- a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts @@ -1,8 +1,8 @@ import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { canUseEmoji, isDiscordAPIError, isValidEmoji, noop, trimPluginDescription } from "../../../utils"; import { canReadChannel } from "../../../utils/canReadChannel"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { TReactionRolePair, reactionRolesCmd } from "../types"; import { applyReactionRoleReactionsToMessage } from "../util/applyReactionRoleReactionsToMessage"; @@ -34,7 +34,9 @@ export const InitReactionRolesCmd = reactionRolesCmd({ async run({ message: msg, args, pluginData }) { if (!canReadChannel(args.message.channel, msg.member)) { - sendErrorMessage(pluginData, msg.channel, "You can't add reaction roles to channels you can't see yourself"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, "You can't add reaction roles to channels you can't see yourself"); return; } @@ -43,7 +45,7 @@ export const InitReactionRolesCmd = reactionRolesCmd({ targetMessage = await args.message.channel.messages.fetch(args.message.messageId); } catch (e) { if (isDiscordAPIError(e)) { - sendErrorMessage(pluginData, msg.channel, `Error ${e.code} while getting message: ${e.message}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Error ${e.code} while getting message: ${e.message}`); return; } @@ -71,30 +73,26 @@ export const InitReactionRolesCmd = reactionRolesCmd({ // Verify the specified emojis and roles are valid and usable for (const pair of emojiRolePairs) { if (pair[0] === CLEAR_ROLES_EMOJI) { - sendErrorMessage( - pluginData, - msg.channel, - `The emoji for clearing roles (${CLEAR_ROLES_EMOJI}) is reserved and cannot be used`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `The emoji for clearing roles (${CLEAR_ROLES_EMOJI}) is reserved and cannot be used`); return; } if (!isValidEmoji(pair[0])) { - sendErrorMessage(pluginData, msg.channel, `Invalid emoji: ${pair[0]}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Invalid emoji: ${pair[0]}`); return; } if (!canUseEmoji(pluginData.client, pair[0])) { - sendErrorMessage( - pluginData, - msg.channel, - "I can only use regular emojis and custom emojis from servers I'm on", - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, "I can only use regular emojis and custom emojis from servers I'm on"); return; } if (!pluginData.guild.roles.cache.has(pair[1] as Snowflake)) { - sendErrorMessage(pluginData, msg.channel, `Unknown role ${pair[1]}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Unknown role ${pair[1]}`); return; } } @@ -125,9 +123,11 @@ export const InitReactionRolesCmd = reactionRolesCmd({ ); if (errors?.length) { - sendErrorMessage(pluginData, msg.channel, `Errors while adding reaction roles:\n${errors.join("\n")}`); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `Errors while adding reaction roles:\n${errors.join("\n")}`); } else { - sendSuccessMessage(pluginData, msg.channel, "Reaction roles added"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Reaction roles added"); } (await progressMessage).delete().catch(noop); diff --git a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts index 3a55f6ba..6d26ff48 100644 --- a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { reactionRolesCmd } from "../types"; import { refreshReactionRoles } from "../util/refreshReactionRoles"; @@ -13,12 +13,12 @@ export const RefreshReactionRolesCmd = reactionRolesCmd({ async run({ message: msg, args, pluginData }) { if (pluginData.state.pendingRefreshes.has(`${args.message.channel.id}-${args.message.messageId}`)) { - sendErrorMessage(pluginData, msg.channel, "Another refresh in progress"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Another refresh in progress"); return; } await refreshReactionRoles(pluginData, args.message.channel.id, args.message.messageId); - sendSuccessMessage(pluginData, msg.channel, "Reaction roles refreshed"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Reaction roles refreshed"); }, }); diff --git a/backend/src/plugins/Reminders/commands/RemindCmd.ts b/backend/src/plugins/Reminders/commands/RemindCmd.ts index c4655771..88ceeaa3 100644 --- a/backend/src/plugins/Reminders/commands/RemindCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindCmd.ts @@ -2,8 +2,8 @@ import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { registerUpcomingReminder } from "../../../data/loops/upcomingRemindersLoop"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { convertDelayStringToMS, messageLink } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { remindersCmd } from "../types"; @@ -38,7 +38,7 @@ export const RemindCmd = remindersCmd({ // "Delay string" i.e. e.g. "2h30m" const ms = convertDelayStringToMS(args.time); if (ms === null) { - sendErrorMessage(pluginData, msg.channel, "Invalid reminder time"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid reminder time"); return; } @@ -46,7 +46,7 @@ export const RemindCmd = remindersCmd({ } if (!reminderTime.isValid() || reminderTime.isBefore(now)) { - sendErrorMessage(pluginData, msg.channel, "Invalid reminder time"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid reminder time"); return; } @@ -67,10 +67,8 @@ export const RemindCmd = remindersCmd({ pluginData.getPlugin(TimeAndDatePlugin).getDateFormat("pretty_datetime"), ); - sendSuccessMessage( - pluginData, - msg.channel, - `I will remind you in **${timeUntilReminder}** at **${prettyReminderTime}**`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `I will remind you in **${timeUntilReminder}** at **${prettyReminderTime}**`); }, }); diff --git a/backend/src/plugins/Reminders/commands/RemindersCmd.ts b/backend/src/plugins/Reminders/commands/RemindersCmd.ts index ce914a34..7b2da150 100644 --- a/backend/src/plugins/Reminders/commands/RemindersCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersCmd.ts @@ -1,7 +1,7 @@ import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; -import { sendErrorMessage } from "../../../pluginUtils"; import { createChunkedMessage, DBDateFormat, sorter } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { remindersCmd } from "../types"; @@ -12,7 +12,7 @@ export const RemindersCmd = remindersCmd({ async run({ message: msg, pluginData }) { const reminders = await pluginData.state.reminders.getRemindersByUserId(msg.author.id); if (reminders.length === 0) { - sendErrorMessage(pluginData, msg.channel, "No reminders"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No reminders"); return; } diff --git a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts index 25713a4f..5566a133 100644 --- a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts @@ -1,7 +1,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { clearUpcomingReminder } from "../../../data/loops/upcomingRemindersLoop"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { sorter } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { remindersCmd } from "../types"; export const RemindersDeleteCmd = remindersCmd({ @@ -17,7 +17,7 @@ export const RemindersDeleteCmd = remindersCmd({ reminders.sort(sorter("remind_at")); if (args.num > reminders.length || args.num <= 0) { - sendErrorMessage(pluginData, msg.channel, "Unknown reminder"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown reminder"); return; } @@ -25,6 +25,6 @@ export const RemindersDeleteCmd = remindersCmd({ clearUpcomingReminder(toDelete); await pluginData.state.reminders.delete(toDelete.id); - sendSuccessMessage(pluginData, msg.channel, "Reminder deleted"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Reminder deleted"); }, }); diff --git a/backend/src/plugins/RoleButtons/commands/resetButtons.ts b/backend/src/plugins/RoleButtons/commands/resetButtons.ts index cca8e643..edd99eb0 100644 --- a/backend/src/plugins/RoleButtons/commands/resetButtons.ts +++ b/backend/src/plugins/RoleButtons/commands/resetButtons.ts @@ -1,6 +1,6 @@ import { guildPluginMessageCommand } from "knub"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { applyAllRoleButtons } from "../functions/applyAllRoleButtons"; import { RoleButtonsPluginType } from "../types"; @@ -16,12 +16,14 @@ export const resetButtonsCmd = guildPluginMessageCommand( async run({ pluginData, args, message }) { const config = pluginData.config.get(); if (!config.buttons[args.name]) { - sendErrorMessage(pluginData, message.channel, `Can't find role buttons with the name "${args.name}"`); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(message, `Can't find role buttons with the name "${args.name}"`); return; } await pluginData.state.roleButtons.deleteRoleButtonItem(args.name); await applyAllRoleButtons(pluginData); - sendSuccessMessage(pluginData, message.channel, "Done!"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(message, "Done!"); }, }); diff --git a/backend/src/plugins/Roles/commands/AddRoleCmd.ts b/backend/src/plugins/Roles/commands/AddRoleCmd.ts index ccd64325..a66ff365 100644 --- a/backend/src/plugins/Roles/commands/AddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/AddRoleCmd.ts @@ -1,7 +1,8 @@ import { GuildChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { canActOn } from "../../../pluginUtils"; import { resolveRoleId, verboseUserMention } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; import { rolesCmd } from "../types"; @@ -18,19 +19,21 @@ export const AddRoleCmd = rolesCmd({ async run({ message: msg, args, pluginData }) { if (!canActOn(pluginData, msg.member, args.member, true)) { - sendErrorMessage(pluginData, msg.channel, "Cannot add roles to this user: insufficient permissions"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, "Cannot add roles to this user: insufficient permissions"); return; } const roleId = await resolveRoleId(pluginData.client, pluginData.guild.id, args.role); if (!roleId) { - sendErrorMessage(pluginData, msg.channel, "Invalid role id"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid role id"); return; } const config = await pluginData.config.getForMessage(msg); if (!config.assignable_roles.includes(roleId)) { - sendErrorMessage(pluginData, msg.channel, "You cannot assign that role"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot assign that role"); return; } @@ -40,12 +43,12 @@ export const AddRoleCmd = rolesCmd({ pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown role configured for 'roles' plugin: ${roleId}`, }); - sendErrorMessage(pluginData, msg.channel, "You cannot assign that role"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot assign that role"); return; } if (args.member.roles.cache.has(roleId)) { - sendErrorMessage(pluginData, msg.channel, "Member already has that role"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member already has that role"); return; } @@ -57,10 +60,8 @@ export const AddRoleCmd = rolesCmd({ roles: [role], }); - sendSuccessMessage( - pluginData, - msg.channel, - `Added role **${role.name}** to ${verboseUserMention(args.member.user)}!`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `Added role **${role.name}** to ${verboseUserMention(args.member.user)}!`); }, }); diff --git a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts index 9030e45c..05db86ba 100644 --- a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts @@ -1,8 +1,9 @@ import { GuildMember } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { logger } from "../../../logger"; -import { canActOn, sendErrorMessage } from "../../../pluginUtils"; +import { canActOn } from "../../../pluginUtils"; import { resolveMember, resolveRoleId, successMessage } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; import { rolesCmd } from "../types"; @@ -29,24 +30,22 @@ export const MassAddRoleCmd = rolesCmd({ for (const member of members) { if (!canActOn(pluginData, msg.member, member, true)) { - sendErrorMessage( - pluginData, - msg.channel, - "Cannot add roles to 1 or more specified members: insufficient permissions", - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, "Cannot add roles to 1 or more specified members: insufficient permissions"); return; } } const roleId = await resolveRoleId(pluginData.client, pluginData.guild.id, args.role); if (!roleId) { - sendErrorMessage(pluginData, msg.channel, "Invalid role id"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid role id"); return; } const config = await pluginData.config.getForMessage(msg); if (!config.assignable_roles.includes(roleId)) { - sendErrorMessage(pluginData, msg.channel, "You cannot assign that role"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot assign that role"); return; } @@ -55,7 +54,7 @@ export const MassAddRoleCmd = rolesCmd({ pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown role configured for 'roles' plugin: ${roleId}`, }); - sendErrorMessage(pluginData, msg.channel, "You cannot assign that role"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot assign that role"); return; } diff --git a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts index de4591b4..06a5337d 100644 --- a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts @@ -1,7 +1,8 @@ import { GuildMember } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage } from "../../../pluginUtils"; +import { canActOn } from "../../../pluginUtils"; import { resolveMember, resolveRoleId, successMessage } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; import { rolesCmd } from "../types"; @@ -28,24 +29,22 @@ export const MassRemoveRoleCmd = rolesCmd({ for (const member of members) { if (!canActOn(pluginData, msg.member, member, true)) { - sendErrorMessage( - pluginData, - msg.channel, - "Cannot add roles to 1 or more specified members: insufficient permissions", - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, "Cannot add roles to 1 or more specified members: insufficient permissions"); return; } } const roleId = await resolveRoleId(pluginData.client, pluginData.guild.id, args.role); if (!roleId) { - sendErrorMessage(pluginData, msg.channel, "Invalid role id"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid role id"); return; } const config = await pluginData.config.getForMessage(msg); if (!config.assignable_roles.includes(roleId)) { - sendErrorMessage(pluginData, msg.channel, "You cannot remove that role"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot remove that role"); return; } @@ -54,7 +53,7 @@ export const MassRemoveRoleCmd = rolesCmd({ pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown role configured for 'roles' plugin: ${roleId}`, }); - sendErrorMessage(pluginData, msg.channel, "You cannot remove that role"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot remove that role"); return; } diff --git a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts index 8cd6f306..e3dc979d 100644 --- a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts @@ -1,7 +1,8 @@ import { GuildChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { canActOn } from "../../../pluginUtils"; import { resolveRoleId, verboseUserMention } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; import { rolesCmd } from "../types"; @@ -18,19 +19,21 @@ export const RemoveRoleCmd = rolesCmd({ async run({ message: msg, args, pluginData }) { if (!canActOn(pluginData, msg.member, args.member, true)) { - sendErrorMessage(pluginData, msg.channel, "Cannot remove roles from this user: insufficient permissions"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, "Cannot remove roles from this user: insufficient permissions"); return; } const roleId = await resolveRoleId(pluginData.client, pluginData.guild.id, args.role); if (!roleId) { - sendErrorMessage(pluginData, msg.channel, "Invalid role id"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid role id"); return; } const config = await pluginData.config.getForMessage(msg); if (!config.assignable_roles.includes(roleId)) { - sendErrorMessage(pluginData, msg.channel, "You cannot remove that role"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot remove that role"); return; } @@ -40,12 +43,12 @@ export const RemoveRoleCmd = rolesCmd({ pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown role configured for 'roles' plugin: ${roleId}`, }); - sendErrorMessage(pluginData, msg.channel, "You cannot remove that role"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot remove that role"); return; } if (!args.member.roles.cache.has(roleId)) { - sendErrorMessage(pluginData, msg.channel, "Member doesn't have that role"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member doesn't have that role"); return; } @@ -56,10 +59,8 @@ export const RemoveRoleCmd = rolesCmd({ roles: [role], }); - sendSuccessMessage( - pluginData, - msg.channel, - `Removed role **${role.name}** from ${verboseUserMention(args.member.user)}!`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `Removed role **${role.name}** from ${verboseUserMention(args.member.user)}!`); }, }); diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts index ce8a3a73..006307ac 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts @@ -1,7 +1,7 @@ import { Role, Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { selfGrantableRolesCmd } from "../types"; import { findMatchingRoles } from "../util/findMatchingRoles"; import { getApplyingEntries } from "../util/getApplyingEntries"; @@ -39,12 +39,11 @@ export const RoleAddCmd = selfGrantableRolesCmd({ }, new Map()); if (!rolesToAdd.size) { - sendErrorMessage( - pluginData, - msg.channel, - `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, - { users: [msg.author.id] }, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, { + users: [msg.author.id], + }); lock.unlock(); return; } @@ -84,12 +83,11 @@ export const RoleAddCmd = selfGrantableRolesCmd({ roles: Array.from(newRoleIds) as Snowflake[], }); } catch { - sendErrorMessage( - pluginData, - msg.channel, - `<@!${msg.author.id}> Got an error while trying to grant you the roles`, - { users: [msg.author.id] }, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `<@!${msg.author.id}> Got an error while trying to grant you the roles`, { + users: [msg.author.id], + }); return; } @@ -120,7 +118,7 @@ export const RoleAddCmd = selfGrantableRolesCmd({ messageParts.push("couldn't recognize some of the roles"); } - sendSuccessMessage(pluginData, msg.channel, `<@!${msg.author.id}> ${messageParts.join("; ")}`, { + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `<@!${msg.author.id}> ${messageParts.join("; ")}`, { users: [msg.author.id], }); diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts index 007aa459..b688203f 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts @@ -1,7 +1,7 @@ import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { selfGrantableRolesCmd } from "../types"; import { findMatchingRoles } from "../util/findMatchingRoles"; import { getApplyingEntries } from "../util/getApplyingEntries"; @@ -46,36 +46,34 @@ export const RoleRemoveCmd = selfGrantableRolesCmd({ const removedRolesWord = rolesToRemove.length === 1 ? "role" : "roles"; if (rolesToRemove.length !== roleNames.length) { - sendSuccessMessage( - pluginData, - msg.channel, - `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord};` + - ` couldn't recognize the other roles you mentioned`, - { users: [msg.author.id] }, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + msg, + `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord};` + + ` couldn't recognize the other roles you mentioned`, + { users: [msg.author.id] }, + ); } else { - sendSuccessMessage( - pluginData, - msg.channel, - `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord}`, - { users: [msg.author.id] }, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord}`, { + users: [msg.author.id], + }); } } catch { - sendSuccessMessage( - pluginData, - msg.channel, - `<@!${msg.author.id}> Got an error while trying to remove the roles`, - { users: [msg.author.id] }, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `<@!${msg.author.id}> Got an error while trying to remove the roles`, { + users: [msg.author.id], + }); } } else { - sendErrorMessage( - pluginData, - msg.channel, - `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, - { users: [msg.author.id] }, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, { + users: [msg.author.id], + }); } lock.unlock(); diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts index 246a048e..72082350 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts @@ -1,9 +1,9 @@ import { ChannelType, escapeInlineCode } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { asSingleLine, renderUserUsername } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { BOT_SLOWMODE_CLEAR_PERMISSIONS } from "../requiredPermissions"; import { slowmodeCmd } from "../types"; import { clearBotSlowmodeFromUserId } from "../util/clearBotSlowmodeFromUserId"; @@ -22,18 +22,16 @@ export const SlowmodeClearCmd = slowmodeCmd({ async run({ message: msg, args, pluginData }) { const channelSlowmode = await pluginData.state.slowmodes.getChannelSlowmode(args.channel.id); if (!channelSlowmode) { - sendErrorMessage(pluginData, msg.channel, "Channel doesn't have slowmode!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Channel doesn't have slowmode!"); return; } const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; const missingPermissions = getMissingChannelPermissions(me, args.channel, BOT_SLOWMODE_CLEAR_PERMISSIONS); if (missingPermissions) { - sendErrorMessage( - pluginData, - msg.channel, - `Unable to clear slowmode. ${missingPermissionError(missingPermissions)}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `Unable to clear slowmode. ${missingPermissionError(missingPermissions)}`); return; } @@ -41,9 +39,8 @@ export const SlowmodeClearCmd = slowmodeCmd({ if (args.channel.type === ChannelType.GuildText) { await clearBotSlowmodeFromUserId(pluginData, args.channel, args.user.id, args.force); } else { - sendErrorMessage( - pluginData, - msg.channel, + pluginData.getPlugin(CommonPlugin).sendErrorMessage( + msg, asSingleLine(` Failed to clear slowmode from **${renderUserUsername(args.user)}** in <#${args.channel.id}>: Threads cannot have Bot Slowmode @@ -52,9 +49,8 @@ export const SlowmodeClearCmd = slowmodeCmd({ return; } } catch (e) { - sendErrorMessage( - pluginData, - msg.channel, + pluginData.getPlugin(CommonPlugin).sendErrorMessage( + msg, asSingleLine(` Failed to clear slowmode from **${renderUserUsername(args.user)}** in <#${args.channel.id}>: \`${escapeInlineCode(e.message)}\` @@ -63,10 +59,8 @@ export const SlowmodeClearCmd = slowmodeCmd({ return; } - sendSuccessMessage( - pluginData, - msg.channel, - `Slowmode cleared from **${renderUserUsername(args.user)}** in <#${args.channel.id}>`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `Slowmode cleared from **${renderUserUsername(args.user)}** in <#${args.channel.id}>`); }, }); diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index 44d5c111..0d088b43 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -1,10 +1,10 @@ import { escapeInlineCode, PermissionsBitField } from "discord.js"; import humanizeDuration from "humanize-duration"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { asSingleLine, DAYS, HOURS, MINUTES } from "../../../utils"; import { getMissingPermissions } from "../../../utils/getMissingPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { BOT_SLOWMODE_PERMISSIONS, NATIVE_SLOWMODE_PERMISSIONS } from "../requiredPermissions"; import { slowmodeCmd } from "../types"; import { actualDisableSlowmodeCmd } from "../util/actualDisableSlowmodeCmd"; @@ -40,7 +40,9 @@ export const SlowmodeSetCmd = slowmodeCmd({ 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"); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, "Slowmode can only be set on non-thread text-based channels"); return; } @@ -56,29 +58,26 @@ export const SlowmodeSetCmd = slowmodeCmd({ const mode = (args.mode as TMode) || defaultMode; if (!validModes.includes(mode)) { - sendErrorMessage(pluginData, msg.channel, "--mode must be 'bot' or 'native'"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "--mode must be 'bot' or 'native'"); return; } // Validate durations if (mode === "native" && args.time > MAX_NATIVE_SLOWMODE) { - sendErrorMessage(pluginData, msg.channel, "Native slowmode can only be set to 6h or less"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Native slowmode can only be set to 6h or less"); return; } if (mode === "bot" && args.time > MAX_BOT_SLOWMODE) { - sendErrorMessage( - pluginData, - msg.channel, - `Sorry, bot managed slowmodes can be at most 100 years long. Maybe 99 would be enough?`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `Sorry, bot managed slowmodes can be at most 100 years long. Maybe 99 would be enough?`); return; } if (mode === "bot" && args.time < MIN_BOT_SLOWMODE) { - sendErrorMessage( - pluginData, - msg.channel, + pluginData.getPlugin(CommonPlugin).sendErrorMessage( + msg, asSingleLine(` Bot managed slowmode must be 15min or more. Use \`--mode native\` to use native slowmodes for short slowmodes instead. @@ -96,11 +95,9 @@ export const SlowmodeSetCmd = slowmodeCmd({ NATIVE_SLOWMODE_PERMISSIONS, ); if (missingPermissions) { - sendErrorMessage( - pluginData, - msg.channel, - `Unable to set native slowmode. ${missingPermissionError(missingPermissions)}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `Unable to set native slowmode. ${missingPermissionError(missingPermissions)}`); return; } } @@ -111,11 +108,9 @@ export const SlowmodeSetCmd = slowmodeCmd({ BOT_SLOWMODE_PERMISSIONS, ); if (missingPermissions) { - sendErrorMessage( - pluginData, - msg.channel, - `Unable to set bot managed slowmode. ${missingPermissionError(missingPermissions)}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `Unable to set bot managed slowmode. ${missingPermissionError(missingPermissions)}`); return; } } @@ -134,7 +129,9 @@ export const SlowmodeSetCmd = slowmodeCmd({ try { await channel.setRateLimitPerUser(rateLimitSeconds); } catch (e) { - sendErrorMessage(pluginData, msg.channel, `Failed to set native slowmode: ${escapeInlineCode(e.message)}`); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `Failed to set native slowmode: ${escapeInlineCode(e.message)}`); return; } } else { @@ -153,10 +150,8 @@ export const SlowmodeSetCmd = slowmodeCmd({ const humanizedSlowmodeTime = humanizeDuration(args.time); const slowmodeType = mode === "native" ? "native slowmode" : "bot-maintained slowmode"; - sendSuccessMessage( - pluginData, - msg.channel, - `Set ${humanizedSlowmodeTime} slowmode for <#${channel.id}> (${slowmodeType})`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `Set ${humanizedSlowmodeTime} slowmode for <#${channel.id}> (${slowmodeType})`); }, }); diff --git a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts index 2bc00bed..72c86a04 100644 --- a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts +++ b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts @@ -1,8 +1,8 @@ import { Message } from "discord.js"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { noop } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { BOT_SLOWMODE_DISABLE_PERMISSIONS } from "../requiredPermissions"; import { disableBotSlowmodeForChannel } from "./disableBotSlowmodeForChannel"; @@ -11,18 +11,16 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { const hasNativeSlowmode = args.channel.rateLimitPerUser; if (!botSlowmode && hasNativeSlowmode === 0) { - sendErrorMessage(pluginData, msg.channel, "Channel is not on slowmode!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Channel is not on slowmode!"); return; } const me = pluginData.guild.members.cache.get(pluginData.client.user!.id); const missingPermissions = getMissingChannelPermissions(me, args.channel, BOT_SLOWMODE_DISABLE_PERMISSIONS); if (missingPermissions) { - sendErrorMessage( - pluginData, - msg.channel, - `Unable to disable slowmode. ${missingPermissionError(missingPermissions)}`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `Unable to disable slowmode. ${missingPermissionError(missingPermissions)}`); return; } @@ -41,13 +39,14 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { } if (failedUsers.length) { - sendSuccessMessage( - pluginData, - msg.channel, - `Slowmode disabled! Failed to clear slowmode from the following users:\n\n<@!${failedUsers.join(">\n<@!")}>`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + msg, + `Slowmode disabled! Failed to clear slowmode from the following users:\n\n<@!${failedUsers.join(">\n<@!")}>`, + ); } else { - sendSuccessMessage(pluginData, msg.channel, "Slowmode disabled!"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Slowmode disabled!"); initMsg.delete().catch(noop); } } diff --git a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts index b2a46432..4c8a4e25 100644 --- a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts @@ -76,10 +76,13 @@ export async function logAndDetectMessageSpam( (spamConfig.mute_time && convertDelayStringToMS(spamConfig.mute_time.toString())) ?? 120 * 1000; try { + const reason = "Automatic spam detection"; + muteResult = await mutesPlugin.muteUser( member.id, muteTime, - "Automatic spam detection", + reason, + reason, { caseArgs: { modId: pluginData.client.user!.id, diff --git a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts index 3a339b5f..5b83c9a1 100644 --- a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts @@ -40,10 +40,13 @@ export async function logAndDetectOtherSpam( (spamConfig.mute_time && convertDelayStringToMS(spamConfig.mute_time.toString())) ?? 120 * 1000; try { + const reason = "Automatic spam detection"; + await mutesPlugin.muteUser( member.id, muteTime, - "Automatic spam detection", + reason, + reason, { caseArgs: { modId: pluginData.client.user!.id, diff --git a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts index 7fba0241..d074c948 100644 --- a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts +++ b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts @@ -1,6 +1,6 @@ import { Snowflake, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { starboardCmd } from "../types"; import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; @@ -19,13 +19,13 @@ export const MigratePinsCmd = starboardCmd({ const config = await pluginData.config.get(); const starboard = config.boards[args.starboardName]; if (!starboard) { - sendErrorMessage(pluginData, msg.channel, "Unknown starboard specified"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown starboard specified"); return; } const starboardChannel = pluginData.guild.channels.cache.get(starboard.channel_id as Snowflake); if (!starboardChannel || !(starboardChannel instanceof TextChannel)) { - sendErrorMessage(pluginData, msg.channel, "Starboard has an unknown/invalid channel id"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Starboard has an unknown/invalid channel id"); return; } @@ -43,10 +43,8 @@ export const MigratePinsCmd = starboardCmd({ await saveMessageToStarboard(pluginData, pin, starboard); } - sendSuccessMessage( - pluginData, - msg.channel, - `Pins migrated from <#${args.pinChannel.id}> to <#${starboardChannel.id}>!`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `Pins migrated from <#${args.pinChannel.id}> to <#${starboardChannel.id}>!`); }, }); diff --git a/backend/src/plugins/Tags/commands/TagCreateCmd.ts b/backend/src/plugins/Tags/commands/TagCreateCmd.ts index 10c81e87..0ee452f5 100644 --- a/backend/src/plugins/Tags/commands/TagCreateCmd.ts +++ b/backend/src/plugins/Tags/commands/TagCreateCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { TemplateParseError, parseTemplate } from "../../../templateFormatter"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { tagsCmd } from "../types"; export const TagCreateCmd = tagsCmd({ @@ -17,7 +17,7 @@ export const TagCreateCmd = tagsCmd({ parseTemplate(args.body); } catch (e) { if (e instanceof TemplateParseError) { - sendErrorMessage(pluginData, msg.channel, `Invalid tag syntax: ${e.message}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Invalid tag syntax: ${e.message}`); return; } else { throw e; @@ -27,6 +27,6 @@ export const TagCreateCmd = tagsCmd({ await pluginData.state.tags.createOrUpdate(args.tag, args.body, msg.author.id); const prefix = pluginData.config.get().prefix; - sendSuccessMessage(pluginData, msg.channel, `Tag set! Use it with: \`${prefix}${args.tag}\``); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Tag set! Use it with: \`${prefix}${args.tag}\``); }, }); diff --git a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts index 47cb623d..174b7b64 100644 --- a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts +++ b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { tagsCmd } from "../types"; export const TagDeleteCmd = tagsCmd({ @@ -13,11 +13,11 @@ export const TagDeleteCmd = tagsCmd({ async run({ message: msg, args, pluginData }) { const tag = await pluginData.state.tags.find(args.tag); if (!tag) { - sendErrorMessage(pluginData, msg.channel, "No tag with that name"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No tag with that name"); return; } await pluginData.state.tags.delete(args.tag); - sendSuccessMessage(pluginData, msg.channel, "Tag deleted!"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Tag deleted!"); }, }); diff --git a/backend/src/plugins/Tags/commands/TagEvalCmd.ts b/backend/src/plugins/Tags/commands/TagEvalCmd.ts index 55659d30..a5de9a77 100644 --- a/backend/src/plugins/Tags/commands/TagEvalCmd.ts +++ b/backend/src/plugins/Tags/commands/TagEvalCmd.ts @@ -1,8 +1,8 @@ import { MessageCreateOptions } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { TemplateParseError } from "../../../templateFormatter"; import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { tagsCmd } from "../types"; import { renderTagBody } from "../util/renderTagBody"; @@ -28,14 +28,14 @@ export const TagEvalCmd = tagsCmd({ )) as MessageCreateOptions; if (!rendered.content && !rendered.embeds?.length) { - sendErrorMessage(pluginData, msg.channel, "Evaluation resulted in an empty text"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Evaluation resulted in an empty text"); return; } msg.channel.send(rendered); } catch (e) { if (e instanceof TemplateParseError) { - sendErrorMessage(pluginData, msg.channel, `Failed to render tag: ${e.message}`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Failed to render tag: ${e.message}`); return; } diff --git a/backend/src/plugins/Tags/commands/TagSourceCmd.ts b/backend/src/plugins/Tags/commands/TagSourceCmd.ts index 9e0e5cef..6690f8f7 100644 --- a/backend/src/plugins/Tags/commands/TagSourceCmd.ts +++ b/backend/src/plugins/Tags/commands/TagSourceCmd.ts @@ -1,6 +1,7 @@ import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getBaseUrl, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { getBaseUrl } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { tagsCmd } from "../types"; export const TagSourceCmd = tagsCmd({ @@ -17,18 +18,18 @@ export const TagSourceCmd = tagsCmd({ if (args.delete) { const actualTag = await pluginData.state.tags.find(args.tag); if (!actualTag) { - sendErrorMessage(pluginData, msg.channel, "No tag with that name"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No tag with that name"); return; } await pluginData.state.tags.delete(args.tag); - sendSuccessMessage(pluginData, msg.channel, "Tag deleted!"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Tag deleted!"); return; } const tag = await pluginData.state.tags.find(args.tag); if (!tag) { - sendErrorMessage(pluginData, msg.channel, "No tag with that name"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No tag with that name"); return; } diff --git a/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts index db59965a..2c39519e 100644 --- a/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts @@ -1,4 +1,4 @@ -import { sendSuccessMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { getGuildTz } from "../functions/getGuildTz"; import { timeAndDateCmd } from "../types"; @@ -11,10 +11,8 @@ export const ResetTimezoneCmd = timeAndDateCmd({ async run({ pluginData, message }) { await pluginData.state.memberTimezones.reset(message.author.id); const serverTimezone = getGuildTz(pluginData); - sendSuccessMessage( - pluginData, - message.channel, - `Your timezone has been reset to server default, **${serverTimezone}**`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(message, `Your timezone has been reset to server default, **${serverTimezone}**`); }, }); diff --git a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts index 90d00b3b..70acf129 100644 --- a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts @@ -1,8 +1,8 @@ import { escapeInlineCode } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; import { trimLines } from "../../../utils"; import { parseFuzzyTimezone } from "../../../utils/parseFuzzyTimezone"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { timeAndDateCmd } from "../types"; export const SetTimezoneCmd = timeAndDateCmd({ @@ -16,9 +16,8 @@ export const SetTimezoneCmd = timeAndDateCmd({ async run({ pluginData, message, args }) { const parsedTz = parseFuzzyTimezone(args.timezone); if (!parsedTz) { - sendErrorMessage( - pluginData, - message.channel, + pluginData.getPlugin(CommonPlugin).sendErrorMessage( + message, trimLines(` Invalid timezone: \`${escapeInlineCode(args.timezone)}\` Zeppelin uses timezone locations rather than specific timezone names. @@ -29,6 +28,6 @@ export const SetTimezoneCmd = timeAndDateCmd({ } await pluginData.state.memberTimezones.set(message.author.id, parsedTz); - sendSuccessMessage(pluginData, message.channel, `Your timezone is now set to **${parsedTz}**`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(message, `Your timezone is now set to **${parsedTz}**`); }, }); diff --git a/backend/src/plugins/Utility/UtilityPlugin.ts b/backend/src/plugins/Utility/UtilityPlugin.ts index 68f6987a..9d966d8c 100644 --- a/backend/src/plugins/Utility/UtilityPlugin.ts +++ b/backend/src/plugins/Utility/UtilityPlugin.ts @@ -5,8 +5,9 @@ import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Supporters } from "../../data/Supporters"; -import { makeIoTsConfigParser, sendSuccessMessage } from "../../pluginUtils"; +import { makeIoTsConfigParser } from "../../pluginUtils"; import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { ModActionsPlugin } from "../ModActions/ModActionsPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; @@ -169,8 +170,8 @@ export const UtilityPlugin = zeppelinGuildPlugin()({ }, userInfo(pluginData) { - return (userId: Snowflake, requestMemberId?: Snowflake) => { - return getUserInfoEmbed(pluginData, userId, false, requestMemberId); + return (userId: Snowflake) => { + return getUserInfoEmbed(pluginData, userId, false); }; }, @@ -214,7 +215,7 @@ export const UtilityPlugin = zeppelinGuildPlugin()({ const { guild } = pluginData; if (activeReloads.has(guild.id)) { - sendSuccessMessage(pluginData, activeReloads.get(guild.id)!, "Reloaded!"); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(activeReloads.get(guild.id)!, "Reloaded!"); activeReloads.delete(guild.id); } }, diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index ef44a2cb..fe81cd15 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -1,7 +1,7 @@ import { APIEmbed, ImageFormat } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { UnknownUser, renderUserUsername } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { utilityCmd } from "../types"; export const AvatarCmd = utilityCmd({ @@ -24,7 +24,7 @@ export const AvatarCmd = utilityCmd({ }; msg.channel.send({ embeds: [embed] }); } else { - sendErrorMessage(pluginData, msg.channel, "Invalid user ID"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid user ID"); } }, }); diff --git a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts index bbef9bcf..5b4a70bb 100644 --- a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed"; import { utilityCmd } from "../types"; @@ -16,7 +16,7 @@ export const ChannelInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { const embed = await getChannelInfoEmbed(pluginData, args.channel); if (!embed) { - sendErrorMessage(pluginData, message.channel, "Unknown channel"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown channel"); return; } diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index e47dc413..11e7bcfb 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -5,9 +5,10 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { LogType } from "../../../data/LogType"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { humanizeDurationShort } from "../../../humanizeDurationShort"; -import { getBaseUrl, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { getBaseUrl } from "../../../pluginUtils"; import { ModActionsPlugin } from "../../../plugins/ModActions/ModActionsPlugin"; import { DAYS, SECONDS, chunkArray, getInviteCodesInString, noop } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { UtilityPluginType, utilityCmd } from "../types"; @@ -82,19 +83,22 @@ export interface CleanArgs { export async function cleanCmd(pluginData: GuildPluginData, args: CleanArgs | any, msg) { if (args.count > MAX_CLEAN_COUNT || args.count <= 0) { - sendErrorMessage( - pluginData, - msg.channel, - `Clean count must be between 1 and ${MAX_CLEAN_COUNT}`, - undefined, - args["response-interaction"], - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage( + msg, + `Clean count must be between 1 and ${MAX_CLEAN_COUNT}`, + undefined, + args["response-interaction"], + ); return; } const targetChannel = args.channel ? pluginData.guild.channels.cache.get(args.channel as Snowflake) : msg.channel; if (!targetChannel?.isTextBased()) { - sendErrorMessage(pluginData, msg.channel, `Invalid channel specified`, undefined, args["response-interaction"]); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `Invalid channel specified`, undefined, args["response-interaction"]); return; } @@ -106,13 +110,14 @@ export async function cleanCmd(pluginData: GuildPluginData, a categoryId: targetChannel.parentId, }); if (configForTargetChannel.can_clean !== true) { - sendErrorMessage( - pluginData, - msg.channel, - `Missing permissions to use clean on that channel`, - undefined, - args["response-interaction"], - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage( + msg, + `Missing permissions to use clean on that channel`, + undefined, + args["response-interaction"], + ); return; } } @@ -218,22 +223,14 @@ export async function cleanCmd(pluginData: GuildPluginData, a } } - responseMsg = await sendSuccessMessage( - pluginData, - msg.channel, - responseText, - undefined, - args["response-interaction"], - ); + responseMsg = await pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, responseText, undefined, args["response-interaction"]); } else { const responseText = `Found no messages to clean${note ? ` (${note})` : ""}!`; - responseMsg = await sendErrorMessage( - pluginData, - msg.channel, - responseText, - undefined, - args["response-interaction"], - ); + responseMsg = await pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, responseText, undefined, args["response-interaction"]); } cleaningMessage?.delete(); diff --git a/backend/src/plugins/Utility/commands/ContextCmd.ts b/backend/src/plugins/Utility/commands/ContextCmd.ts index ceec4407..eb613f57 100644 --- a/backend/src/plugins/Utility/commands/ContextCmd.ts +++ b/backend/src/plugins/Utility/commands/ContextCmd.ts @@ -1,8 +1,8 @@ import { Snowflake, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { messageLink } from "../../../utils"; import { canReadChannel } from "../../../utils/canReadChannel"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { utilityCmd } from "../types"; export const ContextCmd = utilityCmd({ @@ -23,7 +23,7 @@ export const ContextCmd = utilityCmd({ async run({ message: msg, args, pluginData }) { if (args.channel && !(args.channel instanceof TextChannel)) { - sendErrorMessage(pluginData, msg.channel, "Channel must be a text channel"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Channel must be a text channel"); return; } @@ -31,7 +31,7 @@ export const ContextCmd = utilityCmd({ const messageId = args.messageId ?? args.message.messageId; if (!canReadChannel(channel, msg.member)) { - sendErrorMessage(pluginData, msg.channel, "Message context not found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Message context not found"); return; } @@ -42,7 +42,7 @@ export const ContextCmd = utilityCmd({ }) )[0]; if (!previousMessage) { - sendErrorMessage(pluginData, msg.channel, "Message context not found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Message context not found"); return; } diff --git a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts index 5c89f3eb..114652a9 100644 --- a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { getCustomEmojiId } from "../functions/getCustomEmojiId"; import { getEmojiInfoEmbed } from "../functions/getEmojiInfoEmbed"; import { utilityCmd } from "../types"; @@ -17,13 +17,13 @@ export const EmojiInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { const emojiId = getCustomEmojiId(args.emoji); if (!emojiId) { - sendErrorMessage(pluginData, message.channel, "Emoji not found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Emoji not found"); return; } const embed = await getEmojiInfoEmbed(pluginData, emojiId); if (!embed) { - sendErrorMessage(pluginData, message.channel, "Emoji not found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Emoji not found"); return; } diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index 63d0ae81..23ffa8ac 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -1,10 +1,10 @@ import { Snowflake } from "discord.js"; import { getChannelId, getRoleId } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { isValidSnowflake, noop, parseInviteCodeInput, resolveInvite, resolveUser } from "../../../utils"; import { canReadChannel } from "../../../utils/canReadChannel"; import { resolveMessageTarget } from "../../../utils/resolveMessageTarget"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed"; import { getCustomEmojiId } from "../functions/getCustomEmojiId"; import { getEmojiInfoEmbed } from "../functions/getEmojiInfoEmbed"; @@ -42,7 +42,7 @@ export const InfoCmd = utilityCmd({ const channelId = getChannelId(value); const channel = channelId && pluginData.guild.channels.cache.get(channelId as Snowflake); if (channel) { - const embed = await getChannelInfoEmbed(pluginData, channelId!, message.author.id); + const embed = await getChannelInfoEmbed(pluginData, channelId!); if (embed) { message.channel.send({ embeds: [embed] }); return; @@ -54,7 +54,7 @@ export const InfoCmd = utilityCmd({ if (userCfg.can_server) { const guild = await pluginData.client.guilds.fetch(value as Snowflake).catch(noop); if (guild) { - const embed = await getServerInfoEmbed(pluginData, value, message.author.id); + const embed = await getServerInfoEmbed(pluginData, value); if (embed) { message.channel.send({ embeds: [embed] }); return; @@ -66,7 +66,7 @@ export const InfoCmd = utilityCmd({ if (userCfg.can_userinfo) { const user = await resolveUser(pluginData.client, value); if (user && userCfg.can_userinfo) { - const embed = await getUserInfoEmbed(pluginData, user.id, Boolean(args.compact), message.author.id); + const embed = await getUserInfoEmbed(pluginData, user.id, Boolean(args.compact)); if (embed) { message.channel.send({ embeds: [embed] }); return; @@ -79,12 +79,7 @@ export const InfoCmd = utilityCmd({ const messageTarget = await resolveMessageTarget(pluginData, value); if (messageTarget) { if (canReadChannel(messageTarget.channel, message.member)) { - const embed = await getMessageInfoEmbed( - pluginData, - messageTarget.channel.id, - messageTarget.messageId, - message.author.id, - ); + const embed = await getMessageInfoEmbed(pluginData, messageTarget.channel.id, messageTarget.messageId); if (embed) { message.channel.send({ embeds: [embed] }); return; @@ -112,7 +107,7 @@ export const InfoCmd = utilityCmd({ if (userCfg.can_server) { const serverPreview = await getGuildPreview(pluginData.client, value).catch(() => null); if (serverPreview) { - const embed = await getServerInfoEmbed(pluginData, value, message.author.id); + const embed = await getServerInfoEmbed(pluginData, value); if (embed) { message.channel.send({ embeds: [embed] }); return; @@ -125,7 +120,7 @@ export const InfoCmd = utilityCmd({ const roleId = getRoleId(value); const role = roleId && pluginData.guild.roles.cache.get(roleId as Snowflake); if (role) { - const embed = await getRoleInfoEmbed(pluginData, role, message.author.id); + const embed = await getRoleInfoEmbed(pluginData, role); message.channel.send({ embeds: [embed] }); return; } @@ -145,16 +140,17 @@ export const InfoCmd = utilityCmd({ // 9. Arbitrary ID if (isValidSnowflake(value) && userCfg.can_snowflake) { - const embed = await getSnowflakeInfoEmbed(pluginData, value, true, message.author.id); + const embed = await getSnowflakeInfoEmbed(value, true); message.channel.send({ embeds: [embed] }); return; } // 10. No can do - sendErrorMessage( - pluginData, - message.channel, - "Could not find anything with that value or you are lacking permission for the snowflake type", - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage( + message, + "Could not find anything with that value or you are lacking permission for the snowflake type", + ); }, }); diff --git a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts index df34123a..262ab94a 100644 --- a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { parseInviteCodeInput } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { getInviteInfoEmbed } from "../functions/getInviteInfoEmbed"; import { utilityCmd } from "../types"; @@ -18,7 +18,7 @@ export const InviteInfoCmd = utilityCmd({ const inviteCode = parseInviteCodeInput(args.inviteCode); const embed = await getInviteInfoEmbed(pluginData, inviteCode); if (!embed) { - sendErrorMessage(pluginData, message.channel, "Unknown invite"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown invite"); return; } diff --git a/backend/src/plugins/Utility/commands/JumboCmd.ts b/backend/src/plugins/Utility/commands/JumboCmd.ts index 3dd1d30a..a8cf8678 100644 --- a/backend/src/plugins/Utility/commands/JumboCmd.ts +++ b/backend/src/plugins/Utility/commands/JumboCmd.ts @@ -3,8 +3,8 @@ import { AttachmentBuilder } from "discord.js"; import fs from "fs"; import twemoji from "twemoji"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { downloadFile, isEmoji, SECONDS } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { utilityCmd } from "../types"; const fsp = fs.promises; @@ -51,7 +51,7 @@ export const JumboCmd = utilityCmd({ let file: AttachmentBuilder | undefined; if (!isEmoji(args.emoji)) { - sendErrorMessage(pluginData, msg.channel, "Invalid emoji"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid emoji"); return; } @@ -87,7 +87,7 @@ export const JumboCmd = utilityCmd({ } } if (!image) { - sendErrorMessage(pluginData, msg.channel, "Error occurred while jumboing default emoji"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Error occurred while jumboing default emoji"); return; } diff --git a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts index 82096250..88df8eff 100644 --- a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { canReadChannel } from "../../../utils/canReadChannel"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { getMessageInfoEmbed } from "../functions/getMessageInfoEmbed"; import { utilityCmd } from "../types"; @@ -16,18 +16,13 @@ export const MessageInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { if (!canReadChannel(args.message.channel, message.member)) { - sendErrorMessage(pluginData, message.channel, "Unknown message"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown message"); return; } - const embed = await getMessageInfoEmbed( - pluginData, - args.message.channel.id, - args.message.messageId, - message.author.id, - ); + const embed = await getMessageInfoEmbed(pluginData, args.message.channel.id, args.message.messageId); if (!embed) { - sendErrorMessage(pluginData, message.channel, "Unknown message"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown message"); return; } diff --git a/backend/src/plugins/Utility/commands/NicknameCmd.ts b/backend/src/plugins/Utility/commands/NicknameCmd.ts index 9821ef32..63d5eac8 100644 --- a/backend/src/plugins/Utility/commands/NicknameCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameCmd.ts @@ -1,7 +1,8 @@ import { escapeBold } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendSuccessMessage } from "../../../pluginUtils"; +import { canActOn } from "../../../pluginUtils"; import { errorMessage } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { utilityCmd } from "../types"; export const NicknameCmd = utilityCmd({ @@ -45,10 +46,11 @@ export const NicknameCmd = utilityCmd({ return; } - sendSuccessMessage( - pluginData, - msg.channel, - `Changed nickname of <@!${args.member.id}> from **${oldNickname}** to **${args.nickname}**`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + msg, + `Changed nickname of <@!${args.member.id}> from **${oldNickname}** to **${args.nickname}**`, + ); }, }); diff --git a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts index f86a33c9..61417419 100644 --- a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts @@ -1,6 +1,7 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendSuccessMessage } from "../../../pluginUtils"; +import { canActOn } from "../../../pluginUtils"; import { errorMessage } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { utilityCmd } from "../types"; export const NicknameResetCmd = utilityCmd({ @@ -31,6 +32,6 @@ export const NicknameResetCmd = utilityCmd({ return; } - sendSuccessMessage(pluginData, msg.channel, `The nickname of <@!${args.member.id}> has been reset`); + pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `The nickname of <@!${args.member.id}> has been reset`); }, }); diff --git a/backend/src/plugins/Utility/commands/RoleInfoCmd.ts b/backend/src/plugins/Utility/commands/RoleInfoCmd.ts index b04b49a7..6f540b4b 100644 --- a/backend/src/plugins/Utility/commands/RoleInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/RoleInfoCmd.ts @@ -13,7 +13,7 @@ export const RoleInfoCmd = utilityCmd({ }, async run({ message, args, pluginData }) { - const embed = await getRoleInfoEmbed(pluginData, args.role, message.author.id); + const embed = await getRoleInfoEmbed(pluginData, args.role); message.channel.send({ embeds: [embed] }); }, }); diff --git a/backend/src/plugins/Utility/commands/RolesCmd.ts b/backend/src/plugins/Utility/commands/RolesCmd.ts index 86c09554..d04903f9 100644 --- a/backend/src/plugins/Utility/commands/RolesCmd.ts +++ b/backend/src/plugins/Utility/commands/RolesCmd.ts @@ -1,7 +1,7 @@ import { Role } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; import { chunkArray, sorter, trimLines } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { refreshMembersIfNeeded } from "../refreshMembers"; import { utilityCmd } from "../types"; @@ -62,7 +62,7 @@ export const RolesCmd = utilityCmd({ } else if (sort === "name") { roles.sort(sorter((r) => r.name.toLowerCase(), sortDir)); } else { - sendErrorMessage(pluginData, msg.channel, "Unknown sorting method"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown sorting method"); return; } diff --git a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts index 30fb7efe..2e5d7ba5 100644 --- a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { getServerInfoEmbed } from "../functions/getServerInfoEmbed"; import { utilityCmd } from "../types"; @@ -15,9 +15,9 @@ export const ServerInfoCmd = utilityCmd({ async run({ message, pluginData, args }) { const serverId = args.serverId || pluginData.guild.id; - const serverInfoEmbed = await getServerInfoEmbed(pluginData, serverId, message.author.id); + const serverInfoEmbed = await getServerInfoEmbed(pluginData, serverId); if (!serverInfoEmbed) { - sendErrorMessage(pluginData, message.channel, "Could not find information for that server"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Could not find information for that server"); return; } diff --git a/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts b/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts index 59f43893..bf0e859f 100644 --- a/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts @@ -12,8 +12,8 @@ export const SnowflakeInfoCmd = utilityCmd({ id: ct.anyId(), }, - async run({ message, args, pluginData }) { - const embed = await getSnowflakeInfoEmbed(pluginData, args.id, false, message.author.id); + async run({ message, args }) { + const embed = await getSnowflakeInfoEmbed(args.id, false); message.channel.send({ embeds: [embed] }); }, }); diff --git a/backend/src/plugins/Utility/commands/SourceCmd.ts b/backend/src/plugins/Utility/commands/SourceCmd.ts index 54c24647..be3a4bab 100644 --- a/backend/src/plugins/Utility/commands/SourceCmd.ts +++ b/backend/src/plugins/Utility/commands/SourceCmd.ts @@ -1,7 +1,8 @@ import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getBaseUrl, sendErrorMessage } from "../../../pluginUtils"; +import { getBaseUrl } from "../../../pluginUtils"; import { canReadChannel } from "../../../utils/canReadChannel"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { utilityCmd } from "../types"; export const SourceCmd = utilityCmd({ @@ -16,13 +17,13 @@ export const SourceCmd = utilityCmd({ async run({ message: cmdMessage, args, pluginData }) { if (!canReadChannel(args.message.channel, cmdMessage.member)) { - sendErrorMessage(pluginData, cmdMessage.channel, "Unknown message"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(cmdMessage, "Unknown message"); return; } const message = await args.message.channel.messages.fetch(args.message.messageId); if (!message) { - sendErrorMessage(pluginData, cmdMessage.channel, "Unknown message"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(cmdMessage, "Unknown message"); return; } diff --git a/backend/src/plugins/Utility/commands/UserInfoCmd.ts b/backend/src/plugins/Utility/commands/UserInfoCmd.ts index c7ce8b48..6ba99548 100644 --- a/backend/src/plugins/Utility/commands/UserInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/UserInfoCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sendErrorMessage } from "../../../pluginUtils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { getUserInfoEmbed } from "../functions/getUserInfoEmbed"; import { utilityCmd } from "../types"; @@ -17,9 +17,9 @@ export const UserInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { const userId = args.user?.id || message.author.id; - const embed = await getUserInfoEmbed(pluginData, userId, args.compact, message.author.id); + const embed = await getUserInfoEmbed(pluginData, userId, args.compact); if (!embed) { - sendErrorMessage(pluginData, message.channel, "User not found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "User not found"); return; } diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index 0f82458a..f5bdf43c 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -1,7 +1,8 @@ import { VoiceChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { canActOn } from "../../../pluginUtils"; import { renderUserUsername } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { utilityCmd } from "../types"; @@ -17,12 +18,12 @@ export const VcdisconnectCmd = utilityCmd({ async run({ message: msg, args, pluginData }) { if (!canActOn(pluginData, msg.member, args.member)) { - sendErrorMessage(pluginData, msg.channel, "Cannot move: insufficient permissions"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot move: insufficient permissions"); return; } if (!args.member.voice?.channelId) { - sendErrorMessage(pluginData, msg.channel, "Member is not in a voice channel"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member is not in a voice channel"); return; } const channel = pluginData.guild.channels.cache.get(args.member.voice.channelId) as VoiceChannel; @@ -30,7 +31,7 @@ export const VcdisconnectCmd = utilityCmd({ try { await args.member.voice.disconnect(); } catch { - sendErrorMessage(pluginData, msg.channel, "Failed to disconnect member"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Failed to disconnect member"); return; } @@ -40,10 +41,8 @@ export const VcdisconnectCmd = utilityCmd({ oldChannel: channel, }); - sendSuccessMessage( - pluginData, - msg.channel, - `**${renderUserUsername(args.member.user)}** disconnected from **${channel.name}**`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `**${renderUserUsername(args.member.user)}** disconnected from **${channel.name}**`); }, }); diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index db00161e..ba9e998d 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -1,7 +1,8 @@ import { ChannelType, Snowflake, VoiceChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; +import { canActOn } from "../../../pluginUtils"; import { channelMentionRegex, isSnowflake, renderUserUsername, simpleClosestStringMatch } from "../../../utils"; +import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { utilityCmd } from "../types"; @@ -23,7 +24,7 @@ export const VcmoveCmd = utilityCmd({ // Snowflake -> resolve channel directly const potentialChannel = pluginData.guild.channels.cache.get(args.channel as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { - sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown or non-voice channel"); return; } @@ -33,7 +34,7 @@ export const VcmoveCmd = utilityCmd({ const channelId = args.channel.match(channelMentionRegex)![1]; const potentialChannel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { - sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown or non-voice channel"); return; } @@ -45,7 +46,7 @@ export const VcmoveCmd = utilityCmd({ ); const closestMatch = simpleClosestStringMatch(args.channel, voiceChannels, (ch) => ch.name); if (!closestMatch) { - sendErrorMessage(pluginData, msg.channel, "No matching voice channels"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No matching voice channels"); return; } @@ -53,12 +54,12 @@ export const VcmoveCmd = utilityCmd({ } if (!args.member.voice?.channelId) { - sendErrorMessage(pluginData, msg.channel, "Member is not in a voice channel"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member is not in a voice channel"); return; } if (args.member.voice.channelId === channel.id) { - sendErrorMessage(pluginData, msg.channel, "Member is already on that channel!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member is already on that channel!"); return; } @@ -69,7 +70,7 @@ export const VcmoveCmd = utilityCmd({ channel: channel.id, }); } catch { - sendErrorMessage(pluginData, msg.channel, "Failed to move member"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Failed to move member"); return; } @@ -80,11 +81,9 @@ export const VcmoveCmd = utilityCmd({ newChannel: channel, }); - sendSuccessMessage( - pluginData, - msg.channel, - `**${renderUserUsername(args.member.user)}** moved to **${channel.name}**`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage(msg, `**${renderUserUsername(args.member.user)}** moved to **${channel.name}**`); }, }); @@ -106,7 +105,7 @@ export const VcmoveAllCmd = utilityCmd({ // Snowflake -> resolve channel directly const potentialChannel = pluginData.guild.channels.cache.get(args.channel as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { - sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown or non-voice channel"); return; } @@ -116,7 +115,7 @@ export const VcmoveAllCmd = utilityCmd({ const channelId = args.channel.match(channelMentionRegex)![1]; const potentialChannel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { - sendErrorMessage(pluginData, msg.channel, "Unknown or non-voice channel"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown or non-voice channel"); return; } @@ -128,7 +127,7 @@ export const VcmoveAllCmd = utilityCmd({ ); const closestMatch = simpleClosestStringMatch(args.channel, voiceChannels, (ch) => ch.name); if (!closestMatch) { - sendErrorMessage(pluginData, msg.channel, "No matching voice channels"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No matching voice channels"); return; } @@ -136,12 +135,12 @@ export const VcmoveAllCmd = utilityCmd({ } if (args.oldChannel.members.size === 0) { - sendErrorMessage(pluginData, msg.channel, "Voice channel is empty"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Voice channel is empty"); return; } if (args.oldChannel.id === channel.id) { - sendErrorMessage(pluginData, msg.channel, "Cant move from and to the same channel!"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cant move from and to the same channel!"); return; } @@ -154,11 +153,12 @@ export const VcmoveAllCmd = utilityCmd({ // Check for permissions but allow self-moves if (currMember.id !== msg.member.id && !canActOn(pluginData, msg.member, currMember)) { - sendErrorMessage( - pluginData, - msg.channel, - `Failed to move ${renderUserUsername(currMember.user)} (${currMember.id}): You cannot act on this member`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage( + msg, + `Failed to move ${renderUserUsername(currMember.user)} (${currMember.id}): You cannot act on this member`, + ); errAmt++; continue; } @@ -169,14 +169,12 @@ export const VcmoveAllCmd = utilityCmd({ }); } catch { if (msg.member.id === currMember.id) { - sendErrorMessage(pluginData, msg.channel, "Unknown error when trying to move members"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown error when trying to move members"); return; } - sendErrorMessage( - pluginData, - msg.channel, - `Failed to move ${renderUserUsername(currMember.user)} (${currMember.id})`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(msg, `Failed to move ${renderUserUsername(currMember.user)} (${currMember.id})`); errAmt++; continue; } @@ -190,13 +188,14 @@ export const VcmoveAllCmd = utilityCmd({ } if (moveAmt !== errAmt) { - sendSuccessMessage( - pluginData, - msg.channel, - `${moveAmt - errAmt} members from **${args.oldChannel.name}** moved to **${channel.name}**`, - ); + pluginData + .getPlugin(CommonPlugin) + .sendSuccessMessage( + msg, + `${moveAmt - errAmt} members from **${args.oldChannel.name}** moved to **${channel.name}**`, + ); } else { - sendErrorMessage(pluginData, msg.channel, `Failed to move any members.`); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Failed to move any members.`); } }, }); diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index ee006f5f..33a04b8e 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -22,7 +22,6 @@ const FORUM_CHANNEL_ICON = export async function getChannelInfoEmbed( pluginData: GuildPluginData, channelId: string, - requestMemberId?: string, ): Promise { const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!channel) { diff --git a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts index 1568a3e3..4b615cf0 100644 --- a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts @@ -9,7 +9,6 @@ import { trimEmptyLines, trimLines, } from "../../../utils"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; const MESSAGE_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/740685652152025088/message.png"; @@ -18,7 +17,6 @@ export async function getMessageInfoEmbed( pluginData: GuildPluginData, channelId: string, messageId: string, - requestMemberId?: string, ): Promise { const message = await (pluginData.guild.channels.resolve(channelId as Snowflake) as TextChannel).messages .fetch(messageId as Snowflake) @@ -27,8 +25,6 @@ export async function getMessageInfoEmbed( return null; } - const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); - const embed: EmbedWith<"fields" | "author"> = { fields: [], author: { diff --git a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts index fa3188ec..dd19d9b2 100644 --- a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts @@ -6,11 +6,7 @@ import { UtilityPluginType } from "../types"; const MENTION_ICON = "https://cdn.discordapp.com/attachments/705009450855039042/839284872152481792/mention.png"; -export async function getRoleInfoEmbed( - pluginData: GuildPluginData, - role: Role, - requestMemberId?: string, -): Promise { +export async function getRoleInfoEmbed(pluginData: GuildPluginData, role: Role): Promise { const embed: EmbedWith<"fields" | "author" | "color"> = { fields: [], author: { diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index d0202db7..bbd1f78f 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -25,7 +25,6 @@ const prettifyFeature = (feature: string): string => export async function getServerInfoEmbed( pluginData: GuildPluginData, serverId: string, - requestMemberId?: string, ): Promise { const thisServer = serverId === pluginData.guild.id ? pluginData.guild : null; const [restGuild, guildPreview] = await Promise.all([ diff --git a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts index ef676fd1..8449ba74 100644 --- a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts @@ -1,17 +1,10 @@ import { APIEmbed } from "discord.js"; -import { GuildPluginData } from "knub"; import { EmbedWith, preEmbedPadding } from "../../../utils"; import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp"; -import { UtilityPluginType } from "../types"; const SNOWFLAKE_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/742020790471491668/snowflake.png"; -export async function getSnowflakeInfoEmbed( - pluginData: GuildPluginData, - snowflake: string, - showUnknownWarning = false, - requestMemberId?: string, -): Promise { +export async function getSnowflakeInfoEmbed(snowflake: string, showUnknownWarning = false): Promise { const embed: EmbedWith<"fields" | "author"> = { fields: [], author: { diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts index ef8d2320..b568a833 100644 --- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts @@ -13,7 +13,6 @@ import { trimLines, UnknownUser, } from "../../../utils"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { UtilityPluginType } from "../types"; const MAX_ROLES_TO_DISPLAY = 15; @@ -27,7 +26,6 @@ export async function getUserInfoEmbed( pluginData: GuildPluginData, userId: string, compact = false, - requestMemberId?: string, ): Promise { const user = await resolveUser(pluginData.client, userId); if (!user || user instanceof UnknownUser) { @@ -40,8 +38,6 @@ export async function getUserInfoEmbed( fields: [], }; - const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); - embed.author = { name: `${user.bot ? "Bot" : "User"}: ${renderUsername(user.username, user.discriminator)}`, }; diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 19710b58..07e3477d 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -13,11 +13,12 @@ import escapeStringRegexp from "escape-string-regexp"; import { ArgsFromSignatureOrArray, GuildPluginData } from "knub"; import moment from "moment-timezone"; import { RegExpRunner, allowTimeout } from "../../RegExpRunner"; -import { getBaseUrl, sendErrorMessage } from "../../pluginUtils"; +import { getBaseUrl } from "../../pluginUtils"; import { MINUTES, multiSorter, renderUserUsername, sorter, trimLines } from "../../utils"; import { asyncFilter } from "../../utils/async"; import { hasDiscordPermissions } from "../../utils/hasDiscordPermissions"; import { InvalidRegexError, inputPatternToRegExp } from "../../validatorUtils"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { banSearchSignature } from "./commands/BanSearchCmd"; import { searchCmdSignature } from "./commands/SearchCmd"; import { getUserInfoEmbed } from "./functions/getUserInfoEmbed"; @@ -115,12 +116,12 @@ export async function displaySearch( } } catch (e) { if (e instanceof SearchError) { - sendErrorMessage(pluginData, msg.channel, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); return; } if (e instanceof InvalidRegexError) { - sendErrorMessage(pluginData, msg.channel, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); return; } @@ -128,7 +129,7 @@ export async function displaySearch( } if (searchResult.totalResults === 0) { - sendErrorMessage(pluginData, msg.channel, "No results found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No results found"); return; } @@ -259,12 +260,12 @@ export async function archiveSearch( } } catch (e) { if (e instanceof SearchError) { - sendErrorMessage(pluginData, msg.channel, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); return; } if (e instanceof InvalidRegexError) { - sendErrorMessage(pluginData, msg.channel, e.message); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); return; } @@ -272,7 +273,7 @@ export async function archiveSearch( } if (results.totalResults === 0) { - sendErrorMessage(pluginData, msg.channel, "No results found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No results found"); return; } diff --git a/backend/src/plugins/availablePlugins.ts b/backend/src/plugins/availablePlugins.ts index 45119f0f..61597215 100644 --- a/backend/src/plugins/availablePlugins.ts +++ b/backend/src/plugins/availablePlugins.ts @@ -5,6 +5,7 @@ import { BotControlPlugin } from "./BotControl/BotControlPlugin"; import { CasesPlugin } from "./Cases/CasesPlugin"; import { CensorPlugin } from "./Censor/CensorPlugin"; import { ChannelArchiverPlugin } from "./ChannelArchiver/ChannelArchiverPlugin"; +import { CommonPlugin } from "./Common/CommonPlugin"; import { CompanionChannelsPlugin } from "./CompanionChannels/CompanionChannelsPlugin"; import { ContextMenuPlugin } from "./ContextMenus/ContextMenuPlugin"; import { CountersPlugin } from "./Counters/CountersPlugin"; @@ -78,6 +79,7 @@ export const guildPlugins: Array> = [ InternalPosterPlugin, RoleManagerPlugin, RoleButtonsPlugin, + CommonPlugin, ]; // prettier-ignore @@ -96,5 +98,6 @@ export const baseGuildPlugins: Array> = [ CasesPlugin, MutesPlugin, TimeAndDatePlugin, + CommonPlugin, // TODO: Replace these with proper dependencies ]; diff --git a/backend/src/utils.ts b/backend/src/utils.ts index c6c705db..61938019 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -1,6 +1,7 @@ import { APIEmbed, ChannelType, + ChatInputCommandInteraction, Client, DiscordAPIError, EmbedData, @@ -1409,11 +1410,11 @@ export async function resolveStickerId(bot: Client, id: Snowflake): Promise { - return waitForButtonConfirm(channel, content, { restrictToId: userId }); + return waitForButtonConfirm(context, content, { restrictToId: userId }); } export function messageSummary(msg: SavedMessage) { diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index d1075499..e1be4ea4 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -7,7 +7,6 @@ import { MessageReaction, PartialMessageReaction, PartialUser, - TextBasedChannel, User, } from "discord.js"; import { sendContextResponse } from "../pluginUtils"; @@ -29,7 +28,7 @@ const defaultOpts: PaginateMessageOpts = { export async function createPaginatedMessage( client: Client, - context: TextBasedChannel | User | ChatInputCommandInteraction, + context: Message | User | ChatInputCommandInteraction, totalPages: number, loadPageFn: LoadPageFn, opts: Partial = {}, diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index 64cab738..c2cc659b 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -3,10 +3,10 @@ import { ButtonBuilder, ButtonStyle, ChatInputCommandInteraction, + Message, MessageActionRowComponentBuilder, MessageComponentInteraction, MessageCreateOptions, - TextBasedChannel, User, } from "discord.js"; import moment from "moment"; @@ -15,8 +15,8 @@ import { isContextInteraction } from "../pluginUtils"; import { noop } from "../utils"; export async function waitForButtonConfirm( - context: TextBasedChannel | User | ChatInputCommandInteraction, - toPost: MessageCreateOptions, + context: Message | User | ChatInputCommandInteraction, + toPost: Omit, options?: WaitForOptions, ): Promise { return new Promise(async (resolve) => { @@ -33,9 +33,17 @@ export async function waitForButtonConfirm( .setLabel(options?.cancelText || "Cancel") .setCustomId(`cancelButton:${idMod}:${uuidv4()}`), ]); - const sendMethod = contextIsInteraction ? (context.replied ? "followUp" : "reply") : "send"; + const sendMethod = () => { + return contextIsInteraction + ? context.replied + ? context.followUp + : context.reply + : "send" in context + ? context.send + : context.channel.send; + }; const extraParameters = contextIsInteraction ? { fetchReply: true } : {}; - const message = await context[sendMethod]({ ...toPost, components: [row], ...extraParameters }); + const message = await sendMethod()({ ...toPost, components: [row], ...extraParameters }); const collector = message.createMessageComponentCollector({ time: 10000 }); diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index cf8fc8d3..e68d6930 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -3629,9 +3629,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001507", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001507.tgz", - "integrity": "sha512-SFpUDoSLCaE5XYL2jfqe9ova/pbQHEmbheDf5r4diNwbAgR3qxM9NQtfsiSscjqoya5K7kFcHPUQ+VsUkIJR4A==", + "version": "1.0.30001587", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", + "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==", "dev": true, "funding": [ { From cafcc2839ea572d0681ad16d498eaaa897742b8a Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Sat, 17 Feb 2024 18:16:53 +0100 Subject: [PATCH 13/30] Various fixes --- backend/src/configValidator.ts | 14 +++----------- backend/src/plugins/Common/CommonPlugin.ts | 2 +- .../src/plugins/ContextMenus/actions/mute.ts | 1 - .../commands/cases/CasesModMsgCmd.ts | 2 +- .../commands/cases/CasesSlashCmd.ts | 2 +- .../commands/cases/CasesUserMsgCmd.ts | 2 +- .../ModActions/commands/warn/WarnMsgCmd.ts | 10 +++++----- .../ModActions/commands/warn/WarnSlashCmd.ts | 12 ++++++------ .../actualCommands/actualCasesCmd.ts | 14 +++++++------- .../actualCommands/actualMassUnbanCmd.ts | 5 +++-- .../functions/actualCommands/actualWarnCmd.ts | 9 ++++++--- .../ModActions/functions/updateCase.ts | 5 +++++ .../ModActions/functions/warnMember.ts | 8 +------- backend/src/types.ts | 19 +------------------ backend/src/utils/waitForInteraction.ts | 8 ++++---- 15 files changed, 45 insertions(+), 68 deletions(-) diff --git a/backend/src/configValidator.ts b/backend/src/configValidator.ts index eb115d46..b2e2fc55 100644 --- a/backend/src/configValidator.ts +++ b/backend/src/configValidator.ts @@ -1,9 +1,8 @@ -import { ConfigValidationError, PluginConfigManager } from "knub"; -import moment from "moment-timezone"; +import { BaseConfig, ConfigValidationError, PluginConfigManager } from "knub"; import { ZodError } from "zod"; import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin"; import { guildPlugins } from "./plugins/availablePlugins"; -import { ZeppelinGuildConfig, zZeppelinGuildConfig } from "./types"; +import { zZeppelinGuildConfig } from "./types"; import { formatZodIssue } from "./utils/formatZodIssue"; const pluginNameToPlugin = new Map(); @@ -17,14 +16,7 @@ export async function validateGuildConfig(config: any): Promise { return validationResult.error.issues.map(formatZodIssue).join("\n"); } - const guildConfig = config as ZeppelinGuildConfig; - - if (guildConfig.timezone) { - const validTimezones = moment.tz.names(); - if (!validTimezones.includes(guildConfig.timezone)) { - return `Invalid timezone: ${guildConfig.timezone}`; - } - } + const guildConfig = config as BaseConfig; if (guildConfig.plugins) { for (const [pluginName, pluginOptions] of Object.entries(guildConfig.plugins)) { diff --git a/backend/src/plugins/Common/CommonPlugin.ts b/backend/src/plugins/Common/CommonPlugin.ts index 9f4a6d82..62ee3628 100644 --- a/backend/src/plugins/Common/CommonPlugin.ts +++ b/backend/src/plugins/Common/CommonPlugin.ts @@ -98,7 +98,7 @@ export const CommonPlugin = zeppelinGuildPlugin()({ body: string, allowedMentions?: MessageMentionOptions, responseInteraction?: ModalSubmitInteraction, - ephemeral = false, + ephemeral = true, ): Promise => { const emoji = getErrorEmoji(pluginData); const formattedBody = errorMessage(body, emoji); diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index 9861a1d2..6e69b16f 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -69,7 +69,6 @@ async function muteAction( try { const result = await mutes.muteUser(target, durationMs, reason, reason, { caseArgs }); - const messageResultText = result.notifyResult.text ? ` (${result.notifyResult.text})` : ""; const muteMessage = `Muted **${result.case!.user_name}** ${ durationMs ? `for ${humanizeDuration(durationMs)}` : "indefinitely" diff --git a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts index 717ea531..debeff45 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts @@ -32,7 +32,7 @@ export const CasesModMsgCmd = modActionsMsgCmd({ msg, args.mod, null, - msg.author, + msg.member, args.notes, args.warns, args.mutes, diff --git a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts index 5207d76f..7833cfab 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts @@ -33,7 +33,7 @@ export const CasesSlashCmd = { interaction, options.mod, options.user, - interaction.user, + interaction.member, options.notes, options.warns, options.mutes, diff --git a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts index 967ae160..5640080d 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts @@ -45,7 +45,7 @@ export const CasesUserMsgCmd = modActionsMsgCmd({ msg, args.mod, user, - msg.author, + msg.member, args.notes, args.warns, args.mutes, diff --git a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts index cd8533b6..d6175356 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts @@ -24,7 +24,7 @@ export const WarnMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); return; } @@ -33,9 +33,9 @@ export const WarnMsgCmd = modActionsMsgCmd({ if (!memberToWarn) { const _isBanned = await isBanned(pluginData, user.id); if (_isBanned) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User is banned`); + await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User is banned`); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found on the server`); + await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found on the server`); } return; @@ -43,7 +43,7 @@ export const WarnMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to warn this member if (!canActOn(pluginData, msg.member, memberToWarn)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot warn: insufficient permissions"); + await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot warn: insufficient permissions"); return; } @@ -62,7 +62,7 @@ export const WarnMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts index c34e91e0..43f796f2 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts @@ -45,7 +45,7 @@ export const WarnSlashCmd = { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData + await pluginData .getPlugin(CommonPlugin) .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); @@ -57,9 +57,9 @@ export const WarnSlashCmd = { if (!memberToWarn) { const _isBanned = await isBanned(pluginData, options.user.id); if (_isBanned) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `User is banned`); + await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `User is banned`); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `User not found on the server`); + await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `User not found on the server`); } return; @@ -67,7 +67,7 @@ export const WarnSlashCmd = { // Make sure we're allowed to warn this member if (!canActOn(pluginData, interaction.member, memberToWarn)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot warn: insufficient permissions"); + await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot warn: insufficient permissions"); return; } @@ -79,7 +79,7 @@ export const WarnSlashCmd = { if (options.mod) { if (!canActAsOther) { - pluginData + await pluginData .getPlugin(CommonPlugin) .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; @@ -92,7 +92,7 @@ export const WarnSlashCmd = { try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); + await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts index 1ad7b813..ae92affa 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts @@ -145,9 +145,9 @@ async function casesModCmd( expand: boolean | null, ) { const casesPlugin = pluginData.getPlugin(CasesPlugin); - const caseFilters = { type: In(typesToShow), is_hidden: !!hidden }; + const casesFilters = { type: In(typesToShow), is_hidden: !!hidden }; - const totalCases = await casesPlugin.getTotalCasesByMod(modId ?? author.id, caseFilters); + const totalCases = await casesPlugin.getTotalCasesByMod(modId ?? author.id, casesFilters); if (totalCases === 0) { pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `No cases by **${modName}**`); @@ -159,7 +159,7 @@ async function casesModCmd( if (expand) { // Expanded view (= individual case embeds) - const cases = totalCases > 8 ? [] : await casesPlugin.getRecentCasesByMod(modId ?? author.id, 8, 0, caseFilters); + const cases = totalCases > 8 ? [] : await casesPlugin.getRecentCasesByMod(modId ?? author.id, 8, 0, casesFilters); sendExpandedCases(pluginData, context, totalCases, cases); return; @@ -174,7 +174,7 @@ async function casesModCmd( modId ?? author.id, casesPerPage, (page - 1) * casesPerPage, - caseFilters, + casesFilters, ); const lines = await asyncMap(cases, (c) => casesPlugin.getCaseSummary(c, true, author.id)); @@ -212,7 +212,7 @@ export async function actualCasesCmd( context: Message | ChatInputCommandInteraction, modId: string | null, user: GuildMember | User | UnknownUser | null, - author: User, + author: GuildMember, notes: boolean | null, warns: boolean | null, mutes: boolean | null, @@ -253,6 +253,6 @@ export async function actualCasesCmd( } user - ? casesUserCmd(pluginData, context, author, modId!, user, modName, typesToShow, hidden, expand) - : casesModCmd(pluginData, context, author, modId!, mod!, modName, typesToShow, hidden, expand); + ? casesUserCmd(pluginData, context, author.user, modId!, user, modName, typesToShow, hidden, expand) + : casesModCmd(pluginData, context, author.user, modId!, mod ?? author, modName, typesToShow, hidden, expand); } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts index bfb57111..a980445c 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts @@ -4,6 +4,7 @@ import { waitForReply } from "knub/helpers"; import { CaseTypes } from "../../../../data/CaseTypes"; import { LogType } from "../../../../data/LogType"; import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; +import { MINUTES } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; @@ -45,8 +46,8 @@ export async function actualMassUnbanCmd( // We'll create our own cases below and post a single "mass unbanned" log instead userIds.forEach((userId) => { // Use longer timeouts since this can take a while - ignoreEvent(pluginData, IgnoredEventType.Unban, userId, 120 * 1000); - pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, userId, 120 * 1000); + ignoreEvent(pluginData, IgnoredEventType.Unban, userId, 2 * MINUTES); + pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, userId, 2 * MINUTES); }); // Show a loading indicator since this can take a while diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts index 15a54cfe..ac43d8df 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts @@ -37,7 +37,7 @@ export async function actualWarnCmd( { confirmText: "Yes", cancelText: "No", restrictToId: authorId }, ); if (!reply) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Warn cancelled by moderator"); + await pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Warn cancelled by moderator"); return; } } @@ -53,13 +53,16 @@ export async function actualWarnCmd( }); if (warnResult.status === "failed") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Failed to warn user"); + const failReason = warnResult.error ? `: ${warnResult.error}` : ""; + + await pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Failed to warn user${failReason}`); + return; } const messageResultText = warnResult.notifyResult.text ? ` (${warnResult.notifyResult.text})` : ""; - pluginData + await pluginData .getPlugin(CommonPlugin) .sendSuccessMessage( context, diff --git a/backend/src/plugins/ModActions/functions/updateCase.ts b/backend/src/plugins/ModActions/functions/updateCase.ts index 78b5d6f4..08f11230 100644 --- a/backend/src/plugins/ModActions/functions/updateCase.ts +++ b/backend/src/plugins/ModActions/functions/updateCase.ts @@ -6,6 +6,7 @@ import { CasesPlugin } from "../../Cases/CasesPlugin"; import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../types"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "./attachmentLinkReaction"; import { formatReasonWithMessageLinkForAttachments } from "./formatReasonForAttachments"; export async function updateCase( @@ -33,6 +34,10 @@ export async function updateCase( return; } + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, note)) { + return; + } + const formattedNote = await formatReasonWithMessageLinkForAttachments(pluginData, note, context, attachments); const casesPlugin = pluginData.getPlugin(CasesPlugin); diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts index f87ce408..8ba8ee38 100644 --- a/backend/src/plugins/ModActions/functions/warnMember.ts +++ b/backend/src/plugins/ModActions/functions/warnMember.ts @@ -1,7 +1,6 @@ import { GuildMember, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; -import { getContextChannel, isContextInteraction } from "../../../pluginUtils"; import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; import { UserNotificationResult, createUserNotificationError, notifyUser, resolveUser, ucfirst } from "../../../utils"; import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; @@ -52,12 +51,7 @@ export async function warnMember( } if (!notifyResult.success) { - const contextIsNotInteraction = - warnOptions.retryPromptContext && !isContextInteraction(warnOptions.retryPromptContext); - const contextChannel = contextIsNotInteraction ? await getContextChannel(warnOptions.retryPromptContext!) : null; - const isValidChannel = contextIsNotInteraction && pluginData.guild.channels.resolve(contextChannel!.id); - - if (!warnOptions.retryPromptContext || !isValidChannel) { + if (!warnOptions.retryPromptContext) { return { status: "failed", error: "Failed to message user", diff --git a/backend/src/types.ts b/backend/src/types.ts index 409c4dc6..cf0967c3 100644 --- a/backend/src/types.ts +++ b/backend/src/types.ts @@ -1,29 +1,12 @@ -import { BaseConfig, Knub } from "knub"; +import { Knub } from "knub"; import z from "zod"; import { zSnowflake } from "./utils"; -export interface ZeppelinGuildConfig extends BaseConfig { - success_emoji?: string; - error_emoji?: string; - - // Deprecated - timezone?: string; - date_formats?: any; -} - export const zZeppelinGuildConfig = z.strictObject({ // From BaseConfig prefix: z.string().optional(), levels: z.record(zSnowflake, z.number()).optional(), plugins: z.record(z.string(), z.unknown()).optional(), - - // From ZeppelinGuildConfig - success_emoji: z.string().optional(), - error_emoji: z.string().optional(), - - // Deprecated - timezone: z.string().optional(), - date_formats: z.unknown().optional(), }); export type TZeppelinKnub = Knub; diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index c2cc659b..0cdd0437 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -36,11 +36,11 @@ export async function waitForButtonConfirm( const sendMethod = () => { return contextIsInteraction ? context.replied - ? context.followUp - : context.reply + ? context.followUp.bind(context) + : context.reply.bind(context) : "send" in context - ? context.send - : context.channel.send; + ? context.send.bind(context) + : context.channel.send.bind(context.channel); }; const extraParameters = contextIsInteraction ? { fetchReply: true } : {}; const message = await sendMethod()({ ...toPost, components: [row], ...extraParameters }); From b428e18fc7c88269b7d0cc84fe3001350888a77d Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Sat, 17 Feb 2024 22:06:02 +0100 Subject: [PATCH 14/30] Fixed config parsing error with tags --- backend/src/plugins/Tags/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/plugins/Tags/types.ts b/backend/src/plugins/Tags/types.ts index 5ff7e9c7..8b8b472b 100644 --- a/backend/src/plugins/Tags/types.ts +++ b/backend/src/plugins/Tags/types.ts @@ -4,9 +4,9 @@ import { GuildArchives } from "../../data/GuildArchives"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildTags } from "../../data/GuildTags"; -import { zEmbedInput } from "../../utils"; +import { zBoundedCharacters, zStrictMessageContent } from "../../utils"; -export const zTag = z.union([z.string(), zEmbedInput]); +export const zTag = z.union([zBoundedCharacters(0, 4000), zStrictMessageContent]); export type TTag = z.infer; export const zTagCategory = z From ba65ecb48f5fc80964aa29663f4194ccfb177990 Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Sat, 17 Feb 2024 23:57:01 +0100 Subject: [PATCH 15/30] Made cases commands ephemeral by default --- backend/src/pluginUtils.ts | 13 +++++---- .../ModActions/commands/case/CaseMsgCmd.ts | 8 ++++- .../ModActions/commands/case/CaseSlashCmd.ts | 8 ++++- .../commands/cases/CasesModMsgCmd.ts | 2 ++ .../commands/cases/CasesSlashCmd.ts | 2 ++ .../commands/cases/CasesUserMsgCmd.ts | 2 ++ .../functions/actualCommands/actualCaseCmd.ts | 3 +- .../actualCommands/actualCasesCmd.ts | 29 ++++++++++++++----- 8 files changed, 52 insertions(+), 15 deletions(-) diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index f84bf396..9e7f9783 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -5,6 +5,7 @@ import { ChatInputCommandInteraction, GuildMember, + InteractionReplyOptions, Message, MessageCreateOptions, PermissionsBitField, @@ -80,17 +81,19 @@ export async function getContextChannel( export async function sendContextResponse( context: TextBasedChannel | Message | User | ChatInputCommandInteraction, - response: string | Omit, + response: string | Omit | InteractionReplyOptions, ): Promise { if (isContextInteraction(context)) { const options = { ...(typeof response === "string" ? { content: response } : response), fetchReply: true }; return (context.replied ? context.followUp(options) : context.reply(options)) as Promise; - } else if ("send" in context) { - return context.send(response); - } else { - return (await getContextChannel(context)).send(response); } + + if (typeof response !== "string" && "ephemeral" in response) { + delete response.ephemeral; + } + + return (await getContextChannel(context)).send(response as string | Omit); } export function getBaseUrl(pluginData: AnyPluginData) { diff --git a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts index 914cec0f..4e278e23 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts @@ -2,6 +2,10 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { actualCaseCmd } from "../../functions/actualCommands/actualCaseCmd"; import { modActionsMsgCmd } from "../../types"; +const opts = { + show: ct.switchOption({ def: false, shortcut: "sh" }), +}; + export const CaseMsgCmd = modActionsMsgCmd({ trigger: "case", permission: "can_view", @@ -10,10 +14,12 @@ export const CaseMsgCmd = modActionsMsgCmd({ signature: [ { caseNumber: ct.number(), + + ...opts, }, ], async run({ pluginData, message: msg, args }) { - actualCaseCmd(pluginData, msg, msg.author.id, args.caseNumber); + actualCaseCmd(pluginData, msg, msg.author.id, args.caseNumber, args.show); }, }); diff --git a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts index c537ec6e..98219e3f 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts @@ -1,6 +1,10 @@ import { slashOptions } from "knub"; import { actualCaseCmd } from "../../functions/actualCommands/actualCaseCmd"; +const opts = [ + slashOptions.boolean({ name: "show", description: "To make the result visible to everyone", required: false }), +]; + export const CaseSlashCmd = { name: "case", configPermission: "can_view", @@ -9,9 +13,11 @@ export const CaseSlashCmd = { signature: [ slashOptions.number({ name: "case-number", description: "The number of the case to show", required: true }), + + ...opts, ], async run({ interaction, options, pluginData }) { - actualCaseCmd(pluginData, interaction, interaction.user.id, options["case-number"]); + actualCaseCmd(pluginData, interaction, interaction.user.id, options["case-number"], options.show); }, }; diff --git a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts index debeff45..0777e1cf 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts @@ -13,6 +13,7 @@ const opts = { unmutes: ct.switchOption({ def: false, shortcut: "um" }), bans: ct.switchOption({ def: false, shortcut: "b" }), unbans: ct.switchOption({ def: false, shortcut: "ub" }), + show: ct.switchOption({ def: false, shortcut: "sh" }), }; export const CasesModMsgCmd = modActionsMsgCmd({ @@ -42,6 +43,7 @@ export const CasesModMsgCmd = modActionsMsgCmd({ args.reverseFilters, args.hidden, args.expand, + args.show, ); }, }); diff --git a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts index 7833cfab..9d22d5d7 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts @@ -17,6 +17,7 @@ const opts = [ slashOptions.boolean({ name: "unmutes", description: "To filter unmutes", required: false }), slashOptions.boolean({ name: "bans", description: "To filter bans", required: false }), slashOptions.boolean({ name: "unbans", description: "To filter unbans", required: false }), + slashOptions.boolean({ name: "show", description: "To make the result visible to everyone", required: false }), ]; export const CasesSlashCmd = { @@ -43,6 +44,7 @@ export const CasesSlashCmd = { options["reverse-filters"], options.hidden, options.expand, + options.show, ); }, }; diff --git a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts index 5640080d..a185950e 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts @@ -15,6 +15,7 @@ const opts = { unmutes: ct.switchOption({ def: false, shortcut: "um" }), bans: ct.switchOption({ def: false, shortcut: "b" }), unbans: ct.switchOption({ def: false, shortcut: "ub" }), + show: ct.switchOption({ def: false, shortcut: "sh" }), }; export const CasesUserMsgCmd = modActionsMsgCmd({ @@ -55,6 +56,7 @@ export const CasesUserMsgCmd = modActionsMsgCmd({ args.reverseFilters, args.hidden, args.expand, + args.show, ); }, }); diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts index eabd8333..e45dc0e7 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts @@ -10,6 +10,7 @@ export async function actualCaseCmd( context: Message | ChatInputCommandInteraction, authorId: string, caseNumber: number, + show: boolean | null, ) { const theCase = await pluginData.state.cases.findByCaseNumber(caseNumber); @@ -21,5 +22,5 @@ export async function actualCaseCmd( const casesPlugin = pluginData.getPlugin(CasesPlugin); const embed = await casesPlugin.getCaseEmbed(theCase.id, authorId); - sendContextResponse(context, embed); + sendContextResponse(context, { ...embed, ephemeral: show !== true }); } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts index ae92affa..abe63cfa 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts @@ -29,6 +29,7 @@ async function sendExpandedCases( context: Message | ChatInputCommandInteraction, casesCount: number, cases: Case[], + show: boolean | null, ) { if (casesCount > maxExpandedCases) { await sendContextResponse(context, "Too many cases for expanded view. Please use compact view instead."); @@ -40,7 +41,7 @@ async function sendExpandedCases( for (const theCase of cases) { const embed = await casesPlugin.getCaseEmbed(theCase.id); - await sendContextResponse(context, embed); + await sendContextResponse(context, { ...embed, ephemeral: !show }); } } @@ -54,6 +55,7 @@ async function casesUserCmd( typesToShow: CaseTypes[], hidden: boolean | null, expand: boolean | null, + show: boolean | null, ) { const casesPlugin = pluginData.getPlugin(CasesPlugin); const casesFilters: Omit, "guild_id" | "user_id"> = { type: In(typesToShow) }; @@ -86,7 +88,7 @@ async function casesUserCmd( } if (expand) { - sendExpandedCases(pluginData, context, casesToDisplay.length, casesToDisplay); + sendExpandedCases(pluginData, context, casesToDisplay.length, casesToDisplay, show); return; } @@ -129,7 +131,7 @@ async function casesUserCmd( fields: [...(isLastChunk ? [footerField] : [])], } satisfies APIEmbed; - sendContextResponse(context, { embeds: [embed] }); + sendContextResponse(context, { embeds: [embed], ephemeral: !show }); } } @@ -143,6 +145,7 @@ async function casesModCmd( typesToShow: CaseTypes[], hidden: boolean | null, expand: boolean | null, + show: boolean | null, ) { const casesPlugin = pluginData.getPlugin(CasesPlugin); const casesFilters = { type: In(typesToShow), is_hidden: !!hidden }; @@ -161,7 +164,7 @@ async function casesModCmd( // Expanded view (= individual case embeds) const cases = totalCases > 8 ? [] : await casesPlugin.getRecentCasesByMod(modId ?? author.id, 8, 0, casesFilters); - sendExpandedCases(pluginData, context, totalCases, cases); + sendExpandedCases(pluginData, context, totalCases, cases, show); return; } @@ -199,7 +202,7 @@ async function casesModCmd( ], } satisfies APIEmbed; - return { embeds: [embed] }; + return { embeds: [embed], ephemeral: !show }; }, { limitToUserId: author.id, @@ -222,6 +225,7 @@ export async function actualCasesCmd( reverseFilters: boolean | null, hidden: boolean | null, expand: boolean | null, + show: boolean | null, ) { const mod = modId ? (await resolveMember(pluginData.client, pluginData.guild, modId)) || (await resolveUser(pluginData.client, modId)) @@ -253,6 +257,17 @@ export async function actualCasesCmd( } user - ? casesUserCmd(pluginData, context, author.user, modId!, user, modName, typesToShow, hidden, expand) - : casesModCmd(pluginData, context, author.user, modId!, mod ?? author, modName, typesToShow, hidden, expand); + ? casesUserCmd(pluginData, context, author.user, modId!, user, modName, typesToShow, hidden, expand, show === true) + : casesModCmd( + pluginData, + context, + author.user, + modId!, + mod ?? author, + modName, + typesToShow, + hidden, + expand, + show === true, + ); } From e4e7e1c6958276c323c948bcbce4a309cd9ba2ca Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Sun, 18 Feb 2024 01:23:25 +0100 Subject: [PATCH 16/30] Fixed race condition --- .../actualCommands/actualCasesCmd.ts | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts index abe63cfa..3248b20a 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts @@ -88,7 +88,7 @@ async function casesUserCmd( } if (expand) { - sendExpandedCases(pluginData, context, casesToDisplay.length, casesToDisplay, show); + await sendExpandedCases(pluginData, context, casesToDisplay.length, casesToDisplay, show); return; } @@ -131,7 +131,7 @@ async function casesUserCmd( fields: [...(isLastChunk ? [footerField] : [])], } satisfies APIEmbed; - sendContextResponse(context, { embeds: [embed], ephemeral: !show }); + await sendContextResponse(context, { embeds: [embed], ephemeral: !show }); } } @@ -164,11 +164,11 @@ async function casesModCmd( // Expanded view (= individual case embeds) const cases = totalCases > 8 ? [] : await casesPlugin.getRecentCasesByMod(modId ?? author.id, 8, 0, casesFilters); - sendExpandedCases(pluginData, context, totalCases, cases, show); + await sendExpandedCases(pluginData, context, totalCases, cases, show); return; } - createPaginatedMessage( + await createPaginatedMessage( pluginData.client, context, totalPages, @@ -257,8 +257,19 @@ export async function actualCasesCmd( } user - ? casesUserCmd(pluginData, context, author.user, modId!, user, modName, typesToShow, hidden, expand, show === true) - : casesModCmd( + ? await casesUserCmd( + pluginData, + context, + author.user, + modId!, + user, + modName, + typesToShow, + hidden, + expand, + show === true, + ) + : await casesModCmd( pluginData, context, author.user, From 0fee24e9731a7f3b72c60c8970b8cd1653456bee Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Sun, 18 Feb 2024 17:08:31 +0100 Subject: [PATCH 17/30] Fixed supposed-to-be-ephemeral message not being ephemeral --- .../actualCommands/actualCasesCmd.ts | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts index 3248b20a..24c5a356 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts @@ -32,7 +32,10 @@ async function sendExpandedCases( show: boolean | null, ) { if (casesCount > maxExpandedCases) { - await sendContextResponse(context, "Too many cases for expanded view. Please use compact view instead."); + await sendContextResponse(context, { + content: "Too many cases for expanded view. Please use compact view instead.", + ephemeral: true, + }); return; } @@ -72,17 +75,21 @@ async function casesUserCmd( user instanceof UnknownUser && cases.length ? cases[cases.length - 1].user_name : renderUsername(user); if (cases.length === 0) { - await sendContextResponse(context, `No cases found for **${userName}**${modId ? ` by ${modName}` : ""}.`); + await sendContextResponse(context, { + content: `No cases found for **${userName}**${modId ? ` by ${modName}` : ""}.`, + ephemeral: true, + }); + return; } const casesToDisplay = hidden ? cases : normalCases; if (!casesToDisplay.length) { - await sendContextResponse( - context, - `No normal cases found for **${userName}**. Use "-hidden" to show ${cases.length} hidden cases.`, - ); + await sendContextResponse(context, { + content: `No normal cases found for **${userName}**. Use "-hidden" to show ${cases.length} hidden cases.`, + ephemeral: true, + }); return; } From 174e5cc23b8b3ac684f12c437ffaf88616774ac1 Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Tue, 20 Feb 2024 14:23:43 +0100 Subject: [PATCH 18/30] Fixed mute command not updating case when no reason --- backend/src/plugins/Mutes/functions/muteUser.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index ba2fe387..c61766c1 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -246,10 +246,12 @@ export async function muteUser( if (theCase) { // Update old case const noteDetails = [`Mute updated to ${muteTime ? timeUntilUnmuteStr : "indefinite"}`]; - const reasons = reason ? [reason] : []; + const reasons = reason ? [reason] : [""]; // Empty string so that there is a case update even without reason + if (muteOptions.caseArgs?.extraNotes) { reasons.push(...muteOptions.caseArgs.extraNotes); } + for (const noteReason of reasons) { await casesPlugin.createCaseNote({ caseId: existingMute!.case_id, From 2874a0cf8328ca2fcabf344166f73e012a90e72a Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Thu, 22 Feb 2024 01:07:19 +0100 Subject: [PATCH 19/30] Fixed case type filters --- .../commands/cases/CasesModMsgCmd.ts | 2 ++ .../commands/cases/CasesSlashCmd.ts | 2 ++ .../commands/cases/CasesUserMsgCmd.ts | 2 ++ .../actualCommands/actualCasesCmd.ts | 22 +++++++++++-------- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts index 0777e1cf..57f45c74 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts @@ -11,6 +11,7 @@ const opts = { warns: ct.switchOption({ def: false, shortcut: "w" }), mutes: ct.switchOption({ def: false, shortcut: "m" }), unmutes: ct.switchOption({ def: false, shortcut: "um" }), + kicks: ct.switchOption({ def: false, shortcut: "k" }), bans: ct.switchOption({ def: false, shortcut: "b" }), unbans: ct.switchOption({ def: false, shortcut: "ub" }), show: ct.switchOption({ def: false, shortcut: "sh" }), @@ -38,6 +39,7 @@ export const CasesModMsgCmd = modActionsMsgCmd({ args.warns, args.mutes, args.unmutes, + args.kicks, args.bans, args.unbans, args.reverseFilters, diff --git a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts index 9d22d5d7..3e720917 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts @@ -15,6 +15,7 @@ const opts = [ slashOptions.boolean({ name: "warns", description: "To filter warns", required: false }), slashOptions.boolean({ name: "mutes", description: "To filter mutes", required: false }), slashOptions.boolean({ name: "unmutes", description: "To filter unmutes", required: false }), + slashOptions.boolean({ name: "kicks", description: "To filter kicks", required: false }), slashOptions.boolean({ name: "bans", description: "To filter bans", required: false }), slashOptions.boolean({ name: "unbans", description: "To filter unbans", required: false }), slashOptions.boolean({ name: "show", description: "To make the result visible to everyone", required: false }), @@ -39,6 +40,7 @@ export const CasesSlashCmd = { options.warns, options.mutes, options.unmutes, + options.kicks, options.bans, options.unbans, options["reverse-filters"], diff --git a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts index a185950e..c65226a6 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts @@ -13,6 +13,7 @@ const opts = { warns: ct.switchOption({ def: false, shortcut: "w" }), mutes: ct.switchOption({ def: false, shortcut: "m" }), unmutes: ct.switchOption({ def: false, shortcut: "um" }), + kicks: ct.switchOption({ def: false, shortcut: "k" }), bans: ct.switchOption({ def: false, shortcut: "b" }), unbans: ct.switchOption({ def: false, shortcut: "ub" }), show: ct.switchOption({ def: false, shortcut: "sh" }), @@ -51,6 +52,7 @@ export const CasesUserMsgCmd = modActionsMsgCmd({ args.warns, args.mutes, args.unmutes, + args.kicks, args.bans, args.unbans, args.reverseFilters, diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts index 24c5a356..9bb2d580 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts @@ -227,6 +227,7 @@ export async function actualCasesCmd( warns: boolean | null, mutes: boolean | null, unmutes: boolean | null, + kicks: boolean | null, bans: boolean | null, unbans: boolean | null, reverseFilters: boolean | null, @@ -239,27 +240,30 @@ export async function actualCasesCmd( : null; const modName = modId ? (mod instanceof UnknownUser ? modId : renderUsername(mod!)) : renderUsername(author); + const allTypes = [ + CaseTypes.Note, + CaseTypes.Warn, + CaseTypes.Mute, + CaseTypes.Unmute, + CaseTypes.Kick, + CaseTypes.Ban, + CaseTypes.Unban, + ]; let typesToShow: CaseTypes[] = []; if (notes) typesToShow.push(CaseTypes.Note); if (warns) typesToShow.push(CaseTypes.Warn); if (mutes) typesToShow.push(CaseTypes.Mute); if (unmutes) typesToShow.push(CaseTypes.Unmute); + if (kicks) typesToShow.push(CaseTypes.Kick); if (bans) typesToShow.push(CaseTypes.Ban); if (unbans) typesToShow.push(CaseTypes.Unban); if (typesToShow.length === 0) { - typesToShow = [CaseTypes.Note, CaseTypes.Warn, CaseTypes.Mute, CaseTypes.Unmute, CaseTypes.Ban, CaseTypes.Unban]; + typesToShow = allTypes; } else { if (reverseFilters) { - typesToShow = [ - CaseTypes.Note, - CaseTypes.Warn, - CaseTypes.Mute, - CaseTypes.Unmute, - CaseTypes.Ban, - CaseTypes.Unban, - ].filter((t) => !typesToShow.includes(t)); + typesToShow = allTypes.filter((t) => !typesToShow.includes(t)); } } From a49bb81ce194cd74b931cba49eaa7231680ff22c Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Thu, 22 Feb 2024 02:44:46 +0100 Subject: [PATCH 20/30] Fixed ban command --- .../functions/actualCommands/actualBanCmd.ts | 126 +++++++++--------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts index bc944a59..e4bf5ff9 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts @@ -60,77 +60,77 @@ export async function actualBanCmd( } else { forceban = true; } - } + } else { + // Abort if trying to ban user indefinitely if they are already banned indefinitely + if (!existingTempban && !time) { + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `User is already banned indefinitely.`); + return; + } - // Abort if trying to ban user indefinitely if they are already banned indefinitely - if (!existingTempban && !time) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `User is already banned indefinitely.`); - return; - } + // Ask the mod if we should update the existing ban + const reply = await waitForButtonConfirm( + context, + { content: "Failed to message the user. Log the warning anyway?" }, + { confirmText: "Yes", cancelText: "No", restrictToId: author.id }, + ); - // Ask the mod if we should update the existing ban - const reply = await waitForButtonConfirm( - context, - { content: "Failed to message the user. Log the warning anyway?" }, - { confirmText: "Yes", cancelText: "No", restrictToId: author.id }, - ); + if (!reply) { + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(context, "User already banned, update cancelled by moderator"); + lock.unlock(); + return; + } + + // Update or add new tempban / remove old tempban + if (time && time > 0) { + if (existingTempban) { + await pluginData.state.tempbans.updateExpiryTime(user.id, time, mod.id); + } else { + await pluginData.state.tempbans.addTempban(user.id, time, mod.id); + } + const tempban = (await pluginData.state.tempbans.findExistingTempbanForUserId(user.id))!; + registerExpiringTempban(tempban); + } else if (existingTempban) { + clearExpiringTempban(existingTempban); + pluginData.state.tempbans.clear(user.id); + } + + // Create a new case for the updated ban since we never stored the old case id and log the action + const casesPlugin = pluginData.getPlugin(CasesPlugin); + const createdCase = await casesPlugin.createCase({ + modId: mod.id, + type: CaseTypes.Ban, + userId: user.id, + reason: formattedReason, + noteDetails: [`Ban updated to ${time ? humanizeDuration(time) : "indefinite"}`], + }); + if (time) { + pluginData.getPlugin(LogsPlugin).logMemberTimedBan({ + mod: mod.user, + user, + caseNumber: createdCase.case_number, + reason: formattedReason, + banTime: humanizeDuration(time), + }); + } else { + pluginData.getPlugin(LogsPlugin).logMemberBan({ + mod: mod.user, + user, + caseNumber: createdCase.case_number, + reason: formattedReason, + }); + } - if (!reply) { pluginData .getPlugin(CommonPlugin) - .sendErrorMessage(context, "User already banned, update cancelled by moderator"); + .sendSuccessMessage( + context, + `Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`, + ); lock.unlock(); return; } - - // Update or add new tempban / remove old tempban - if (time && time > 0) { - if (existingTempban) { - await pluginData.state.tempbans.updateExpiryTime(user.id, time, mod.id); - } else { - await pluginData.state.tempbans.addTempban(user.id, time, mod.id); - } - const tempban = (await pluginData.state.tempbans.findExistingTempbanForUserId(user.id))!; - registerExpiringTempban(tempban); - } else if (existingTempban) { - clearExpiringTempban(existingTempban); - pluginData.state.tempbans.clear(user.id); - } - - // Create a new case for the updated ban since we never stored the old case id and log the action - const casesPlugin = pluginData.getPlugin(CasesPlugin); - const createdCase = await casesPlugin.createCase({ - modId: mod.id, - type: CaseTypes.Ban, - userId: user.id, - reason: formattedReason, - noteDetails: [`Ban updated to ${time ? humanizeDuration(time) : "indefinite"}`], - }); - if (time) { - pluginData.getPlugin(LogsPlugin).logMemberTimedBan({ - mod: mod.user, - user, - caseNumber: createdCase.case_number, - reason: formattedReason, - banTime: humanizeDuration(time), - }); - } else { - pluginData.getPlugin(LogsPlugin).logMemberBan({ - mod: mod.user, - user, - caseNumber: createdCase.case_number, - reason: formattedReason, - }); - } - - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - context, - `Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`, - ); - lock.unlock(); - return; } // Make sure we're allowed to ban this member if they are on the server From 4d8b6b5cd73f9d59b3133c375e6b7556b2633463 Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Sat, 24 Feb 2024 03:41:43 +0100 Subject: [PATCH 21/30] Made confirms ephemeral and fixed slash command duration options --- backend/src/plugins/Common/CommonPlugin.ts | 4 ++-- .../commands/forcemute/ForceMuteSlashCmd.ts | 4 ++-- .../commands/forceunmute/ForceUnmuteSlashCmd.ts | 4 ++-- .../ModActions/commands/mute/MuteSlashCmd.ts | 13 ++----------- .../ModActions/commands/unmute/UnmuteSlashCmd.ts | 4 ++-- backend/src/utils/waitForInteraction.ts | 12 ++++++------ 6 files changed, 16 insertions(+), 25 deletions(-) diff --git a/backend/src/plugins/Common/CommonPlugin.ts b/backend/src/plugins/Common/CommonPlugin.ts index 62ee3628..7f9c2204 100644 --- a/backend/src/plugins/Common/CommonPlugin.ts +++ b/backend/src/plugins/Common/CommonPlugin.ts @@ -76,7 +76,7 @@ export const CommonPlugin = zeppelinGuildPlugin()({ }); } - const replyMethod = context.replied ? "followUp" : "reply"; + const replyMethod = context.replied ? "editReply" : "reply"; return context[replyMethod]({ content: formattedBody, @@ -127,7 +127,7 @@ export const CommonPlugin = zeppelinGuildPlugin()({ }); } - const replyMethod = context.replied ? "followUp" : "reply"; + const replyMethod = context.replied ? "editReply" : "reply"; return context[replyMethod]({ content: formattedBody, diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts index 6d6c2fb9..a306fc4a 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts @@ -71,7 +71,7 @@ export const ForceMuteSlashCmd = { ppId = interaction.user.id; } - const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; + const convertedTime = options.time ? convertDelayStringToMS(options.time) ?? undefined : undefined; if (options.time && !convertedTime) { pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; @@ -92,7 +92,7 @@ export const ForceMuteSlashCmd = { attachments, mod, ppId, - options.time, + convertedTime, options.reason, contactMethods, ); diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts index 3c68a64e..6bf6ca90 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts @@ -54,12 +54,12 @@ export const ForceUnmuteSlashCmd = { ppId = interaction.user.id; } - const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; + const convertedTime = options.time ? convertDelayStringToMS(options.time) ?? undefined : undefined; if (options.time && !convertedTime) { pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } - actualUnmuteCmd(pluginData, interaction, options.user, attachments, mod, ppId, options.time, options.reason); + actualUnmuteCmd(pluginData, interaction, options.user, attachments, mod, ppId, convertedTime, options.reason); }, }; diff --git a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts index c84ce9ef..b3fb3f01 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts @@ -45,15 +45,6 @@ export const MuteSlashCmd = { async run({ interaction, options, pluginData }) { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); - - if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); - - return; - } - const memberToMute = await resolveMember(pluginData.client, pluginData.guild, options.user.id); if (!memberToMute) { @@ -106,7 +97,7 @@ export const MuteSlashCmd = { ppId = interaction.user.id; } - const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; + const convertedTime = options.time ? convertDelayStringToMS(options.time) ?? undefined : undefined; if (options.time && !convertedTime) { pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; @@ -127,7 +118,7 @@ export const MuteSlashCmd = { attachments, mod, ppId, - options.time, + convertedTime, options.reason, contactMethods, ); diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts index 97163b2b..5186e86b 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts @@ -102,12 +102,12 @@ export const UnmuteSlashCmd = { ppId = interaction.user.id; } - const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; + const convertedTime = options.time ? convertDelayStringToMS(options.time) ?? undefined : undefined; if (options.time && !convertedTime) { pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } - actualUnmuteCmd(pluginData, interaction, options.user, attachments, mod, ppId, options.time, options.reason); + actualUnmuteCmd(pluginData, interaction, options.user, attachments, mod, ppId, convertedTime, options.reason); }, }; diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index 0cdd0437..59054d72 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -36,14 +36,14 @@ export async function waitForButtonConfirm( const sendMethod = () => { return contextIsInteraction ? context.replied - ? context.followUp.bind(context) + ? context.editReply.bind(context) : context.reply.bind(context) : "send" in context ? context.send.bind(context) : context.channel.send.bind(context.channel); }; - const extraParameters = contextIsInteraction ? { fetchReply: true } : {}; - const message = await sendMethod()({ ...toPost, components: [row], ...extraParameters }); + const extraParameters = contextIsInteraction ? { fetchReply: true, ephemeral: true } : {}; + const message = (await sendMethod()({ ...toPost, components: [row], ...extraParameters })) as Message; const collector = message.createMessageComponentCollector({ time: 10000 }); @@ -55,16 +55,16 @@ export async function waitForButtonConfirm( .catch((err) => console.trace(err.message)); } else { if (interaction.customId.startsWith(`confirmButton:${idMod}:`)) { - message.delete(); + if (!contextIsInteraction) message.delete(); resolve(true); } else if (interaction.customId.startsWith(`cancelButton:${idMod}:`)) { - message.delete(); + if (!contextIsInteraction) message.delete(); resolve(false); } } }); collector.on("end", () => { - if (message.deletable) message.delete().catch(noop); + if (!contextIsInteraction && message.deletable) message.delete().catch(noop); resolve(false); }); }); From 91025d856994557035aec60e50249fdb2f56c803 Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Sat, 24 Feb 2024 20:30:11 +0100 Subject: [PATCH 22/30] Made mass action reason part of the slash command options --- .../commands/addcase/AddCaseSlashCmd.ts | 2 +- .../ModActions/commands/ban/BanSlashCmd.ts | 2 +- .../commands/forceban/ForceBanSlashCmd.ts | 2 +- .../commands/forcemute/ForceMuteSlashCmd.ts | 2 +- .../forceunmute/ForceUnmuteSlashCmd.ts | 2 +- .../ModActions/commands/kick/KickSlashCmd.ts | 2 +- .../commands/massban/MassBanMsgCmd.ts | 16 +++++- .../commands/massban/MassBanSlashCmd.ts | 36 ++++++++++++- .../commands/massmute/MassMuteMsgCmd.ts | 19 ++++++- .../commands/massmute/MassMuteSlashCmd.ts | 36 ++++++++++++- .../commands/massunban/MassUnbanMsgCmd.ts | 17 +++++- .../commands/massunban/MassUnbanSlashCmd.ts | 36 ++++++++++++- .../ModActions/commands/mute/MuteSlashCmd.ts | 2 +- .../commands/unban/UnbanSlashCmd.ts | 2 +- .../commands/unmute/UnmuteSlashCmd.ts | 2 +- .../ModActions/commands/warn/WarnSlashCmd.ts | 2 +- .../actualCommands/actualMassBanCmd.ts | 53 ++++++++++--------- .../actualCommands/actualMassMuteCmd.ts | 37 +++++-------- .../actualCommands/actualMassUnbanCmd.ts | 31 +++++------ 19 files changed, 213 insertions(+), 88 deletions(-) diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts index c83a6b42..2fdaf6c8 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts @@ -11,7 +11,7 @@ const opts = [ slashOptions.user({ name: "mod", description: "The moderator to add this case as", required: false }), ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { name: "attachment", - description: "An attachment to add to the reason of the case", + description: "An attachment to add to the reason", }), ]; diff --git a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts index dd86a546..cae32c55 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts @@ -34,7 +34,7 @@ const opts = [ }), ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { name: "attachment", - description: "An attachment to add to the reason of the ban", + description: "An attachment to add to the reason", }), ]; diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts index c246982e..57de4a0d 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts @@ -11,7 +11,7 @@ const opts = [ slashOptions.user({ name: "mod", description: "The moderator to ban as", required: false }), ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { name: "attachment", - description: "An attachment to add to the reason of the ban", + description: "An attachment to add to the reason", }), ]; diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts index a306fc4a..7bb65b73 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts @@ -29,7 +29,7 @@ const opts = [ }), ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { name: "attachment", - description: "An attachment to add to the reason of the mute", + description: "An attachment to add to the reason", }), ]; diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts index 6bf6ca90..5d93ef00 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts @@ -12,7 +12,7 @@ const opts = [ slashOptions.user({ name: "mod", description: "The moderator to unmute as", required: false }), ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { name: "attachment", - description: "An attachment to add to the reason of the unmute", + description: "An attachment to add to the reason", }), ]; diff --git a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts index 961445ec..98c46452 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts @@ -33,7 +33,7 @@ const opts = [ }), ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { name: "attachment", - description: "An attachment to add to the reason of the kick", + description: "An attachment to add to the reason", }), ]; diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts index d607224a..d2f72c70 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts @@ -1,4 +1,7 @@ +import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMassBanCmd } from "../../functions/actualCommands/actualMassBanCmd"; import { modActionsMsgCmd } from "../../types"; @@ -14,6 +17,17 @@ export const MassBanMsgCmd = modActionsMsgCmd({ ], async run({ pluginData, message: msg, args }) { - actualMassBanCmd(pluginData, msg, args.userIds, msg.member); + // Ask for ban reason (cleaner this way instead of trying to cram it into the args) + sendContextResponse(msg, "Ban reason? `cancel` to cancel"); + const banReasonReply = await waitForReply(pluginData.client, await getContextChannel(msg), msg.author.id); + + if (!banReasonReply || !banReasonReply.content || banReasonReply.content.toLowerCase().trim() === "cancel") { + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cancelled"); + return; + } + + actualMassBanCmd(pluginData, msg, args.userIds, msg.member, banReasonReply.content, [ + ...banReasonReply.attachments.values(), + ]); }, }); diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts index 74f9ba91..6905e0b1 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts @@ -1,5 +1,16 @@ import { slashOptions } from "knub"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMassBanCmd } from "../../functions/actualCommands/actualMassBanCmd"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "reason", description: "The reason", required: false }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason", + }), +]; export const MassBanSlashCmd = { name: "massban", @@ -7,9 +18,30 @@ export const MassBanSlashCmd = { description: "Mass-ban a list of user IDs", allowDms: false, - signature: [slashOptions.string({ name: "user-ids", description: "The list of user IDs to ban", required: true })], + signature: [ + slashOptions.string({ name: "user-ids", description: "The list of user IDs to ban", required: true }), + + ...opts, + ], async run({ interaction, options, pluginData }) { - actualMassBanCmd(pluginData, interaction, options["user-ids"].split(/[\s,\r\n]+/), interaction.member); + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + actualMassBanCmd( + pluginData, + interaction, + options["user-ids"].split(/[\s,\r\n]+/), + interaction.member, + options.reason || "", + attachments, + ); }, }; diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts index a09a5f26..713e89dd 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts @@ -1,4 +1,7 @@ +import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; +import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMassMuteCmd } from "../../functions/actualCommands/actualMassMuteCmd"; import { modActionsMsgCmd } from "../../types"; @@ -14,6 +17,20 @@ export const MassMuteMsgCmd = modActionsMsgCmd({ ], async run({ pluginData, message: msg, args }) { - actualMassMuteCmd(pluginData, msg, args.userIds, msg.member); + // Ask for mute reason + sendContextResponse(msg, "Mute reason? `cancel` to cancel"); + const muteReasonReceived = await waitForReply(pluginData.client, await getContextChannel(msg), msg.author.id); + if ( + !muteReasonReceived || + !muteReasonReceived.content || + muteReasonReceived.content.toLowerCase().trim() === "cancel" + ) { + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cancelled"); + return; + } + + actualMassMuteCmd(pluginData, msg, args.userIds, msg.member, muteReasonReceived.content, [ + ...muteReasonReceived.attachments.values(), + ]); }, }); diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts index 1650b174..da58647d 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts @@ -1,5 +1,16 @@ import { slashOptions } from "knub"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMassMuteCmd } from "../../functions/actualCommands/actualMassMuteCmd"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "reason", description: "The reason", required: false }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason", + }), +]; export const MassMuteSlashSlashCmd = { name: "massmute", @@ -7,9 +18,30 @@ export const MassMuteSlashSlashCmd = { description: "Mass-mute a list of user IDs", allowDms: false, - signature: [slashOptions.string({ name: "user-ids", description: "The list of user IDs to mute", required: true })], + signature: [ + slashOptions.string({ name: "user-ids", description: "The list of user IDs to mute", required: true }), + + ...opts, + ], async run({ interaction, options, pluginData }) { - actualMassMuteCmd(pluginData, interaction, options["user-ids"].split(/[\s,\r\n]+/), interaction.member); + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + actualMassMuteCmd( + pluginData, + interaction, + options["user-ids"].split(/[\s,\r\n]+/), + interaction.member, + options.reason || "", + attachments, + ); }, }; diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts index 72713ad5..121be1cb 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts @@ -1,5 +1,8 @@ +import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualMassBanCmd } from "../../functions/actualCommands/actualMassBanCmd"; +import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; +import { actualMassUnbanCmd } from "../../functions/actualCommands/actualMassUnbanCmd"; import { modActionsMsgCmd } from "../../types"; export const MassUnbanMsgCmd = modActionsMsgCmd({ @@ -14,6 +17,16 @@ export const MassUnbanMsgCmd = modActionsMsgCmd({ ], async run({ pluginData, message: msg, args }) { - actualMassBanCmd(pluginData, msg, args.userIds, msg.member); + // Ask for unban reason (cleaner this way instead of trying to cram it into the args) + sendContextResponse(msg, "Unban reason? `cancel` to cancel"); + const unbanReasonReply = await waitForReply(pluginData.client, await getContextChannel(msg), msg.author.id); + if (!unbanReasonReply || !unbanReasonReply.content || unbanReasonReply.content.toLowerCase().trim() === "cancel") { + pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cancelled"); + return; + } + + actualMassUnbanCmd(pluginData, msg, args.userIds, msg.member, unbanReasonReply.content, [ + ...unbanReasonReply.attachments.values(), + ]); }, }); diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts index 15f6ca6a..ded26357 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts @@ -1,5 +1,16 @@ import { slashOptions } from "knub"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; +import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMassUnbanCmd } from "../../functions/actualCommands/actualMassUnbanCmd"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; + +const opts = [ + slashOptions.string({ name: "reason", description: "The reason", required: false }), + ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { + name: "attachment", + description: "An attachment to add to the reason", + }), +]; export const MassUnbanSlashCmd = { name: "massunban", @@ -7,9 +18,30 @@ export const MassUnbanSlashCmd = { description: "Mass-unban a list of user IDs", allowDms: false, - signature: [slashOptions.string({ name: "user-ids", description: "The list of user IDs to unban", required: true })], + signature: [ + slashOptions.string({ name: "user-ids", description: "The list of user IDs to unban", required: true }), + + ...opts, + ], async run({ interaction, options, pluginData }) { - actualMassUnbanCmd(pluginData, interaction, options["user-ids"].split(/[\s,\r\n]+/), interaction.member); + const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); + + if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + + return; + } + + actualMassUnbanCmd( + pluginData, + interaction, + options["user-ids"].split(/[\s,\r\n]+/), + interaction.member, + options.reason || "", + attachments, + ); }, }; diff --git a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts index b3fb3f01..37b11b52 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts @@ -31,7 +31,7 @@ const opts = [ }), ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { name: "attachment", - description: "An attachment to add to the reason of the mute", + description: "An attachment to add to the reason", }), ]; diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts index abc969de..58be63b2 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts @@ -10,7 +10,7 @@ const opts = [ slashOptions.user({ name: "mod", description: "The moderator to unban as", required: false }), ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { name: "attachment", - description: "An attachment to add to the reason of the unban", + description: "An attachment to add to the reason", }), ]; diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts index 5186e86b..41ec3eac 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts @@ -15,7 +15,7 @@ const opts = [ slashOptions.user({ name: "mod", description: "The moderator to unmute as", required: false }), ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { name: "attachment", - description: "An attachment to add to the reason of the unmute", + description: "An attachment to add to the reason", }), ]; diff --git a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts index 43f796f2..920326a5 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts @@ -29,7 +29,7 @@ const opts = [ }), ...generateAttachmentSlashOptions(NUMBER_ATTACHMENTS_CASE_CREATION, { name: "attachment", - description: "An attachment to add to the reason of the warn", + description: "An attachment to add to the reason", }), ]; diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts index 2b35c51a..f1c4953c 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts @@ -1,6 +1,5 @@ -import { ChatInputCommandInteraction, GuildMember, Message, Snowflake } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, GuildMember, Message, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { waitForReply } from "knub/helpers"; import { CaseTypes } from "../../../../data/CaseTypes"; import { LogType } from "../../../../data/LogType"; import { humanizeDurationShort } from "../../../../humanizeDurationShort"; @@ -19,6 +18,8 @@ export async function actualMassBanCmd( context: Message | ChatInputCommandInteraction, userIds: string[], author: GuildMember, + reason: string, + attachments: Attachment[], ) { // Limit to 100 users at once (arbitrary?) if (userIds.length > 100) { @@ -26,25 +27,12 @@ export async function actualMassBanCmd( return; } - // Ask for ban reason (cleaner this way instead of trying to cram it into the args) - sendContextResponse(context, "Ban reason? `cancel` to cancel"); - const banReasonReply = await waitForReply(pluginData.client, await getContextChannel(context), author.id); - - if (!banReasonReply || !banReasonReply.content || banReasonReply.content.toLowerCase().trim() === "cancel") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Cancelled"); + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { return; } - if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, banReasonReply.content)) { - return; - } - - const banReason = await formatReasonWithMessageLinkForAttachments(pluginData, banReasonReply.content, context, [ - ...banReasonReply.attachments.values(), - ]); - const banReasonWithAttachments = formatReasonWithAttachments(banReasonReply.content, [ - ...banReasonReply.attachments.values(), - ]); + const banReason = await formatReasonWithMessageLinkForAttachments(pluginData, reason, context, attachments); + const banReasonWithAttachments = formatReasonWithAttachments(reason, attachments); // Verify we can act on each of the users specified for (const userId of userIds) { @@ -64,7 +52,7 @@ export async function actualMassBanCmd( pluginData.state.massbanQueue.length === 0 ? "Banning..." : `Massban queued. Waiting for previous massban to finish (max wait ${maxWaitTimeFormatted}).`; - const loadingMsg = await sendContextResponse(context, initialLoadingText); + const loadingMsg = await sendContextResponse(context, { content: initialLoadingText, ephemeral: true }); const waitTimeStart = performance.now(); const waitingInterval = setInterval(() => { @@ -78,11 +66,20 @@ export async function actualMassBanCmd( clearInterval(waitingInterval); if (pluginData.state.unloaded) { - void loadingMsg.delete().catch(noop); + if (isContextInteraction(context)) { + void context.deleteReply().catch(noop); + } else { + void loadingMsg.delete().catch(noop); + } + return; } - void loadingMsg.edit("Banning...").catch(noop); + if (isContextInteraction(context)) { + void context.editReply("Banning...").catch(noop); + } else { + void loadingMsg.edit("Banning...").catch(noop); + } // Ban each user and count failed bans (if any) const startTime = performance.now(); @@ -124,15 +121,23 @@ export async function actualMassBanCmd( // Send a status update every 10 bans if ((i + 1) % 10 === 0) { - loadingMsg.edit(`Banning... ${i + 1}/${userIds.length}`).catch(noop); + const newLoadingMessageContent = `Banning... ${i + 1}/${userIds.length}`; + + if (isContextInteraction(context)) { + void context.editReply(newLoadingMessageContent).catch(noop); + } else { + loadingMsg.edit(newLoadingMessageContent).catch(noop); + } } } const totalTime = performance.now() - startTime; const formattedTimeTaken = humanizeDurationShort(totalTime, { round: true }); - // Clear loading indicator - loadingMsg.delete().catch(noop); + if (!isContextInteraction(context)) { + // Clear loading indicator + loadingMsg.delete().catch(noop); + } const successfulBanCount = userIds.length - failedBans.length; if (successfulBanCount === 0) { diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts index 2d8086cb..53a82421 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts @@ -1,9 +1,8 @@ -import { ChatInputCommandInteraction, GuildMember, Message, Snowflake } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, GuildMember, Message, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { waitForReply } from "knub/helpers"; import { LogType } from "../../../../data/LogType"; import { logger } from "../../../../logger"; -import { canActOn, getContextChannel, sendContextResponse } from "../../../../pluginUtils"; +import { canActOn, isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; @@ -16,6 +15,8 @@ export async function actualMassMuteCmd( context: Message | ChatInputCommandInteraction, userIds: string[], author: GuildMember, + reason: string, + attachments: Attachment[], ) { // Limit to 100 users at once (arbitrary?) if (userIds.length > 100) { @@ -23,28 +24,12 @@ export async function actualMassMuteCmd( return; } - // Ask for mute reason - sendContextResponse(context, "Mute reason? `cancel` to cancel"); - const muteReasonReceived = await waitForReply(pluginData.client, await getContextChannel(context), author.id); - if ( - !muteReasonReceived || - !muteReasonReceived.content || - muteReasonReceived.content.toLowerCase().trim() === "cancel" - ) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Cancelled"); + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { return; } - if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, muteReasonReceived.content)) { - return; - } - - const muteReason = await formatReasonWithMessageLinkForAttachments(pluginData, muteReasonReceived.content, context, [ - ...muteReasonReceived.attachments.values(), - ]); - const muteReasonWithAttachments = formatReasonWithAttachments(muteReasonReceived.content, [ - ...muteReasonReceived.attachments.values(), - ]); + const muteReason = await formatReasonWithMessageLinkForAttachments(pluginData, reason, context, attachments); + const muteReasonWithAttachments = formatReasonWithAttachments(reason, attachments); // Verify we can act upon all users for (const userId of userIds) { @@ -65,7 +50,7 @@ export async function actualMassMuteCmd( }); // Show loading indicator - const loadingMsg = await sendContextResponse(context, "Muting..."); + const loadingMsg = await sendContextResponse(context, { content: "Muting...", ephemeral: true }); // Mute everyone and count fails const modId = author.id; @@ -84,8 +69,10 @@ export async function actualMassMuteCmd( } } - // Clear loading indicator - loadingMsg.delete(); + if (!isContextInteraction(context)) { + // Clear loading indicator + loadingMsg.delete(); + } const successfulMuteCount = userIds.length - failedMutes.length; if (successfulMuteCount === 0) { diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts index a980445c..8cf1b4ac 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts @@ -1,10 +1,9 @@ -import { ChatInputCommandInteraction, GuildMember, Message, Snowflake } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, GuildMember, Message, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { waitForReply } from "knub/helpers"; import { CaseTypes } from "../../../../data/CaseTypes"; import { LogType } from "../../../../data/LogType"; -import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { MINUTES } from "../../../../utils"; +import { isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; +import { MINUTES, noop } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; @@ -19,6 +18,8 @@ export async function actualMassUnbanCmd( context: Message | ChatInputCommandInteraction, userIds: string[], author: GuildMember, + reason: string, + attachments: Attachment[], ) { // Limit to 100 users at once (arbitrary?) if (userIds.length > 100) { @@ -26,21 +27,11 @@ export async function actualMassUnbanCmd( return; } - // Ask for unban reason (cleaner this way instead of trying to cram it into the args) - sendContextResponse(context, "Unban reason? `cancel` to cancel"); - const unbanReasonReply = await waitForReply(pluginData.client, await getContextChannel(context), author.id); - if (!unbanReasonReply || !unbanReasonReply.content || unbanReasonReply.content.toLowerCase().trim() === "cancel") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Cancelled"); + if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { return; } - if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, unbanReasonReply.content)) { - return; - } - - const unbanReason = await formatReasonWithMessageLinkForAttachments(pluginData, unbanReasonReply.content, context, [ - ...unbanReasonReply.attachments.values(), - ]); + const unbanReason = await formatReasonWithMessageLinkForAttachments(pluginData, reason, context, attachments); // Ignore automatic unban cases and logs for these users // We'll create our own cases below and post a single "mass unbanned" log instead @@ -51,7 +42,7 @@ export async function actualMassUnbanCmd( }); // Show a loading indicator since this can take a while - const loadingMsg = await sendContextResponse(context, "Unbanning..."); + const loadingMsg = await sendContextResponse(context, { content: "Unbanning...", ephemeral: true }); // Unban each user and count failed unbans (if any) const failedUnbans: Array<{ userId: string; reason: UnbanFailReasons }> = []; @@ -77,8 +68,10 @@ export async function actualMassUnbanCmd( } } - // Clear loading indicator - loadingMsg.delete(); + if (!isContextInteraction(context)) { + // Clear loading indicator + loadingMsg.delete().catch(noop); + } const successfulUnbanCount = userIds.length - failedUnbans.length; if (successfulUnbanCount === 0) { From e879a15aa48bbb17dbd190f62fa9778ca1d4e372 Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Sat, 24 Feb 2024 20:46:48 +0100 Subject: [PATCH 23/30] Fixed incomplete attachment list for mass action message commands --- .../ModActions/functions/formatReasonForAttachments.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts b/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts index 9bcc825e..4cb16e82 100644 --- a/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts +++ b/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts @@ -10,7 +10,9 @@ export async function formatReasonWithMessageLinkForAttachments( attachments: Attachment[], ) { if (isContextMessage(context)) { - return context.attachments.size > 0 ? ((reason || "") + " " + context.url).trim() : reason; + const allAttachments = [...new Set([...context.attachments.values(), ...attachments])]; + + return allAttachments.length > 0 ? ((reason || "") + " " + context.url).trim() : reason; } if (attachments.length < 1) { From ee861bb5e9fecb6010a4b08b61e7c3d920580b4d Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Sat, 24 Feb 2024 20:52:41 +0100 Subject: [PATCH 24/30] Fixed fatal error for massbans --- .../functions/actualCommands/actualMassBanCmd.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts index f1c4953c..fcb9610d 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts @@ -57,9 +57,13 @@ export async function actualMassBanCmd( const waitTimeStart = performance.now(); const waitingInterval = setInterval(() => { const waitTime = humanizeDurationShort(performance.now() - waitTimeStart, { round: true }); - loadingMsg - .edit(`Massban queued. Still waiting for previous massban to finish (waited ${waitTime}).`) - .catch(() => clearInterval(waitingInterval)); + const waitMessageContent = `Massban queued. Still waiting for previous massban to finish (waited ${waitTime}).`; + + if (isContextInteraction(context)) { + context.editReply(waitMessageContent).catch(() => clearInterval(waitingInterval)); + } else { + loadingMsg.edit(waitMessageContent).catch(() => clearInterval(waitingInterval)); + } }, 1 * MINUTES); pluginData.state.massbanQueue.add(async () => { From 408f1b9c30019ff4b3e5ab5c2d62ff51e2c8ebc7 Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Mon, 26 Feb 2024 22:05:25 +0100 Subject: [PATCH 25/30] Added slash command deferral to avoid timeouts --- backend/src/pluginUtils.ts | 8 +++++++- backend/src/plugins/Common/CommonPlugin.ts | 4 ++-- .../ModActions/commands/addcase/AddCaseSlashCmd.ts | 1 + .../src/plugins/ModActions/commands/ban/BanSlashCmd.ts | 1 + .../src/plugins/ModActions/commands/case/CaseSlashCmd.ts | 1 + .../plugins/ModActions/commands/cases/CasesSlashCmd.ts | 2 ++ .../ModActions/commands/deletecase/DeleteCaseSlashCmd.ts | 2 ++ .../ModActions/commands/forceban/ForceBanSlashCmd.ts | 1 + .../ModActions/commands/forcemute/ForceMuteSlashCmd.ts | 1 + .../commands/forceunmute/ForceUnmuteSlashCmd.ts | 1 + .../ModActions/commands/hidecase/HideCaseSlashCmd.ts | 1 + .../src/plugins/ModActions/commands/kick/KickSlashCmd.ts | 1 + .../ModActions/commands/massban/MassBanSlashCmd.ts | 1 + .../ModActions/commands/massmute/MassMuteSlashCmd.ts | 1 + .../ModActions/commands/massunban/MassUnbanSlashCmd.ts | 1 + .../src/plugins/ModActions/commands/mute/MuteSlashCmd.ts | 1 + .../src/plugins/ModActions/commands/note/NoteSlashCmd.ts | 1 + .../plugins/ModActions/commands/unban/UnbanSlashCmd.ts | 1 + .../ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts | 1 + .../plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts | 1 + .../plugins/ModActions/commands/update/UpdateSlashCmd.ts | 2 ++ .../src/plugins/ModActions/commands/warn/WarnSlashCmd.ts | 1 + 22 files changed, 32 insertions(+), 3 deletions(-) diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index 9e7f9783..b49c4665 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -86,7 +86,13 @@ export async function sendContextResponse( if (isContextInteraction(context)) { const options = { ...(typeof response === "string" ? { content: response } : response), fetchReply: true }; - return (context.replied ? context.followUp(options) : context.reply(options)) as Promise; + return ( + context.replied + ? context.followUp(options) + : context.deferred + ? context.editReply(options) + : context.reply(options) + ) as Promise; } if (typeof response !== "string" && "ephemeral" in response) { diff --git a/backend/src/plugins/Common/CommonPlugin.ts b/backend/src/plugins/Common/CommonPlugin.ts index 7f9c2204..92c58b63 100644 --- a/backend/src/plugins/Common/CommonPlugin.ts +++ b/backend/src/plugins/Common/CommonPlugin.ts @@ -76,7 +76,7 @@ export const CommonPlugin = zeppelinGuildPlugin()({ }); } - const replyMethod = context.replied ? "editReply" : "reply"; + const replyMethod = context.replied || context.deferred ? "editReply" : "reply"; return context[replyMethod]({ content: formattedBody, @@ -127,7 +127,7 @@ export const CommonPlugin = zeppelinGuildPlugin()({ }); } - const replyMethod = context.replied ? "editReply" : "reply"; + const replyMethod = context.replied || context.deferred ? "editReply" : "reply"; return context[replyMethod]({ content: formattedBody, diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts index 2fdaf6c8..c8ee903e 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts @@ -34,6 +34,7 @@ export const AddCaseSlashCmd = { ], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); // The moderator who did the action is the message author or, if used, the specified -mod diff --git a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts index cae32c55..c1b0ebcd 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts @@ -47,6 +47,7 @@ export const BanSlashCmd = { signature: [slashOptions.user({ name: "user", description: "The user to ban", required: true }), ...opts], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { diff --git a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts index 98219e3f..3394c086 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts @@ -18,6 +18,7 @@ export const CaseSlashCmd = { ], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); actualCaseCmd(pluginData, interaction, interaction.user.id, options["case-number"], options.show); }, }; diff --git a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts index 3e720917..07a457ff 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts @@ -30,6 +30,8 @@ export const CasesSlashCmd = { signature: [...opts], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); + return actualCasesCmd( pluginData, interaction, diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts index e087e3a4..89004847 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts @@ -16,6 +16,8 @@ export const DeleteCaseSlashCmd = { ], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); + actualDeleteCaseCmd( pluginData, interaction, diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts index 57de4a0d..059ff2de 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts @@ -24,6 +24,7 @@ export const ForceBanSlashCmd = { signature: [slashOptions.user({ name: "user", description: "The user to ban", required: true }), ...opts], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts index 7bb65b73..6f7fa2ca 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts @@ -42,6 +42,7 @@ export const ForceMuteSlashCmd = { signature: [slashOptions.user({ name: "user", description: "The user to mute", required: true }), ...opts], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts index 5d93ef00..8ea323fe 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts @@ -25,6 +25,7 @@ export const ForceUnmuteSlashCmd = { signature: [slashOptions.user({ name: "user", description: "The user to unmute", required: true }), ...opts], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts index c324b250..95f48580 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts @@ -12,6 +12,7 @@ export const HideCaseSlashCmd = { ], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); actualHideCaseCmd(pluginData, interaction, options["case-number"].split(/[\s,]+/).map(Number)); }, }; diff --git a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts index 98c46452..ce0a659b 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts @@ -46,6 +46,7 @@ export const KickSlashCmd = { signature: [slashOptions.user({ name: "user", description: "The user to kick", required: true }), ...opts], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts index 6905e0b1..ab8ea1d1 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts @@ -25,6 +25,7 @@ export const MassBanSlashCmd = { ], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts index da58647d..6f2c18ba 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts @@ -25,6 +25,7 @@ export const MassMuteSlashSlashCmd = { ], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts index ded26357..da079dfd 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts @@ -25,6 +25,7 @@ export const MassUnbanSlashCmd = { ], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { diff --git a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts index 37b11b52..f20585a9 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts @@ -44,6 +44,7 @@ export const MuteSlashCmd = { signature: [slashOptions.user({ name: "user", description: "The user to mute", required: true }), ...opts], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); const memberToMute = await resolveMember(pluginData.client, pluginData.guild, options.user.id); diff --git a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts index 9647d861..edcf60e9 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts @@ -21,6 +21,7 @@ export const NoteSlashCmd = { signature: [slashOptions.user({ name: "user", description: "The user to add a note to", required: true }), ...opts], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.note || options.note.trim() === "") && attachments.length < 1) { diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts index 58be63b2..1a8a2181 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts @@ -23,6 +23,7 @@ export const UnbanSlashCmd = { signature: [slashOptions.user({ name: "user", description: "The user to unban", required: true }), ...opts], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts index d0a66d7c..92d3c0fb 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts @@ -12,6 +12,7 @@ export const UnhideCaseSlashCmd = { ], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); actualUnhideCaseCmd(pluginData, interaction, options["case-number"].split(/[\s,]+/).map(Number)); }, }; diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts index 41ec3eac..df57fa05 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts @@ -28,6 +28,7 @@ export const UnmuteSlashCmd = { signature: [slashOptions.user({ name: "user", description: "The user to unmute", required: true }), ...opts], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { diff --git a/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts b/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts index 4f6fdae2..a1a6cabf 100644 --- a/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts @@ -21,6 +21,8 @@ export const UpdateSlashCmd = { signature: [...opts], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); + await updateCase( pluginData, interaction, diff --git a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts index 920326a5..7295551b 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts @@ -42,6 +42,7 @@ export const WarnSlashCmd = { signature: [slashOptions.user({ name: "user", description: "The user to warn", required: true }), ...opts], async run({ interaction, options, pluginData }) { + await interaction.deferReply({ ephemeral: true }); const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { From 7eff7bcaa6b6f06d59cfc8656cf233cb0fd9dc1a Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Mon, 26 Feb 2024 22:23:30 +0100 Subject: [PATCH 26/30] Fixed show option for case and cases commands --- .../src/plugins/ModActions/commands/case/CaseSlashCmd.ts | 2 +- .../plugins/ModActions/commands/cases/CasesSlashCmd.ts | 2 +- .../ModActions/functions/actualCommands/actualCaseCmd.ts | 2 +- .../functions/actualCommands/actualCasesCmd.ts | 9 ++++++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts index 3394c086..8db48612 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts @@ -18,7 +18,7 @@ export const CaseSlashCmd = { ], async run({ interaction, options, pluginData }) { - await interaction.deferReply({ ephemeral: true }); + await interaction.deferReply({ ephemeral: options.show !== true }); actualCaseCmd(pluginData, interaction, interaction.user.id, options["case-number"], options.show); }, }; diff --git a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts index 07a457ff..ff29588d 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts @@ -30,7 +30,7 @@ export const CasesSlashCmd = { signature: [...opts], async run({ interaction, options, pluginData }) { - await interaction.deferReply({ ephemeral: true }); + await interaction.deferReply({ ephemeral: options.show !== true }); return actualCasesCmd( pluginData, diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts index e45dc0e7..92b27199 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts @@ -15,7 +15,7 @@ export async function actualCaseCmd( const theCase = await pluginData.state.cases.findByCaseNumber(caseNumber); if (!theCase) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Case not found"); + pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Case not found", undefined, undefined, show !== true); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts index 9bb2d580..23c091a1 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts @@ -77,7 +77,7 @@ async function casesUserCmd( if (cases.length === 0) { await sendContextResponse(context, { content: `No cases found for **${userName}**${modId ? ` by ${modName}` : ""}.`, - ephemeral: true, + ephemeral: !show, }); return; @@ -88,7 +88,7 @@ async function casesUserCmd( if (!casesToDisplay.length) { await sendContextResponse(context, { content: `No normal cases found for **${userName}**. Use "-hidden" to show ${cases.length} hidden cases.`, - ephemeral: true, + ephemeral: !show, }); return; @@ -160,7 +160,10 @@ async function casesModCmd( const totalCases = await casesPlugin.getTotalCasesByMod(modId ?? author.id, casesFilters); if (totalCases === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `No cases by **${modName}**`); + pluginData + .getPlugin(CommonPlugin) + .sendErrorMessage(context, `No cases by **${modName}**`, undefined, undefined, !show); + return; } From cbec6101e01430b69ee667f8c5c382b3a81712e0 Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Tue, 5 Mar 2024 05:05:03 +0100 Subject: [PATCH 27/30] Used guildPluginSlashCommand instead of raw blueprints --- .../plugins/ModActions/ModActionsPlugin.ts | 40 +++++++++---------- .../commands/addcase/AddCaseSlashCmd.ts | 13 +++--- .../ModActions/commands/ban/BanSlashCmd.ts | 15 +++---- .../ModActions/commands/case/CaseSlashCmd.ts | 5 ++- .../commands/cases/CasesSlashCmd.ts | 10 +++-- .../commands/deletecase/DeleteCaseSlashCmd.ts | 10 +++-- .../commands/forceban/ForceBanSlashCmd.ts | 22 +++++++--- .../commands/forcemute/ForceMuteSlashCmd.ts | 15 +++---- .../forceunmute/ForceUnmuteSlashCmd.ts | 14 ++++--- .../commands/hidecase/HideCaseSlashCmd.ts | 7 ++-- .../ModActions/commands/kick/KickSlashCmd.ts | 15 +++---- .../commands/massban/MassBanSlashCmd.ts | 10 +++-- .../commands/massmute/MassMuteSlashCmd.ts | 10 +++-- .../commands/massunban/MassUnbanSlashCmd.ts | 8 ++-- .../ModActions/commands/mute/MuteSlashCmd.ts | 15 +++---- .../ModActions/commands/note/NoteSlashCmd.ts | 5 ++- .../commands/unban/UnbanSlashCmd.ts | 13 +++--- .../commands/unhidecase/UnhideCaseSlashCmd.ts | 7 ++-- .../commands/unmute/UnmuteSlashCmd.ts | 12 +++--- .../commands/update/UpdateSlashCmd.ts | 9 +++-- .../ModActions/commands/warn/WarnSlashCmd.ts | 13 +++--- .../functions/actualCommands/actualKickCmd.ts | 2 +- .../functions/actualCommands/actualMuteCmd.ts | 2 +- .../actualCommands/actualUnmuteCmd.ts | 2 +- .../functions/readContactMethodsFromArgs.ts | 4 +- .../ModActions/functions/updateCase.ts | 2 +- backend/src/plugins/ModActions/types.ts | 9 ++++- 27 files changed, 168 insertions(+), 121 deletions(-) diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index 8efc5c4b..075c6d6f 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -170,26 +170,26 @@ export const ModActionsPlugin = zeppelinGuildPlugin()({ description: "Moderation actions", defaultMemberPermissions: "0", subcommands: [ - { type: "slash", ...AddCaseSlashCmd }, - { type: "slash", ...BanSlashCmd }, - { type: "slash", ...CaseSlashCmd }, - { type: "slash", ...CasesSlashCmd }, - { type: "slash", ...DeleteCaseSlashCmd }, - { type: "slash", ...ForceBanSlashCmd }, - { type: "slash", ...ForceMuteSlashCmd }, - { type: "slash", ...ForceUnmuteSlashCmd }, - { type: "slash", ...HideCaseSlashCmd }, - { type: "slash", ...KickSlashCmd }, - { type: "slash", ...MassBanSlashCmd }, - { type: "slash", ...MassMuteSlashSlashCmd }, - { type: "slash", ...MassUnbanSlashCmd }, - { type: "slash", ...MuteSlashCmd }, - { type: "slash", ...NoteSlashCmd }, - { type: "slash", ...UnbanSlashCmd }, - { type: "slash", ...UnhideCaseSlashCmd }, - { type: "slash", ...UnmuteSlashCmd }, - { type: "slash", ...UpdateSlashCmd }, - { type: "slash", ...WarnSlashCmd }, + AddCaseSlashCmd, + BanSlashCmd, + CaseSlashCmd, + CasesSlashCmd, + DeleteCaseSlashCmd, + ForceBanSlashCmd, + ForceMuteSlashCmd, + ForceUnmuteSlashCmd, + HideCaseSlashCmd, + KickSlashCmd, + MassBanSlashCmd, + MassMuteSlashSlashCmd, + MassUnbanSlashCmd, + MuteSlashCmd, + NoteSlashCmd, + UnbanSlashCmd, + UnhideCaseSlashCmd, + UnmuteSlashCmd, + UpdateSlashCmd, + WarnSlashCmd, ], }), ], diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts index c8ee903e..5f427686 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts @@ -1,9 +1,12 @@ +import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { CaseTypes } from "../../../../data/CaseTypes"; import { hasPermission } from "../../../../pluginUtils"; +import { resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualAddCaseCmd } from "../../functions/actualCommands/actualAddCaseCmd"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -15,7 +18,7 @@ const opts = [ }), ]; -export const AddCaseSlashCmd = { +export const AddCaseSlashCmd = modActionsSlashCmd({ name: "addcase", configPermission: "can_addcase", description: "Add an arbitrary case to the specified user without taking any action", @@ -38,7 +41,7 @@ export const AddCaseSlashCmd = { const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); // The moderator who did the action is the message author or, if used, the specified -mod - let mod = interaction.member; + let mod = interaction.member as GuildMember; const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { channel: interaction.channel, member: interaction.member, @@ -52,13 +55,13 @@ export const AddCaseSlashCmd = { return; } - mod = options.mod; + mod = (await resolveMember(pluginData.client, pluginData.guild, options.mod.id))!; } actualAddCaseCmd( pluginData, interaction, - interaction.member, + interaction.member as GuildMember, mod, attachments, options.user, @@ -66,4 +69,4 @@ export const AddCaseSlashCmd = { options.reason || "", ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts index c1b0ebcd..21b5558a 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts @@ -1,11 +1,12 @@ -import { ChannelType } from "discord.js"; +import { ChannelType, GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; -import { UserNotificationMethod, convertDelayStringToMS } from "../../../../utils"; +import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualBanCmd } from "../../functions/actualCommands/actualBanCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -38,7 +39,7 @@ const opts = [ }), ]; -export const BanSlashCmd = { +export const BanSlashCmd = modActionsSlashCmd({ name: "ban", configPermission: "can_ban", description: "Ban or Tempban the specified member", @@ -58,7 +59,7 @@ export const BanSlashCmd = { return; } - let mod = interaction.member; + let mod = interaction.member as GuildMember; const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { channel: interaction.channel, member: interaction.member, @@ -72,7 +73,7 @@ export const BanSlashCmd = { return; } - mod = options.mod; + mod = (await resolveMember(pluginData.client, pluginData.guild, options.mod.id))!; } let contactMethods: UserNotificationMethod[] | undefined; @@ -96,9 +97,9 @@ export const BanSlashCmd = { convertedTime, options.reason || "", attachments, - interaction.member, + interaction.member as GuildMember, mod, contactMethods, ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts index 8db48612..15f2d03f 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts @@ -1,11 +1,12 @@ import { slashOptions } from "knub"; import { actualCaseCmd } from "../../functions/actualCommands/actualCaseCmd"; +import { modActionsSlashCmd } from "../../types"; const opts = [ slashOptions.boolean({ name: "show", description: "To make the result visible to everyone", required: false }), ]; -export const CaseSlashCmd = { +export const CaseSlashCmd = modActionsSlashCmd({ name: "case", configPermission: "can_view", description: "Show information about a specific case", @@ -21,4 +22,4 @@ export const CaseSlashCmd = { await interaction.deferReply({ ephemeral: options.show !== true }); actualCaseCmd(pluginData, interaction, interaction.user.id, options["case-number"], options.show); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts index ff29588d..8e885d1a 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts @@ -1,5 +1,7 @@ +import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { actualCasesCmd } from "../../functions/actualCommands/actualCasesCmd"; +import { modActionsSlashCmd } from "../../types"; const opts = [ slashOptions.user({ name: "user", description: "The user to show cases for", required: false }), @@ -21,7 +23,7 @@ const opts = [ slashOptions.boolean({ name: "show", description: "To make the result visible to everyone", required: false }), ]; -export const CasesSlashCmd = { +export const CasesSlashCmd = modActionsSlashCmd({ name: "cases", configPermission: "can_view", description: "Show a list of cases the specified user has or the specified mod made", @@ -35,9 +37,9 @@ export const CasesSlashCmd = { return actualCasesCmd( pluginData, interaction, - options.mod, + options.mod?.id ?? null, options.user, - interaction.member, + interaction.member as GuildMember, options.notes, options.warns, options.mutes, @@ -51,4 +53,4 @@ export const CasesSlashCmd = { options.show, ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts index 89004847..f852b666 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts @@ -1,9 +1,11 @@ +import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { actualDeleteCaseCmd } from "../../functions/actualCommands/actualDeleteCaseCmd"; +import { modActionsSlashCmd } from "../../types"; const opts = [slashOptions.boolean({ name: "force", description: "Whether or not to force delete", required: false })]; -export const DeleteCaseSlashCmd = { +export const DeleteCaseSlashCmd = modActionsSlashCmd({ name: "deletecase", configPermission: "can_deletecase", description: "Delete the specified case. This operation can *not* be reversed.", @@ -21,9 +23,9 @@ export const DeleteCaseSlashCmd = { actualDeleteCaseCmd( pluginData, interaction, - interaction.member, - options["case-number"].split(/[\s,]+/), + interaction.member as GuildMember, + options["case-number"].split(/\D+/).map(Number), !!options.force, ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts index 059ff2de..7f7e824c 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts @@ -1,9 +1,11 @@ +import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; -import { convertDelayStringToMS } from "../../../../utils"; +import { convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualForceBanCmd } from "../../functions/actualCommands/actualForceBanCmd"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -15,7 +17,7 @@ const opts = [ }), ]; -export const ForceBanSlashCmd = { +export const ForceBanSlashCmd = modActionsSlashCmd({ name: "forceban", configPermission: "can_ban", description: "Force-ban the specified user, even if they aren't on the server", @@ -35,7 +37,7 @@ export const ForceBanSlashCmd = { return; } - let mod = interaction.member; + let mod = interaction.member as GuildMember; const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { channel: interaction.channel, member: interaction.member, @@ -49,7 +51,7 @@ export const ForceBanSlashCmd = { return; } - mod = options.mod; + mod = (await resolveMember(pluginData.client, pluginData.guild, options.mod.id))!; } const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; @@ -58,6 +60,14 @@ export const ForceBanSlashCmd = { return; } - actualForceBanCmd(pluginData, interaction, interaction.user.id, options.user, options.reason, attachments, mod); + actualForceBanCmd( + pluginData, + interaction, + interaction.user.id, + options.user, + options.reason ?? "", + attachments, + mod, + ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts index 6f7fa2ca..348ff047 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts @@ -1,11 +1,12 @@ -import { ChannelType } from "discord.js"; +import { ChannelType, GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; -import { UserNotificationMethod, convertDelayStringToMS } from "../../../../utils"; +import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -33,7 +34,7 @@ const opts = [ }), ]; -export const ForceMuteSlashCmd = { +export const ForceMuteSlashCmd = modActionsSlashCmd({ name: "forcemute", configPermission: "can_mute", description: "Force-mute the specified user, even if they're not on the server", @@ -53,7 +54,7 @@ export const ForceMuteSlashCmd = { return; } - let mod = interaction.member; + let mod = interaction.member as GuildMember; let ppId: string | undefined; const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { channel: interaction.channel, @@ -68,7 +69,7 @@ export const ForceMuteSlashCmd = { return; } - mod = options.mod; + mod = (await resolveMember(pluginData.client, pluginData.guild, options.mod.id))!; ppId = interaction.user.id; } @@ -94,8 +95,8 @@ export const ForceMuteSlashCmd = { mod, ppId, convertedTime, - options.reason, + options.reason ?? "", contactMethods, ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts index 8ea323fe..326d5b73 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts @@ -1,9 +1,11 @@ +import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; -import { convertDelayStringToMS } from "../../../../utils"; +import { convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -16,7 +18,7 @@ const opts = [ }), ]; -export const ForceUnmuteSlashCmd = { +export const ForceUnmuteSlashCmd = modActionsSlashCmd({ name: "forceunmute", configPermission: "can_mute", description: "Force-unmute the specified user, even if they're not on the server", @@ -36,7 +38,7 @@ export const ForceUnmuteSlashCmd = { return; } - let mod = interaction.member; + let mod = interaction.member as GuildMember; let ppId: string | undefined; const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { channel: interaction.channel, @@ -51,7 +53,7 @@ export const ForceUnmuteSlashCmd = { return; } - mod = options.mod; + mod = (await resolveMember(pluginData.client, pluginData.guild, options.mod.id))!; ppId = interaction.user.id; } @@ -61,6 +63,6 @@ export const ForceUnmuteSlashCmd = { return; } - actualUnmuteCmd(pluginData, interaction, options.user, attachments, mod, ppId, convertedTime, options.reason); + actualUnmuteCmd(pluginData, interaction, options.user, attachments, mod, ppId, convertedTime, options.reason ?? ""); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts index 95f48580..a501a5b1 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts @@ -1,7 +1,8 @@ import { slashOptions } from "knub"; import { actualHideCaseCmd } from "../../functions/actualCommands/actualHideCaseCmd"; +import { modActionsSlashCmd } from "../../types"; -export const HideCaseSlashCmd = { +export const HideCaseSlashCmd = modActionsSlashCmd({ name: "hidecase", configPermission: "can_hidecase", description: "Hide the specified case so it doesn't appear in !cases or !info", @@ -13,6 +14,6 @@ export const HideCaseSlashCmd = { async run({ interaction, options, pluginData }) { await interaction.deferReply({ ephemeral: true }); - actualHideCaseCmd(pluginData, interaction, options["case-number"].split(/[\s,]+/).map(Number)); + actualHideCaseCmd(pluginData, interaction, options["case-number"].split(/\D+/).map(Number)); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts index ce0a659b..4776d093 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts @@ -1,11 +1,12 @@ -import { ChannelType } from "discord.js"; +import { ChannelType, GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; -import { UserNotificationMethod } from "../../../../utils"; +import { UserNotificationMethod, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualKickCmd } from "../../functions/actualCommands/actualKickCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -37,7 +38,7 @@ const opts = [ }), ]; -export const KickSlashCmd = { +export const KickSlashCmd = modActionsSlashCmd({ name: "kick", configPermission: "can_kick", description: "Kick the specified member", @@ -57,7 +58,7 @@ export const KickSlashCmd = { return; } - let mod = interaction.member; + let mod = interaction.member as GuildMember; const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { channel: interaction.channel, member: interaction.member, @@ -71,7 +72,7 @@ export const KickSlashCmd = { return; } - mod = options.mod; + mod = (await resolveMember(pluginData.client, pluginData.guild, options.mod.id))!; } let contactMethods: UserNotificationMethod[] | undefined; @@ -85,7 +86,7 @@ export const KickSlashCmd = { actualKickCmd( pluginData, interaction, - interaction.member, + interaction.member as GuildMember, options.user, options.reason || "", attachments, @@ -94,4 +95,4 @@ export const KickSlashCmd = { options.clean, ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts index ab8ea1d1..de374434 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts @@ -1,7 +1,9 @@ +import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMassBanCmd } from "../../functions/actualCommands/actualMassBanCmd"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -12,7 +14,7 @@ const opts = [ }), ]; -export const MassBanSlashCmd = { +export const MassBanSlashCmd = modActionsSlashCmd({ name: "massban", configPermission: "can_massban", description: "Mass-ban a list of user IDs", @@ -39,10 +41,10 @@ export const MassBanSlashCmd = { actualMassBanCmd( pluginData, interaction, - options["user-ids"].split(/[\s,\r\n]+/), - interaction.member, + options["user-ids"].split(/\D+/), + interaction.member as GuildMember, options.reason || "", attachments, ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts index 6f2c18ba..ecdadbc7 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts @@ -1,7 +1,9 @@ +import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMassMuteCmd } from "../../functions/actualCommands/actualMassMuteCmd"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -12,7 +14,7 @@ const opts = [ }), ]; -export const MassMuteSlashSlashCmd = { +export const MassMuteSlashSlashCmd = modActionsSlashCmd({ name: "massmute", configPermission: "can_massmute", description: "Mass-mute a list of user IDs", @@ -39,10 +41,10 @@ export const MassMuteSlashSlashCmd = { actualMassMuteCmd( pluginData, interaction, - options["user-ids"].split(/[\s,\r\n]+/), - interaction.member, + options["user-ids"].split(/\D+/), + interaction.member as GuildMember, options.reason || "", attachments, ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts index da079dfd..1a2cf558 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts @@ -1,7 +1,9 @@ +import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMassUnbanCmd } from "../../functions/actualCommands/actualMassUnbanCmd"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -12,7 +14,7 @@ const opts = [ }), ]; -export const MassUnbanSlashCmd = { +export const MassUnbanSlashCmd = modActionsSlashCmd({ name: "massunban", configPermission: "can_massunban", description: "Mass-unban a list of user IDs", @@ -40,9 +42,9 @@ export const MassUnbanSlashCmd = { pluginData, interaction, options["user-ids"].split(/[\s,\r\n]+/), - interaction.member, + interaction.member as GuildMember, options.reason || "", attachments, ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts index f20585a9..5913d67e 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts @@ -1,4 +1,4 @@ -import { ChannelType } from "discord.js"; +import { ChannelType, GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; @@ -8,6 +8,7 @@ import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -35,7 +36,7 @@ const opts = [ }), ]; -export const MuteSlashCmd = { +export const MuteSlashCmd = modActionsSlashCmd({ name: "mute", configPermission: "can_mute", description: "Mute the specified member", @@ -61,7 +62,7 @@ export const MuteSlashCmd = { const reply = await waitForButtonConfirm( interaction, { content: "User not found on the server, forcemute instead?" }, - { confirmText: "Yes", cancelText: "No", restrictToId: interaction.member.id }, + { confirmText: "Yes", cancelText: "No", restrictToId: interaction.user.id }, ); if (!reply) { @@ -74,12 +75,12 @@ export const MuteSlashCmd = { } // Make sure we're allowed to mute this member - if (memberToMute && !canActOn(pluginData, interaction.member, memberToMute)) { + if (memberToMute && !canActOn(pluginData, interaction.member as GuildMember, memberToMute)) { pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot mute: insufficient permissions"); return; } - let mod = interaction.member; + let mod = interaction.member as GuildMember; let ppId: string | undefined; const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { channel: interaction.channel, @@ -94,7 +95,7 @@ export const MuteSlashCmd = { return; } - mod = options.mod; + mod = (await resolveMember(pluginData.client, pluginData.guild, options.mod.id))!; ppId = interaction.user.id; } @@ -124,4 +125,4 @@ export const MuteSlashCmd = { contactMethods, ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts index edcf60e9..8962be11 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts @@ -2,6 +2,7 @@ import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualNoteCmd } from "../../functions/actualCommands/actualNoteCmd"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -12,7 +13,7 @@ const opts = [ }), ]; -export const NoteSlashCmd = { +export const NoteSlashCmd = modActionsSlashCmd({ name: "note", configPermission: "can_note", description: "Add a note to the specified user", @@ -34,4 +35,4 @@ export const NoteSlashCmd = { actualNoteCmd(pluginData, interaction, interaction.user, attachments, options.user, options.note || ""); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts index 1a8a2181..954a90ae 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts @@ -1,8 +1,11 @@ +import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; +import { resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualUnbanCmd } from "../../functions/actualCommands/actualUnbanCmd"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -14,7 +17,7 @@ const opts = [ }), ]; -export const UnbanSlashCmd = { +export const UnbanSlashCmd = modActionsSlashCmd({ name: "unban", configPermission: "can_unban", description: "Unban the specified member", @@ -34,7 +37,7 @@ export const UnbanSlashCmd = { return; } - let mod = interaction.member; + let mod = interaction.member as GuildMember; const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { channel: interaction.channel, member: interaction.member, @@ -48,9 +51,9 @@ export const UnbanSlashCmd = { return; } - mod = options.mod; + mod = (await resolveMember(pluginData.client, pluginData.guild, options.mod.id))!; } - actualUnbanCmd(pluginData, interaction, interaction.user.id, options.user, options.reason, attachments, mod); + actualUnbanCmd(pluginData, interaction, interaction.user.id, options.user, options.reason ?? "", attachments, mod); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts index 92d3c0fb..2dbdc309 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts @@ -1,7 +1,8 @@ import { slashOptions } from "knub"; import { actualUnhideCaseCmd } from "../../functions/actualCommands/actualUnhideCaseCmd"; +import { modActionsSlashCmd } from "../../types"; -export const UnhideCaseSlashCmd = { +export const UnhideCaseSlashCmd = modActionsSlashCmd({ name: "unhidecase", configPermission: "can_hidecase", description: "Un-hide the specified case", @@ -13,6 +14,6 @@ export const UnhideCaseSlashCmd = { async run({ interaction, options, pluginData }) { await interaction.deferReply({ ephemeral: true }); - actualUnhideCaseCmd(pluginData, interaction, options["case-number"].split(/[\s,]+/).map(Number)); + actualUnhideCaseCmd(pluginData, interaction, options["case-number"].split(/\D+/).map(Number)); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts index df57fa05..b3ab730c 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts @@ -1,3 +1,4 @@ +import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { convertDelayStringToMS, resolveMember } from "../../../../utils"; @@ -7,6 +8,7 @@ import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; import { isBanned } from "../../functions/isBanned"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -19,7 +21,7 @@ const opts = [ }), ]; -export const UnmuteSlashCmd = { +export const UnmuteSlashCmd = modActionsSlashCmd({ name: "unmute", configPermission: "can_mute", description: "Unmute the specified member", @@ -79,12 +81,12 @@ export const UnmuteSlashCmd = { } // Make sure we're allowed to unmute this member - if (memberToUnmute && !canActOn(pluginData, interaction.member, memberToUnmute)) { + if (memberToUnmute && !canActOn(pluginData, interaction.member as GuildMember, memberToUnmute)) { pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot unmute: insufficient permissions"); return; } - let mod = interaction.member; + let mod = interaction.member as GuildMember; let ppId: string | undefined; const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { channel: interaction.channel, @@ -99,7 +101,7 @@ export const UnmuteSlashCmd = { return; } - mod = options.mod; + mod = (await resolveMember(pluginData.client, pluginData.guild, options.mod.id))!; ppId = interaction.user.id; } @@ -111,4 +113,4 @@ export const UnmuteSlashCmd = { actualUnmuteCmd(pluginData, interaction, options.user, attachments, mod, ppId, convertedTime, options.reason); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts b/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts index a1a6cabf..2316f82d 100644 --- a/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts @@ -1,6 +1,7 @@ import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { updateCase } from "../../functions/updateCase"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_UPDATE } from "../constants"; const opts = [ @@ -12,7 +13,7 @@ const opts = [ }), ]; -export const UpdateSlashCmd = { +export const UpdateSlashCmd = modActionsSlashCmd({ name: "update", configPermission: "can_note", description: "Update the specified case (or your latest case) by adding more notes to it", @@ -27,9 +28,9 @@ export const UpdateSlashCmd = { pluginData, interaction, interaction.user, - options.caseNumber, - options.note, + options["case-number"] ? Number(options["case-number"]) : null, + options.reason ?? "", retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_UPDATE, options, "attachment"), ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts index 7295551b..180d52c8 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts @@ -1,4 +1,4 @@ -import { ChannelType } from "discord.js"; +import { ChannelType, GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, resolveMember } from "../../../../utils"; @@ -7,6 +7,7 @@ import { CommonPlugin } from "../../../Common/CommonPlugin"; import { actualWarnCmd } from "../../functions/actualCommands/actualWarnCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; +import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; const opts = [ @@ -33,7 +34,7 @@ const opts = [ }), ]; -export const WarnSlashCmd = { +export const WarnSlashCmd = modActionsSlashCmd({ name: "warn", configPermission: "can_warn", description: "Send a warning to the specified user", @@ -67,12 +68,12 @@ export const WarnSlashCmd = { } // Make sure we're allowed to warn this member - if (!canActOn(pluginData, interaction.member, memberToWarn)) { + if (!canActOn(pluginData, interaction.member as GuildMember, memberToWarn)) { await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot warn: insufficient permissions"); return; } - let mod = interaction.member; + let mod = interaction.member as GuildMember; const canActAsOther = await hasPermission(pluginData, "can_act_as_other", { channel: interaction.channel, member: interaction.member, @@ -86,7 +87,7 @@ export const WarnSlashCmd = { return; } - mod = options.mod; + mod = (await resolveMember(pluginData.client, pluginData.guild, options.mod.id))!; } let contactMethods: UserNotificationMethod[] | undefined; @@ -108,4 +109,4 @@ export const WarnSlashCmd = { contactMethods, ); }, -}; +}); diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts index a1767be9..f8ad0158 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts @@ -20,7 +20,7 @@ export async function actualKickCmd( attachments: Attachment[], mod: GuildMember, contactMethods?: UserNotificationMethod[], - clean?: boolean, + clean?: boolean | null, ) { if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { return; diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts index d93e10d0..2cff62ff 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts @@ -29,7 +29,7 @@ export async function actualMuteCmd( mod: GuildMember, ppId?: string, time?: number, - reason?: string, + reason?: string | null, contactMethods?: UserNotificationMethod[], ) { if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts b/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts index 22f79eb6..11a668b4 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts +++ b/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts @@ -16,7 +16,7 @@ export async function actualUnmuteCmd( mod: GuildMember, ppId?: string, time?: number, - reason?: string, + reason?: string | null, ) { if (await handleAttachmentLinkDetectionAndGetRestriction(pluginData, context, reason)) { return; diff --git a/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts b/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts index a9503333..5ddc222b 100644 --- a/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts +++ b/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts @@ -2,8 +2,8 @@ import { GuildTextBasedChannel } from "discord.js"; import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils"; export function readContactMethodsFromArgs(args: { - notify?: string; - "notify-channel"?: GuildTextBasedChannel; + notify?: string | null; + "notify-channel"?: GuildTextBasedChannel | null; }): 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 08f11230..e4011fb7 100644 --- a/backend/src/plugins/ModActions/functions/updateCase.ts +++ b/backend/src/plugins/ModActions/functions/updateCase.ts @@ -13,7 +13,7 @@ export async function updateCase( pluginData: GuildPluginData, context: Message | ChatInputCommandInteraction, author: User, - caseNumber?: number, + caseNumber?: number | null, note = "", attachments: Attachment[] = [], ) { diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index ec2d29ea..ee128986 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -1,6 +1,12 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { EventEmitter } from "events"; -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, guildPluginSlashGroup } from "knub"; +import { + BasePluginType, + guildPluginEventListener, + guildPluginMessageCommand, + guildPluginSlashCommand, + guildPluginSlashGroup, +} from "knub"; import z from "zod"; import { Queue } from "../../Queue"; import { GuildCases } from "../../data/GuildCases"; @@ -152,4 +158,5 @@ export type ModActionType = "note" | "warn" | "mute" | "unmute" | "kick" | "ban" export const modActionsMsgCmd = guildPluginMessageCommand(); export const modActionsSlashGroup = guildPluginSlashGroup(); +export const modActionsSlashCmd = guildPluginSlashCommand(); export const modActionsEvt = guildPluginEventListener(); From 893a77d5620a700ca71707ea9ea979e7c5aa7bea Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Mon, 15 Apr 2024 15:51:45 +0200 Subject: [PATCH 28/30] Fixes, refactoring and PR feedback --- backend/src/api/start.ts | 8 +-- .../AutoReactions/AutoReactionsPlugin.ts | 5 ++ .../commands/DisableAutoReactionsCmd.ts | 4 +- .../commands/NewAutoReactionsCmd.ts | 20 +++---- backend/src/plugins/AutoReactions/types.ts | 4 +- backend/src/plugins/Automod/AutomodPlugin.ts | 5 ++ .../Automod/commands/AntiraidClearCmd.ts | 3 +- .../Automod/commands/SetAntiraidCmd.ts | 5 +- backend/src/plugins/Automod/types.ts | 5 +- .../plugins/BotControl/BotControlPlugin.ts | 3 +- .../commands/AddDashboardUserCmd.ts | 9 +-- .../commands/AddServerFromInviteCmd.ts | 12 ++-- .../BotControl/commands/AllowServerCmd.ts | 8 +-- .../BotControl/commands/ChannelToServerCmd.ts | 2 +- .../BotControl/commands/DisallowServerCmd.ts | 4 +- .../BotControl/commands/EligibleCmd.ts | 6 +- .../BotControl/commands/LeaveServerCmd.ts | 6 +- .../commands/ListDashboardPermsCmd.ts | 19 +++---- .../commands/ListDashboardUsersCmd.ts | 13 ++--- .../commands/RateLimitPerformanceCmd.ts | 2 +- .../commands/ReloadGlobalPluginsCmd.ts | 2 +- .../BotControl/commands/ReloadServerCmd.ts | 6 +- .../commands/RemoveDashboardUserCmd.ts | 11 ++-- backend/src/plugins/BotControl/types.ts | 2 +- .../ChannelArchiver/ChannelArchiverPlugin.ts | 5 ++ .../commands/ArchiveChannelCmd.ts | 2 +- backend/src/plugins/ChannelArchiver/types.ts | 9 ++- backend/src/plugins/Common/CommonPlugin.ts | 55 +++++++++++-------- backend/src/plugins/Common/info.ts | 8 +++ backend/src/plugins/Common/types.ts | 1 + .../src/plugins/ContextMenus/actions/ban.ts | 27 +++------ .../src/plugins/ContextMenus/actions/clean.ts | 11 +--- .../src/plugins/ContextMenus/actions/mute.ts | 47 ++++++---------- .../src/plugins/ContextMenus/actions/note.ts | 47 +++++++--------- .../plugins/ContextMenus/actions/update.ts | 6 +- .../src/plugins/ContextMenus/actions/warn.ts | 43 ++++++--------- .../commands/ModMenuUserCtxCmd.ts | 20 ++----- .../src/plugins/Counters/CountersPlugin.ts | 5 ++ .../Counters/commands/AddCounterCmd.ts | 20 +++---- .../Counters/commands/CountersListCmd.ts | 2 +- .../commands/ResetAllCounterValuesCmd.ts | 12 ++-- .../Counters/commands/ResetCounterCmd.ts | 16 +++--- .../Counters/commands/SetCounterCmd.ts | 22 ++++---- .../Counters/commands/ViewCounterCmd.ts | 16 +++--- backend/src/plugins/Counters/types.ts | 4 +- .../CustomEvents/CustomEventsPlugin.ts | 5 ++ .../CustomEvents/functions/runEvent.ts | 2 +- backend/src/plugins/CustomEvents/types.ts | 4 +- .../plugins/LocateUser/LocateUserPlugin.ts | 5 ++ .../plugins/LocateUser/commands/FollowCmd.ts | 12 +--- .../LocateUser/commands/ListFollowCmd.ts | 6 +- backend/src/plugins/LocateUser/types.ts | 4 +- .../plugins/LocateUser/utils/moveMember.ts | 8 +-- .../src/plugins/LocateUser/utils/sendWhere.ts | 2 +- .../MessageSaver/MessageSaverPlugin.ts | 5 ++ .../MessageSaver/commands/SaveMessagesToDB.ts | 6 +- .../MessageSaver/commands/SavePinsToDB.ts | 6 +- backend/src/plugins/MessageSaver/types.ts | 4 +- .../plugins/ModActions/ModActionsPlugin.ts | 6 +- .../commands/addcase/AddCaseMsgCmd.ts | 9 ++- .../commands/addcase/AddCaseSlashCmd.ts | 10 ++-- .../addcase}/actualAddCaseCmd.ts | 21 +++---- .../ModActions/commands/ban/BanMsgCmd.ts | 9 ++- .../ModActions/commands/ban/BanSlashCmd.ts | 24 ++++---- .../ban}/actualBanCmd.ts | 36 ++++++------ .../ModActions/commands/case/CaseMsgCmd.ts | 2 +- .../ModActions/commands/case/CaseSlashCmd.ts | 2 +- .../case}/actualCaseCmd.ts | 5 +- .../commands/cases/CasesModMsgCmd.ts | 2 +- .../commands/cases/CasesSlashCmd.ts | 2 +- .../commands/cases/CasesUserMsgCmd.ts | 5 +- .../cases}/actualCasesCmd.ts | 11 ++-- .../commands/deletecase/DeleteCaseMsgCmd.ts | 2 +- .../commands/deletecase/DeleteCaseSlashCmd.ts | 2 +- .../deletecase}/actualDeleteCaseCmd.ts | 17 +++--- .../commands/forceban/ForceBanMsgCmd.ts | 11 ++-- .../commands/forceban/ForceBanSlashCmd.ts | 22 +++++--- .../forceban}/actualForceBanCmd.ts | 13 ++--- .../commands/forcemute/ForceMuteMsgCmd.ts | 11 ++-- .../commands/forcemute/ForceMuteSlashCmd.ts | 24 ++++---- .../commands/forceunmute/ForceUnmuteMsgCmd.ts | 11 ++-- .../forceunmute/ForceUnmuteSlashCmd.ts | 22 +++++--- .../commands/hidecase/HideCaseMsgCmd.ts | 2 +- .../commands/hidecase/HideCaseSlashCmd.ts | 2 +- .../hidecase}/actualHideCaseCmd.ts | 7 +-- .../ModActions/commands/kick/KickMsgCmd.ts | 9 ++- .../ModActions/commands/kick/KickSlashCmd.ts | 22 +++++--- .../kick}/actualKickCmd.ts | 29 +++++----- .../commands/massban/MassBanMsgCmd.ts | 5 +- .../commands/massban/MassBanSlashCmd.ts | 13 +++-- .../massban}/actualMassBanCmd.ts | 38 ++++++------- .../commands/massmute/MassMuteMsgCmd.ts | 5 +- .../commands/massmute/MassMuteSlashCmd.ts | 13 +++-- .../massmute}/actualMassMuteCmd.ts | 22 ++++---- .../commands/massunban/MassUnbanMsgCmd.ts | 5 +- .../commands/massunban/MassUnbanSlashCmd.ts | 13 +++-- .../massunban}/actualMassUnbanCmd.ts | 26 ++++----- .../ModActions/commands/mute/MuteMsgCmd.ts | 20 +++---- .../ModActions/commands/mute/MuteSlashCmd.ts | 30 +++++----- .../mute}/actualMuteCmd.ts | 18 +++--- .../ModActions/commands/note/NoteMsgCmd.ts | 7 +-- .../ModActions/commands/note/NoteSlashCmd.ts | 13 +++-- .../note}/actualNoteCmd.ts | 9 +-- .../ModActions/commands/unban/UnbanMsgCmd.ts | 7 +-- .../commands/unban/UnbanSlashCmd.ts | 20 ++++--- .../unban}/actualUnbanCmd.ts | 16 +++--- .../commands/unhidecase/UnhideCaseMsgCmd.ts | 2 +- .../commands/unhidecase/UnhideCaseSlashCmd.ts | 2 +- .../unhidecase}/actualUnhideCaseCmd.ts | 10 ++-- .../commands/unmute/UnmuteMsgCmd.ts | 20 +++---- .../commands/unmute/UnmuteSlashCmd.ts | 40 ++++++++------ .../unmute}/actualUnmuteCmd.ts | 11 ++-- .../ModActions/commands/warn/WarnMsgCmd.ts | 13 ++--- .../ModActions/commands/warn/WarnSlashCmd.ts | 28 ++++++---- .../warn}/actualWarnCmd.ts | 15 ++--- .../functions/attachmentLinkReaction.ts | 17 +++--- .../functions/formatReasonForAttachments.ts | 14 +---- .../ModActions/functions/updateCase.ts | 7 +-- backend/src/plugins/ModActions/types.ts | 8 ++- backend/src/plugins/Mutes/MutesPlugin.ts | 5 ++ .../Mutes/commands/ClearBannedMutesCmd.ts | 2 +- .../plugins/Mutes/commands/ClearMutesCmd.ts | 8 +-- .../commands/ClearMutesWithoutRoleCmd.ts | 4 +- backend/src/plugins/Mutes/types.ts | 5 +- .../plugins/NameHistory/NameHistoryPlugin.ts | 5 ++ .../plugins/NameHistory/commands/NamesCmd.ts | 2 +- backend/src/plugins/NameHistory/types.ts | 4 +- .../PingableRoles/PingableRolesPlugin.ts | 5 ++ .../commands/PingableRoleDisableCmd.ts | 8 +-- .../commands/PingableRoleEnableCmd.ts | 8 +-- backend/src/plugins/PingableRoles/types.ts | 4 +- backend/src/plugins/Post/PostPlugin.ts | 5 ++ backend/src/plugins/Post/commands/EditCmd.ts | 6 +- .../src/plugins/Post/commands/EditEmbedCmd.ts | 10 ++-- .../src/plugins/Post/commands/PostEmbedCmd.ts | 8 +-- .../Post/commands/ScheduledPostsDeleteCmd.ts | 4 +- .../Post/commands/ScheduledPostsShowCmd.ts | 2 +- backend/src/plugins/Post/types.ts | 4 +- .../src/plugins/Post/util/actualPostCmd.ts | 38 +++++-------- .../ReactionRoles/ReactionRolesPlugin.ts | 5 ++ .../commands/ClearReactionRolesCmd.ts | 6 +- .../commands/InitReactionRolesCmd.ts | 24 +++----- .../commands/RefreshReactionRolesCmd.ts | 4 +- backend/src/plugins/ReactionRoles/types.ts | 5 +- .../src/plugins/Reminders/RemindersPlugin.ts | 5 ++ .../plugins/Reminders/commands/RemindCmd.ts | 8 +-- .../Reminders/commands/RemindersCmd.ts | 2 +- .../Reminders/commands/RemindersDeleteCmd.ts | 4 +- backend/src/plugins/Reminders/types.ts | 4 +- .../plugins/RoleButtons/RoleButtonsPlugin.ts | 5 ++ .../RoleButtons/commands/resetButtons.ts | 6 +- backend/src/plugins/RoleButtons/types.ts | 4 +- backend/src/plugins/Roles/RolesPlugin.ts | 5 ++ .../src/plugins/Roles/commands/AddRoleCmd.ts | 16 ++---- .../plugins/Roles/commands/MassAddRoleCmd.ts | 10 ++-- .../Roles/commands/MassRemoveRoleCmd.ts | 10 ++-- .../plugins/Roles/commands/RemoveRoleCmd.ts | 16 ++---- backend/src/plugins/Roles/types.ts | 4 +- .../SelfGrantableRolesPlugin.ts | 5 ++ .../SelfGrantableRoles/commands/RoleAddCmd.ts | 18 +++--- .../commands/RoleRemoveCmd.ts | 38 +++++-------- .../src/plugins/SelfGrantableRoles/types.ts | 4 +- .../src/plugins/Slowmode/SlowmodePlugin.ts | 5 ++ .../Slowmode/commands/SlowmodeClearCmd.ts | 14 ++--- .../Slowmode/commands/SlowmodeSetCmd.ts | 30 +++------- backend/src/plugins/Slowmode/types.ts | 4 +- .../Slowmode/util/actualDisableSlowmodeCmd.ts | 18 +++--- .../src/plugins/Starboard/StarboardPlugin.ts | 5 ++ .../Starboard/commands/MigratePinsCmd.ts | 8 +-- backend/src/plugins/Starboard/types.ts | 4 +- backend/src/plugins/Tags/TagsPlugin.ts | 5 ++ .../src/plugins/Tags/commands/TagCreateCmd.ts | 4 +- .../src/plugins/Tags/commands/TagDeleteCmd.ts | 4 +- .../src/plugins/Tags/commands/TagEvalCmd.ts | 4 +- .../src/plugins/Tags/commands/TagSourceCmd.ts | 6 +- backend/src/plugins/Tags/types.ts | 4 +- .../plugins/TimeAndDate/TimeAndDatePlugin.ts | 5 ++ .../TimeAndDate/commands/ResetTimezoneCmd.ts | 4 +- .../TimeAndDate/commands/SetTimezoneCmd.ts | 4 +- backend/src/plugins/TimeAndDate/types.ts | 4 +- backend/src/plugins/Utility/UtilityPlugin.ts | 6 +- .../src/plugins/Utility/commands/AvatarCmd.ts | 2 +- .../Utility/commands/ChannelInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/CleanCmd.ts | 40 +++++--------- .../plugins/Utility/commands/ContextCmd.ts | 6 +- .../plugins/Utility/commands/EmojiInfoCmd.ts | 4 +- .../src/plugins/Utility/commands/InfoCmd.ts | 10 ++-- .../plugins/Utility/commands/InviteInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/JumboCmd.ts | 4 +- .../Utility/commands/MessageInfoCmd.ts | 4 +- .../plugins/Utility/commands/NicknameCmd.ts | 10 ++-- .../Utility/commands/NicknameResetCmd.ts | 2 +- .../src/plugins/Utility/commands/RolesCmd.ts | 2 +- .../plugins/Utility/commands/ServerInfoCmd.ts | 2 +- .../src/plugins/Utility/commands/SourceCmd.ts | 4 +- .../plugins/Utility/commands/UserInfoCmd.ts | 2 +- .../Utility/commands/VcdisconnectCmd.ts | 13 +++-- .../src/plugins/Utility/commands/VcmoveCmd.ts | 54 ++++++++---------- backend/src/plugins/Utility/search.ts | 13 ++--- backend/src/plugins/Utility/types.ts | 5 +- backend/src/utils/loadYamlSafely.ts | 2 +- backend/src/utils/waitForInteraction.ts | 12 ++-- 202 files changed, 1037 insertions(+), 1069 deletions(-) create mode 100644 backend/src/plugins/Common/info.ts rename backend/src/plugins/ModActions/{functions/actualCommands => commands/addcase}/actualAddCaseCmd.ts (76%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/ban}/actualBanCmd.ts (85%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/case}/actualCaseCmd.ts (74%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/cases}/actualCasesCmd.ts (97%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/deletecase}/actualDeleteCaseCmd.ts (85%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/forceban}/actualForceBanCmd.ts (83%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/hidecase}/actualHideCaseCmd.ts (81%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/kick}/actualKickCmd.ts (72%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/massban}/actualMassBanCmd.ts (85%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/massmute}/actualMassMuteCmd.ts (80%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/massunban}/actualMassUnbanCmd.ts (84%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/mute}/actualMuteCmd.ts (85%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/note}/actualNoteCmd.ts (85%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/unban}/actualUnbanCmd.ts (81%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/unhidecase}/actualUnhideCaseCmd.ts (73%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/unmute}/actualUnmuteCmd.ts (81%) rename backend/src/plugins/ModActions/{functions/actualCommands => commands/warn}/actualWarnCmd.ts (83%) diff --git a/backend/src/api/start.ts b/backend/src/api/start.ts index 088c8ba9..e009e393 100644 --- a/backend/src/api/start.ts +++ b/backend/src/api/start.ts @@ -28,10 +28,10 @@ app.use(multer().none()); const rootRouter = express.Router(); -initAuth(app); -initGuildsAPI(app); -initArchives(app); -initDocs(app); +initAuth(rootRouter); +initGuildsAPI(rootRouter); +initArchives(rootRouter); +initDocs(rootRouter); // Default route rootRouter.get("/", (req, res) => { diff --git a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts index 6c24b296..df5ebd3a 100644 --- a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts +++ b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts @@ -6,6 +6,7 @@ import { DisableAutoReactionsCmd } from "./commands/DisableAutoReactionsCmd"; import { NewAutoReactionsCmd } from "./commands/NewAutoReactionsCmd"; import { AddReactionsEvt } from "./events/AddReactionsEvt"; import { AutoReactionsPluginType, zAutoReactionsConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -50,4 +51,8 @@ export const AutoReactionsPlugin = guildPlugin()({ state.autoReactions = GuildAutoReactions.getGuildInstance(guild.id); state.cache = new Map(); }, + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + } }); diff --git a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts index ec3417d4..f6539174 100644 --- a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts @@ -14,12 +14,12 @@ export const DisableAutoReactionsCmd = autoReactionsCmd({ async run({ message: msg, args, pluginData }) { const autoReaction = await pluginData.state.autoReactions.getForChannel(args.channelId); if (!autoReaction) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Auto-reactions aren't enabled in <#${args.channelId}>`); + void pluginData.state.common.sendErrorMessage(msg, `Auto-reactions aren't enabled in <#${args.channelId}>`); return; } await pluginData.state.autoReactions.removeFromChannel(args.channelId); pluginData.state.cache.delete(args.channelId); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Auto-reactions disabled in <#${args.channelId}>`); + void pluginData.state.common.sendSuccessMessage(msg, `Auto-reactions disabled in <#${args.channelId}>`); }, }); diff --git a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts index 250df4f0..7f3355fb 100644 --- a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts @@ -25,20 +25,16 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; const missingPermissions = getMissingChannelPermissions(me, args.channel, requiredPermissions); if (missingPermissions) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - msg, - `Cannot set auto-reactions for that channel. ${missingPermissionError(missingPermissions)}`, - ); + pluginData.state.common.sendErrorMessage( + msg, + `Cannot set auto-reactions for that channel. ${missingPermissionError(missingPermissions)}`, + ); return; } for (const reaction of args.reactions) { if (!isEmoji(reaction)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "One or more of the specified reactions were invalid!"); + void pluginData.state.common.sendErrorMessage(msg, "One or more of the specified reactions were invalid!"); return; } @@ -48,9 +44,7 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ if (customEmojiMatch) { // Custom emoji if (!canUseEmoji(pluginData.client, customEmojiMatch[2])) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "I can only use regular emojis and custom emojis from this server"); + pluginData.state.common.sendErrorMessage(msg, "I can only use regular emojis and custom emojis from this server"); return; } @@ -65,6 +59,6 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ await pluginData.state.autoReactions.set(args.channel.id, finalReactions); pluginData.state.cache.delete(args.channel.id); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Auto-reactions set for <#${args.channel.id}>`); + void pluginData.state.common.sendSuccessMessage(msg, `Auto-reactions set for <#${args.channel.id}>`); }, }); diff --git a/backend/src/plugins/AutoReactions/types.ts b/backend/src/plugins/AutoReactions/types.ts index 996fba8d..d060d59a 100644 --- a/backend/src/plugins/AutoReactions/types.ts +++ b/backend/src/plugins/AutoReactions/types.ts @@ -1,9 +1,10 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildAutoReactions } from "../../data/GuildAutoReactions"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { AutoReaction } from "../../data/entities/AutoReaction"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zAutoReactionsConfig = z.strictObject({ can_manage: z.boolean(), @@ -16,6 +17,7 @@ export interface AutoReactionsPluginType extends BasePluginType { savedMessages: GuildSavedMessages; autoReactions: GuildAutoReactions; cache: Map; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Automod/AutomodPlugin.ts b/backend/src/plugins/Automod/AutomodPlugin.ts index 33956590..5da233a1 100644 --- a/backend/src/plugins/Automod/AutomodPlugin.ts +++ b/backend/src/plugins/Automod/AutomodPlugin.ts @@ -32,6 +32,7 @@ import { clearOldRecentNicknameChanges } from "./functions/clearOldNicknameChang import { clearOldRecentActions } from "./functions/clearOldRecentActions"; import { clearOldRecentSpam } from "./functions/clearOldRecentSpam"; import { AutomodPluginType, zAutomodConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions = { config: { @@ -117,6 +118,10 @@ export const AutomodPlugin = guildPlugin()({ state.cachedAntiraidLevel = await state.antiraidLevels.get(); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + async afterLoad(pluginData) { const { state } = pluginData; diff --git a/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts b/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts index 983a1f99..85f9bbcb 100644 --- a/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts +++ b/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts @@ -1,5 +1,4 @@ import { guildPluginMessageCommand } from "knub"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { setAntiraidLevel } from "../functions/setAntiraidLevel"; import { AutomodPluginType } from "../types"; @@ -9,6 +8,6 @@ export const AntiraidClearCmd = guildPluginMessageCommand()({ async run({ pluginData, message }) { await setAntiraidLevel(pluginData, null, message.author); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(message, "Anti-raid turned **off**"); + void pluginData.state.common.sendSuccessMessage(message, "Anti-raid turned **off**"); }, }); diff --git a/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts b/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts index 91cbacd6..46c2106f 100644 --- a/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts +++ b/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts @@ -1,6 +1,5 @@ import { guildPluginMessageCommand } from "knub"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { setAntiraidLevel } from "../functions/setAntiraidLevel"; import { AutomodPluginType } from "../types"; @@ -15,11 +14,11 @@ export const SetAntiraidCmd = guildPluginMessageCommand()({ async run({ pluginData, message, args }) { const config = pluginData.config.get(); if (!config.antiraid_levels.includes(args.level)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown anti-raid level"); + pluginData.state.common.sendErrorMessage(message, "Unknown anti-raid level"); return; } await setAntiraidLevel(pluginData, args.level, message.author); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(message, `Anti-raid level set to **${args.level}**`); + pluginData.state.common.sendSuccessMessage(message, `Anti-raid level set to **${args.level}**`); }, }); diff --git a/backend/src/plugins/Automod/types.ts b/backend/src/plugins/Automod/types.ts index 6cf88ad6..75cd8daa 100644 --- a/backend/src/plugins/Automod/types.ts +++ b/backend/src/plugins/Automod/types.ts @@ -1,5 +1,5 @@ import { GuildMember, GuildTextBasedChannel, PartialGuildMember, ThreadChannel, User } from "discord.js"; -import { BasePluginType, CooldownManager } from "knub"; +import { BasePluginType, CooldownManager, pluginUtils } from "knub"; import z from "zod"; import { Queue } from "../../Queue"; import { RegExpRunner } from "../../RegExpRunner"; @@ -17,6 +17,7 @@ import { RecentActionType } from "./constants"; import { availableTriggers } from "./triggers/availableTriggers"; import Timeout = NodeJS.Timeout; +import { CommonPlugin } from "../Common/CommonPlugin"; export type ZTriggersMapHelper = { [TriggerName in keyof typeof availableTriggers]: (typeof availableTriggers)[TriggerName]["configSchema"]; @@ -139,6 +140,8 @@ export interface AutomodPluginType extends BasePluginType { modActionsListeners: Map; mutesListeners: Map; + + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/BotControl/BotControlPlugin.ts b/backend/src/plugins/BotControl/BotControlPlugin.ts index b3812e02..c1a94888 100644 --- a/backend/src/plugins/BotControl/BotControlPlugin.ts +++ b/backend/src/plugins/BotControl/BotControlPlugin.ts @@ -4,7 +4,6 @@ import { AllowedGuilds } from "../../data/AllowedGuilds"; import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; import { Configs } from "../../data/Configs"; import { GuildArchives } from "../../data/GuildArchives"; -import { CommonPlugin } from "../Common/CommonPlugin"; import { getActiveReload, resetActiveReload } from "./activeReload"; import { AddDashboardUserCmd } from "./commands/AddDashboardUserCmd"; import { AddServerFromInviteCmd } from "./commands/AddServerFromInviteCmd"; @@ -77,7 +76,7 @@ export const BotControlPlugin = globalPlugin()({ if (guild) { const channel = guild.channels.cache.get(channelId as Snowflake); if (channel instanceof TextChannel) { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(channel, "Global plugins reloaded!"); + void channel.send("Global plugins reloaded!"); } } } diff --git a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts index 5a50d1b0..8e97cf56 100644 --- a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts @@ -20,7 +20,7 @@ export const AddDashboardUserCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is not using Zeppelin"); + void msg.channel.send("Server is not using Zeppelin"); return; } @@ -38,11 +38,6 @@ export const AddDashboardUserCmd = botControlCmd({ const userNameList = args.users.map((user) => `<@!${user.id}> (**${renderUsername(user)}**, \`${user.id}\`)`); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `The following users were given dashboard access for **${guild.name}**:\n\n${userNameList}`, - ); + msg.channel.send(`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 aaeb7147..e5245bb3 100644 --- a/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts @@ -18,21 +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)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Could not resolve invite"); // :D + void msg.channel.send("Could not resolve invite"); // :D return; } const existing = await pluginData.state.allowedGuilds.find(invite.guild.id); if (existing) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is already allowed!"); + void msg.channel.send("Server is already allowed!"); return; } const { result, explanation } = await isEligible(pluginData, args.user, invite); if (!result) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Could not add server because it's not eligible: ${explanation}`); + msg.channel.send(`Could not add server because it's not eligible: ${explanation}`); return; } @@ -53,8 +51,6 @@ export const AddServerFromInviteCmd = botControlCmd({ ); } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, "Server was eligible and is now allowed to use Zeppelin!"); + msg.channel.send("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 ac843867..9d0a6cea 100644 --- a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts @@ -21,17 +21,17 @@ export const AllowServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const existing = await pluginData.state.allowedGuilds.find(args.guildId); if (existing) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is already allowed!"); + void msg.channel.send("Server is already allowed!"); return; } if (!isSnowflake(args.guildId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid server ID!"); + void msg.channel.send("Invalid server ID!"); return; } if (args.userId && !isSnowflake(args.userId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid user ID!"); + void msg.channel.send("Invalid user ID!"); return; } @@ -52,6 +52,6 @@ export const AllowServerCmd = botControlCmd({ ); } - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Server is now allowed to use Zeppelin!"); + void msg.channel.send("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 939077e2..f19a41c9 100644 --- a/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts @@ -17,7 +17,7 @@ export const ChannelToServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const channel = pluginData.client.channels.cache.get(args.channelId); if (!channel) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Channel not found in cache!"); + void msg.channel.send("Channel not found in cache!"); return; } diff --git a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts index 69ba0b4c..8a31ddf5 100644 --- a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts @@ -19,7 +19,7 @@ export const DisallowServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const existing = await pluginData.state.allowedGuilds.find(args.guildId); if (!existing) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "That server is not allowed in the first place!"); + void msg.channel.send("That server is not allowed in the first place!"); return; } @@ -28,6 +28,6 @@ export const DisallowServerCmd = botControlCmd({ .get(args.guildId as Snowflake) ?.leave() .catch(noop); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Server removed!"); + void msg.channel.send("Server removed!"); }, }); diff --git a/backend/src/plugins/BotControl/commands/EligibleCmd.ts b/backend/src/plugins/BotControl/commands/EligibleCmd.ts index bbcd5c5d..60adcea2 100644 --- a/backend/src/plugins/BotControl/commands/EligibleCmd.ts +++ b/backend/src/plugins/BotControl/commands/EligibleCmd.ts @@ -16,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)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Could not resolve invite"); + void msg.channel.send("Could not resolve invite"); return; } const { result, explanation } = await isEligible(pluginData, args.user, invite); if (result) { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Server is eligible: ${explanation}`); + void msg.channel.send(`Server is eligible: ${explanation}`); return; } - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Server is **NOT** eligible: ${explanation}`); + void msg.channel.send(`Server is **NOT** eligible: ${explanation}`); }, }); diff --git a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts index 0066a916..c22a885f 100644 --- a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts @@ -17,7 +17,7 @@ export const LeaveServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { if (!pluginData.client.guilds.cache.has(args.guildId as Snowflake)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "I am not in that guild"); + void msg.channel.send("I am not in that guild"); return; } @@ -27,10 +27,10 @@ export const LeaveServerCmd = botControlCmd({ try { await pluginData.client.guilds.cache.get(args.guildId as Snowflake)?.leave(); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Failed to leave guild: ${e.message}`); + void msg.channel.send(`Failed to leave guild: ${e.message}`); return; } - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Left guild **${guildName}**`); + void msg.channel.send(`Left guild **${guildName}**`); }, }); diff --git a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts index 0de1ff26..83f0cc37 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts @@ -16,7 +16,7 @@ export const ListDashboardPermsCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { if (!args.user && !args.guildId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Must specify at least guildId, user, or both."); + void msg.channel.send("Must specify at least guildId, user, or both."); return; } @@ -24,7 +24,7 @@ export const ListDashboardPermsCmd = botControlCmd({ if (args.guildId) { guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is not using Zeppelin"); + void msg.channel.send("Server is not using Zeppelin"); return; } } @@ -33,7 +33,7 @@ export const ListDashboardPermsCmd = botControlCmd({ if (args.user) { existingUserAssignment = await pluginData.state.apiPermissionAssignments.getByUserId(args.user.id); if (existingUserAssignment.length === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "The user has no assigned permissions."); + void msg.channel.send("The user has no assigned permissions."); return; } } @@ -54,9 +54,7 @@ export const ListDashboardPermsCmd = botControlCmd({ } if (finalMessage === "") { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `The user ${userInfo} has no assigned permissions on the specified server.`); + msg.channel.send(`The user ${userInfo} has no assigned permissions on the specified server.`); return; } // Else display all users that have permissions on the specified guild @@ -65,9 +63,7 @@ export const ListDashboardPermsCmd = botControlCmd({ const existingGuildAssignment = await pluginData.state.apiPermissionAssignments.getByGuildId(guild.id); if (existingGuildAssignment.length === 0) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `The server ${guildInfo} has no assigned permissions.`); + msg.channel.send(`The server ${guildInfo} has no assigned permissions.`); return; } @@ -80,6 +76,9 @@ export const ListDashboardPermsCmd = botControlCmd({ } } - await pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, finalMessage.trim(), {}); + await msg.channel.send({ + content: finalMessage.trim(), + allowedMentions: {}, + }); }, }); diff --git a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts index b835dfed..2892e6e6 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts @@ -14,7 +14,7 @@ export const ListDashboardUsersCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is not using Zeppelin"); + void msg.channel.send("Server is not using Zeppelin"); return; } @@ -30,12 +30,9 @@ export const ListDashboardUsersCmd = botControlCmd({ `<@!${user.id}> (**${renderUsername(user)}**, \`${user.id}\`): ${permission.permissions.join(", ")}`, ); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `The following users have dashboard access for **${guild.name}**:\n\n${userNameList.join("\n")}`, - {}, - ); + msg.channel.send({ + content: `The following users have dashboard access for **${guild.name}**:\n\n${userNameList.join("\n")}`, + allowedMentions: {}, + }); }, }); diff --git a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts index 9ac5499d..9ba9d23c 100644 --- a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts +++ b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts @@ -14,7 +14,7 @@ export const RateLimitPerformanceCmd = botControlCmd({ async run({ pluginData, message: msg }) { const logItems = getRateLimitStats(); if (logItems.length === 0) { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `No rate limits hit`); + void msg.channel.send(`No rate limits hit`); return; } diff --git a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts index ea51dc00..957fca95 100644 --- a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts @@ -15,7 +15,7 @@ export const ReloadGlobalPluginsCmd = botControlCmd({ const guildId = "guild" in message.channel ? message.channel.guild.id : null; if (!guildId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "This command can only be used in a server"); + void message.channel.send("This command can only be used in a server"); return; } diff --git a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts index 8481682e..a171af5f 100644 --- a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts @@ -17,18 +17,18 @@ export const ReloadServerCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { if (!pluginData.client.guilds.cache.has(args.guildId as Snowflake)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "I am not in that guild"); + void msg.channel.send("I am not in that guild"); return; } try { await pluginData.getKnubInstance().reloadGuild(args.guildId); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Failed to reload guild: ${e.message}`); + void msg.channel.send(`Failed to reload guild: ${e.message}`); return; } const guild = await pluginData.client.guilds.fetch(args.guildId as Snowflake); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Reloaded guild **${guild?.name || "???"}**`); + void msg.channel.send(`Reloaded guild **${guild?.name || "???"}**`); }, }); diff --git a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts index 90927a2a..502570a7 100644 --- a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts @@ -19,7 +19,7 @@ export const RemoveDashboardUserCmd = botControlCmd({ async run({ pluginData, message: msg, args }) { const guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Server is not using Zeppelin"); + void msg.channel.send("Server is not using Zeppelin"); return; } @@ -37,11 +37,8 @@ export const RemoveDashboardUserCmd = botControlCmd({ const userNameList = args.users.map((user) => `<@!${user.id}> (**${renderUsername(user)}**, \`${user.id}\`)`); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `The following users were removed from the dashboard for **${guild.name}**:\n\n${userNameList}`, - ); + msg.channel.send( + `The following users were removed from the dashboard for **${guild.name}**:\n\n${userNameList}`, + ); }, }); diff --git a/backend/src/plugins/BotControl/types.ts b/backend/src/plugins/BotControl/types.ts index 1c1ccea6..592189c1 100644 --- a/backend/src/plugins/BotControl/types.ts +++ b/backend/src/plugins/BotControl/types.ts @@ -1,4 +1,4 @@ -import { BasePluginType, globalPluginEventListener, globalPluginMessageCommand } from "knub"; +import { BasePluginType, globalPluginEventListener, globalPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { AllowedGuilds } from "../../data/AllowedGuilds"; import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; diff --git a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts index c8373aeb..b9c310d7 100644 --- a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts +++ b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts @@ -3,6 +3,7 @@ import z from "zod"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { ArchiveChannelCmd } from "./commands/ArchiveChannelCmd"; import { ChannelArchiverPluginType } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const ChannelArchiverPlugin = guildPlugin()({ name: "channel_archiver", @@ -14,4 +15,8 @@ export const ChannelArchiverPlugin = guildPlugin()({ messageCommands: [ ArchiveChannelCmd, ], + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + } }); diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index 327c6956..34bdeef7 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -38,7 +38,7 @@ export const ArchiveChannelCmd = channelArchiverCmd({ "No `-attachment-channel` specified. Continue? Attachments will not be available in the log if their message is deleted.", }); if (!confirmed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Canceled"); + void pluginData.state.common.sendErrorMessage(msg, "Canceled"); return; } } diff --git a/backend/src/plugins/ChannelArchiver/types.ts b/backend/src/plugins/ChannelArchiver/types.ts index 024edf3d..a560af39 100644 --- a/backend/src/plugins/ChannelArchiver/types.ts +++ b/backend/src/plugins/ChannelArchiver/types.ts @@ -1,5 +1,10 @@ -import { BasePluginType, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; +import { CommonPlugin } from "../Common/CommonPlugin"; -export interface ChannelArchiverPluginType extends BasePluginType {} +export interface ChannelArchiverPluginType extends BasePluginType { + state: { + common: pluginUtils.PluginPublicInterface; + } +} export const channelArchiverCmd = guildPluginMessageCommand(); diff --git a/backend/src/plugins/Common/CommonPlugin.ts b/backend/src/plugins/Common/CommonPlugin.ts index 92c58b63..144c355c 100644 --- a/backend/src/plugins/Common/CommonPlugin.ts +++ b/backend/src/plugins/Common/CommonPlugin.ts @@ -1,4 +1,5 @@ import { + Attachment, ChatInputCommandInteraction, Message, MessageCreateOptions, @@ -7,11 +8,10 @@ import { TextBasedChannel, User, } from "discord.js"; -import { PluginOptions } from "knub"; +import { PluginOptions, guildPlugin } from "knub"; import { logger } from "../../logger"; import { isContextInteraction, sendContextResponse } from "../../pluginUtils"; import { errorMessage, successMessage } from "../../utils"; -import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint"; import { getErrorEmoji, getSuccessEmoji } from "./functions/getEmoji"; import { CommonPluginType, zCommonConfig } from "./types"; @@ -19,30 +19,21 @@ const defaultOptions: PluginOptions = { config: { success_emoji: "✅", error_emoji: "❌", + attachment_storing_channel: null, }, }; -export const CommonPlugin = zeppelinGuildPlugin()({ +export const CommonPlugin = guildPlugin()({ name: "common", - showInDocs: false, - info: { - prettyName: "Common", - }, - dependencies: () => [], configParser: (input) => zCommonConfig.parse(input), defaultOptions, - public: { - getSuccessEmoji(pluginData) { - return () => getSuccessEmoji(pluginData); - }, + public(pluginData) { + return { + getSuccessEmoji, + getErrorEmoji, - getErrorEmoji(pluginData) { - return () => getErrorEmoji(pluginData); - }, - - sendSuccessMessage(pluginData) { - return async ( + sendSuccessMessage: async ( context: TextBasedChannel | Message | User | ChatInputCommandInteraction, body: string, allowedMentions?: MessageMentionOptions, @@ -89,11 +80,9 @@ export const CommonPlugin = zeppelinGuildPlugin()({ return undefined; }) as Promise; - }; - }, + }, - sendErrorMessage(pluginData) { - return async ( + sendErrorMessage: async ( context: TextBasedChannel | Message | User | ChatInputCommandInteraction, body: string, allowedMentions?: MessageMentionOptions, @@ -140,7 +129,25 @@ export const CommonPlugin = zeppelinGuildPlugin()({ return undefined; }) as Promise; - }; - }, + }, + + storeAttachmentsAsMessage: async (attachments: Attachment[], backupChannel?: TextBasedChannel | null) => { + const attachmentChannelId = pluginData.config.get().attachment_storing_channel; + const channel = attachmentChannelId + ? (pluginData.guild.channels.cache.get(attachmentChannelId) as TextBasedChannel) ?? backupChannel + : backupChannel; + + if (!channel) { + throw new Error( + 'Cannot store attachments: no attachment storing channel configured, and no backup channel passed' + ); + } + + return channel!.send({ + content: `Storing ${attachments.length} attachment${attachments.length === 1 ? "" : "s"}`, + files: attachments.map((a) => a.url), + }); + }, + } }, }); diff --git a/backend/src/plugins/Common/info.ts b/backend/src/plugins/Common/info.ts new file mode 100644 index 00000000..666ac502 --- /dev/null +++ b/backend/src/plugins/Common/info.ts @@ -0,0 +1,8 @@ +import { ZeppelinPluginInfo } from "../../types"; +import { zCommonConfig } from "./types"; + +export const contextMenuPluginInfo: ZeppelinPluginInfo = { + showInDocs: false, + prettyName: "Common", + configSchema: zCommonConfig, +}; diff --git a/backend/src/plugins/Common/types.ts b/backend/src/plugins/Common/types.ts index 965046aa..87a342f5 100644 --- a/backend/src/plugins/Common/types.ts +++ b/backend/src/plugins/Common/types.ts @@ -4,6 +4,7 @@ import z from "zod"; export const zCommonConfig = z.strictObject({ success_emoji: z.string(), error_emoji: z.string(), + attachment_storing_channel: z.nullable(z.string()), }); export interface CommonPluginType extends BasePluginType { diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts index 9848f5d5..9f7114c6 100644 --- a/backend/src/plugins/ContextMenus/actions/ban.ts +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -9,8 +9,8 @@ import { } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { canActOn } from "src/pluginUtils"; -import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { canActOn } from "../../../pluginUtils"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { logger } from "../../../logger"; import { convertDelayStringToMS, renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; @@ -36,17 +36,13 @@ async function banAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasBanPermission(executingMember, interaction.channelId))) { - await interactionToReply - .editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }) - .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interactionToReply - .editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }) - .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: "Cannot ban: insufficient permissions", embeds: [], components: [] }); return; } @@ -57,9 +53,7 @@ async function banAction( const durationMs = duration ? convertDelayStringToMS(duration)! : undefined; const result = await modactions.banUserId(target, reason, reason, { caseArgs }, durationMs); if (result.status === "failed") { - await interactionToReply - .editReply({ content: "Error: Failed to ban user", embeds: [], components: [] }) - .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: "Error: Failed to ban user", embeds: [], components: [] }); return; } @@ -73,9 +67,7 @@ async function banAction( await updateAction(pluginData, executingMember, result.case, evidence); } - await interactionToReply - .editReply({ content: banMessage, embeds: [], components: [] }) - .catch((err) => logger.error(`Ban interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: banMessage, embeds: [], components: [] }); } export async function launchBanActionModal( @@ -112,9 +104,7 @@ export async function launchBanActionModal( if (interaction.isButton()) { await submitted.deferUpdate().catch((err) => logger.error(`Ban interaction defer failed: ${err}`)); } else if (interaction.isContextMenuCommand()) { - await submitted - .deferReply({ ephemeral: true }) - .catch((err) => logger.error(`Ban interaction defer failed: ${err}`)); + await submitted.deferReply({ ephemeral: true }); } const duration = submitted.fields.getTextInputValue("duration"); @@ -122,6 +112,5 @@ export async function launchBanActionModal( const evidence = submitted.fields.getTextInputValue("evidence"); await banAction(pluginData, duration, reason, evidence, target, interaction, submitted); - }) - .catch((err) => logger.error(`Ban modal interaction failed: ${err}`)); + }); } diff --git a/backend/src/plugins/ContextMenus/actions/clean.ts b/backend/src/plugins/ContextMenus/actions/clean.ts index c5125721..8dee27b1 100644 --- a/backend/src/plugins/ContextMenus/actions/clean.ts +++ b/backend/src/plugins/ContextMenus/actions/clean.ts @@ -61,15 +61,11 @@ export async function launchCleanActionModal( await interaction .awaitModalSubmit({ time: MODAL_TIMEOUT, filter: (i) => i.customId == modalId }) .then(async (submitted) => { - await submitted - .deferReply({ ephemeral: true }) - .catch((err) => logger.error(`Clean interaction defer failed: ${err}`)); + await submitted.deferReply({ ephemeral: true }); const amount = submitted.fields.getTextInputValue("amount"); if (isNaN(Number(amount))) { - interaction - .editReply({ content: `Error: Amount '${amount}' is invalid`, embeds: [], components: [] }) - .catch((err) => logger.error(`Clean interaction reply failed: ${err}`)); + interaction.editReply({ content: `Error: Amount '${amount}' is invalid`, embeds: [], components: [] }); return; } @@ -81,6 +77,5 @@ export async function launchCleanActionModal( interaction.channelId, submitted, ); - }) - .catch((err) => logger.error(`Clean modal interaction failed: ${err}`)); + }); } diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index 6e69b16f..6d7ec1e1 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -39,25 +39,21 @@ async function muteAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasMutePermission(executingMember, interaction.channelId))) { - await interactionToReply - .editReply({ - content: "Cannot mute: insufficient permissions", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Cannot mute: insufficient permissions", + embeds: [], + components: [], + }); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interactionToReply - .editReply({ - content: "Cannot mute: insufficient permissions", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Cannot mute: insufficient permissions", + embeds: [], + components: [], + }); return; } @@ -78,17 +74,13 @@ async function muteAction( await updateAction(pluginData, executingMember, result.case!, evidence); } - await interactionToReply - .editReply({ content: muteMessage, embeds: [], components: [] }) - .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: muteMessage, embeds: [], components: [] }); } catch (e) { - await interactionToReply - .editReply({ - content: "Plugin error, please check your BOT_ALERTs", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Mute interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Plugin error, please check your BOT_ALERTs", + embeds: [], + components: [], + }); if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { pluginData.getPlugin(LogsPlugin).logBotAlert({ @@ -134,9 +126,7 @@ export async function launchMuteActionModal( if (interaction.isButton()) { await submitted.deferUpdate().catch((err) => logger.error(`Mute interaction defer failed: ${err}`)); } else if (interaction.isContextMenuCommand()) { - await submitted - .deferReply({ ephemeral: true }) - .catch((err) => logger.error(`Mute interaction defer failed: ${err}`)); + await submitted.deferReply({ ephemeral: true }); } const duration = submitted.fields.getTextInputValue("duration"); @@ -144,6 +134,5 @@ export async function launchMuteActionModal( const evidence = submitted.fields.getTextInputValue("evidence"); await muteAction(pluginData, duration, reason, evidence, target, interaction, submitted); - }) - .catch((err) => logger.error(`Mute modal interaction failed: ${err}`)); + }); } diff --git a/backend/src/plugins/ContextMenus/actions/note.ts b/backend/src/plugins/ContextMenus/actions/note.ts index b6911274..bbdc6a8e 100644 --- a/backend/src/plugins/ContextMenus/actions/note.ts +++ b/backend/src/plugins/ContextMenus/actions/note.ts @@ -8,8 +8,8 @@ import { TextInputStyle, } from "discord.js"; import { GuildPluginData } from "knub"; -import { canActOn } from "src/pluginUtils"; -import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { canActOn } from "../../../pluginUtils"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; import { logger } from "../../../logger"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; @@ -34,25 +34,21 @@ async function noteAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasNotePermission(executingMember, interaction.channelId))) { - await interactionToReply - .editReply({ - content: "Cannot note: insufficient permissions", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Note interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Cannot note: insufficient permissions", + embeds: [], + components: [], + }); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interactionToReply - .editReply({ - content: "Cannot note: insufficient permissions", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Note interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Cannot note: insufficient permissions", + embeds: [], + components: [], + }); return; } @@ -72,13 +68,11 @@ async function noteAction( }); const userName = renderUserUsername(targetMember.user); - await interactionToReply - .editReply({ - content: `Note added on **${userName}** (Case #${createdCase.case_number})`, - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Note interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: `Note added on **${userName}** (Case #${createdCase.case_number})`, + embeds: [], + components: [], + }); } export async function launchNoteActionModal( @@ -99,14 +93,11 @@ export async function launchNoteActionModal( if (interaction.isButton()) { await submitted.deferUpdate().catch((err) => logger.error(`Note interaction defer failed: ${err}`)); } else if (interaction.isContextMenuCommand()) { - await submitted - .deferReply({ ephemeral: true }) - .catch((err) => logger.error(`Note interaction defer failed: ${err}`)); + await submitted.deferReply({ ephemeral: true }); } const reason = submitted.fields.getTextInputValue("reason"); await noteAction(pluginData, reason, target, interaction, submitted); - }) - .catch((err) => logger.error(`Note modal interaction failed: ${err}`)); + }); } diff --git a/backend/src/plugins/ContextMenus/actions/update.ts b/backend/src/plugins/ContextMenus/actions/update.ts index 3365f293..d534930d 100644 --- a/backend/src/plugins/ContextMenus/actions/update.ts +++ b/backend/src/plugins/ContextMenus/actions/update.ts @@ -2,8 +2,8 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; +import { CasesPlugin } from "../../Cases/CasesPlugin"; +import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ContextMenuPluginType } from "../types"; export async function updateAction( @@ -19,7 +19,7 @@ export async function updateAction( body: value, }); - pluginData.getPlugin(LogsPlugin).logCaseUpdate({ + void pluginData.getPlugin(LogsPlugin).logCaseUpdate({ mod: executingMember.user, caseNumber: theCase.case_number, caseType: CaseTypes[theCase.type], diff --git a/backend/src/plugins/ContextMenus/actions/warn.ts b/backend/src/plugins/ContextMenus/actions/warn.ts index b467ed61..1e93f42d 100644 --- a/backend/src/plugins/ContextMenus/actions/warn.ts +++ b/backend/src/plugins/ContextMenus/actions/warn.ts @@ -8,8 +8,8 @@ import { TextInputStyle, } from "discord.js"; import { GuildPluginData } from "knub"; -import { canActOn } from "src/pluginUtils"; -import { ModActionsPlugin } from "src/plugins/ModActions/ModActionsPlugin"; +import { canActOn } from "../../../pluginUtils"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { logger } from "../../../logger"; import { renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; @@ -34,25 +34,21 @@ async function warnAction( const modactions = pluginData.getPlugin(ModActionsPlugin); if (!userCfg.can_use || !(await modactions.hasWarnPermission(executingMember, interaction.channelId))) { - await interactionToReply - .editReply({ - content: "Cannot warn: insufficient permissions", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Cannot warn: insufficient permissions", + embeds: [], + components: [], + }); return; } const targetMember = await pluginData.guild.members.fetch(target); if (!canActOn(pluginData, executingMember, targetMember)) { - await interactionToReply - .editReply({ - content: "Cannot warn: insufficient permissions", - embeds: [], - components: [], - }) - .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); + await interactionToReply.editReply({ + content: "Cannot warn: insufficient permissions", + embeds: [], + components: [], + }); return; } @@ -62,9 +58,7 @@ async function warnAction( const result = await modactions.warnMember(targetMember, reason, reason, { caseArgs }); if (result.status === "failed") { - await interactionToReply - .editReply({ content: "Error: Failed to warn user", embeds: [], components: [] }) - .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: "Error: Failed to warn user", embeds: [], components: [] }); return; } @@ -76,9 +70,7 @@ async function warnAction( await updateAction(pluginData, executingMember, result.case, evidence); } - await interactionToReply - .editReply({ content: muteMessage, embeds: [], components: [] }) - .catch((err) => logger.error(`Warn interaction reply failed: ${err}`)); + await interactionToReply.editReply({ content: muteMessage, embeds: [], components: [] }); } export async function launchWarnActionModal( @@ -105,15 +97,12 @@ export async function launchWarnActionModal( if (interaction.isButton()) { await submitted.deferUpdate().catch((err) => logger.error(`Warn interaction defer failed: ${err}`)); } else if (interaction.isContextMenuCommand()) { - await submitted - .deferReply({ ephemeral: true }) - .catch((err) => logger.error(`Warn interaction defer failed: ${err}`)); + await submitted.deferReply({ ephemeral: true }); } const reason = submitted.fields.getTextInputValue("reason"); const evidence = submitted.fields.getTextInputValue("evidence"); await warnAction(pluginData, reason, evidence, target, interaction, submitted); - }) - .catch((err) => logger.error(`Warn modal interaction failed: ${err}`)); + }); } diff --git a/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts index 9cb40f14..fd538997 100644 --- a/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts @@ -12,7 +12,7 @@ import { import { GuildPluginData, guildPluginUserContextMenuCommand } from "knub"; import { Case } from "../../../data/entities/Case"; import { logger } from "../../../logger"; -import { ModActionsPlugin } from "../../../plugins/ModActions/ModActionsPlugin"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { SECONDS, UnknownUser, emptyEmbedValue, renderUserUsername, resolveUser, trimLines } from "../../../utils"; import { asyncMap } from "../../../utils/async"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; @@ -40,9 +40,7 @@ export const ModMenuCmd = guildPluginUserContextMenuCommand({ name: "Mod Menu", defaultMemberPermissions: PermissionFlagsBits.ViewAuditLog.toString(), async run({ pluginData, interaction }) { - await interaction - .deferReply({ ephemeral: true }) - .catch((err) => logger.error(`Mod menu interaction defer failed: ${err}`)); + await interaction.deferReply({ ephemeral: true }); // Run permission checks for executing user. const executingMember = await pluginData.guild.members.fetch(interaction.user.id); @@ -50,22 +48,14 @@ export const ModMenuCmd = guildPluginUserContextMenuCommand({ channelId: interaction.channelId, member: executingMember, }); - const utility = pluginData.getPlugin(UtilityPlugin); - if ( - !userCfg.can_use || - (await !utility.hasPermission(executingMember, interaction.channelId, "can_open_mod_menu")) - ) { - await interaction - .followUp({ content: "Error: Insufficient Permissions" }) - .catch((err) => logger.error(`Mod menu interaction follow up failed: ${err}`)); + if (!userCfg.can_use || !userCfg.can_open_mod_menu) { + await interaction.followUp({ content: "Error: Insufficient Permissions" }); return; } const user = await resolveUser(pluginData.client, interaction.targetId); if (!user.id) { - await interaction - .followUp("Error: User not found") - .catch((err) => logger.error(`Mod menu interaction follow up failed: ${err}`)); + await interaction.followUp("Error: User not found"); return; } diff --git a/backend/src/plugins/Counters/CountersPlugin.ts b/backend/src/plugins/Counters/CountersPlugin.ts index ed1b2d8a..dd226865 100644 --- a/backend/src/plugins/Counters/CountersPlugin.ts +++ b/backend/src/plugins/Counters/CountersPlugin.ts @@ -19,6 +19,7 @@ import { offCounterEvent } from "./functions/offCounterEvent"; import { onCounterEvent } from "./functions/onCounterEvent"; import { setCounterValue } from "./functions/setCounterValue"; import { CountersPluginType, zCountersConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const DECAY_APPLY_INTERVAL = 5 * MINUTES; @@ -127,6 +128,10 @@ export const CountersPlugin = guildPlugin()({ await state.counters.markUnusedTriggersToBeDeleted(activeTriggerIds); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + async afterLoad(pluginData) { const { state } = pluginData; diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index 0eb68f2b..558c23de 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -45,22 +45,22 @@ export const AddCounterCmd = guildPluginMessageCommand()({ const counter = config.counters[args.counterName]; const counterId = pluginData.state.counterIds[args.counterName]; if (!counter || !counterId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Unknown counter: ${args.counterName}`); + void pluginData.state.common.sendErrorMessage(message, `Unknown counter: ${args.counterName}`); return; } if (counter.can_edit === false) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Missing permissions to edit this counter's value`); + void pluginData.state.common.sendErrorMessage(message, `Missing permissions to edit this counter's value`); return; } if (args.channel && !counter.per_channel) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-channel`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-channel`); return; } if (args.user && !counter.per_user) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-user`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-user`); return; } @@ -69,13 +69,13 @@ export const AddCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which channel's counter value would you like to add to?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Channel is not a text channel, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Channel is not a text channel, cancelling"); return; } @@ -87,13 +87,13 @@ export const AddCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which user's counter value would you like to add to?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialUser = await resolveUser(pluginData.client, reply.content); if (!potentialUser || potentialUser instanceof UnknownUser) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown user, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Unknown user, cancelling"); return; } @@ -105,13 +105,13 @@ export const AddCounterCmd = guildPluginMessageCommand()({ message.channel.send("How much would you like to add to the counter's value?"); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialAmount = parseInt(reply.content, 10); if (!potentialAmount) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Not a number, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Not a number, cancelling"); return; } diff --git a/backend/src/plugins/Counters/commands/CountersListCmd.ts b/backend/src/plugins/Counters/commands/CountersListCmd.ts index db83812e..fc79b62c 100644 --- a/backend/src/plugins/Counters/commands/CountersListCmd.ts +++ b/backend/src/plugins/Counters/commands/CountersListCmd.ts @@ -15,7 +15,7 @@ export const CountersListCmd = guildPluginMessageCommand()({ const countersToShow = Array.from(Object.values(config.counters)).filter((c) => c.can_view !== false); if (!countersToShow.length) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "No counters are configured for this server"); + void pluginData.state.common.sendErrorMessage(message, "No counters are configured for this server"); return; } diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index e413cf21..5f7aa5d4 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -18,14 +18,12 @@ export const ResetAllCounterValuesCmd = guildPluginMessageCommand()({ const counter = config.counters[args.counterName]; const counterId = pluginData.state.counterIds[args.counterName]; if (!counter || !counterId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Unknown counter: ${args.counterName}`); + void pluginData.state.common.sendErrorMessage(message, `Unknown counter: ${args.counterName}`); return; } if (counter.can_edit === false) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Missing permissions to reset this counter's value`); + void pluginData.state.common.sendErrorMessage(message, `Missing permissions to reset this counter's value`); return; } if (args.channel && !counter.per_channel) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-channel`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-channel`); return; } if (args.user && !counter.per_user) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-user`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-user`); return; } @@ -64,13 +64,13 @@ export const ResetCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which channel's counter value would you like to reset?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Channel is not a text channel, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Channel is not a text channel, cancelling"); return; } @@ -82,13 +82,13 @@ export const ResetCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which user's counter value would you like to reset?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialUser = await resolveUser(pluginData.client, reply.content); if (!potentialUser || potentialUser instanceof UnknownUser) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown user, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Unknown user, cancelling"); return; } diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index 3cc62c54..da055ee0 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -45,22 +45,22 @@ export const SetCounterCmd = guildPluginMessageCommand()({ const counter = config.counters[args.counterName]; const counterId = pluginData.state.counterIds[args.counterName]; if (!counter || !counterId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Unknown counter: ${args.counterName}`); + void pluginData.state.common.sendErrorMessage(message, `Unknown counter: ${args.counterName}`); return; } if (counter.can_edit === false) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Missing permissions to edit this counter's value`); + void pluginData.state.common.sendErrorMessage(message, `Missing permissions to edit this counter's value`); return; } if (args.channel && !counter.per_channel) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-channel`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-channel`); return; } if (args.user && !counter.per_user) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-user`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-user`); return; } @@ -69,13 +69,13 @@ export const SetCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which channel's counter value would you like to change?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel || !(potentialChannel instanceof TextChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Channel is not a text channel, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Channel is not a text channel, cancelling"); return; } @@ -87,13 +87,13 @@ export const SetCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which user's counter value would you like to change?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialUser = await resolveUser(pluginData.client, reply.content); if (!potentialUser || potentialUser instanceof UnknownUser) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown user, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Unknown user, cancelling"); return; } @@ -105,13 +105,13 @@ export const SetCounterCmd = guildPluginMessageCommand()({ message.channel.send("What would you like to set the counter's value to?"); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialValue = parseInt(reply.content, 10); if (Number.isNaN(potentialValue)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Not a number, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Not a number, cancelling"); return; } @@ -119,7 +119,7 @@ export const SetCounterCmd = guildPluginMessageCommand()({ } if (value < 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cannot set counter value below 0"); + void pluginData.state.common.sendErrorMessage(message, "Cannot set counter value below 0"); return; } diff --git a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts index 1c037e69..d91de3f3 100644 --- a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts @@ -39,22 +39,22 @@ export const ViewCounterCmd = guildPluginMessageCommand()({ const counter = config.counters[args.counterName]; const counterId = pluginData.state.counterIds[args.counterName]; if (!counter || !counterId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Unknown counter: ${args.counterName}`); + void pluginData.state.common.sendErrorMessage(message, `Unknown counter: ${args.counterName}`); return; } if (counter.can_view === false) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `Missing permissions to view this counter's value`); + void pluginData.state.common.sendErrorMessage(message, `Missing permissions to view this counter's value`); return; } if (args.channel && !counter.per_channel) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-channel`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-channel`); return; } if (args.user && !counter.per_user) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, `This counter is not per-user`); + void pluginData.state.common.sendErrorMessage(message, `This counter is not per-user`); return; } @@ -63,13 +63,13 @@ export const ViewCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which channel's counter value would you like to view?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake); if (!potentialChannel?.isTextBased()) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Channel is not a text channel, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Channel is not a text channel, cancelling"); return; } @@ -81,13 +81,13 @@ export const ViewCounterCmd = guildPluginMessageCommand()({ message.channel.send(`Which user's counter value would you like to view?`); const reply = await waitForReply(pluginData.client, message.channel, message.author.id); if (!reply || !reply.content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Cancelling"); return; } const potentialUser = await resolveUser(pluginData.client, reply.content); if (!potentialUser || potentialUser instanceof UnknownUser) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown user, cancelling"); + void pluginData.state.common.sendErrorMessage(message, "Unknown user, cancelling"); return; } diff --git a/backend/src/plugins/Counters/types.ts b/backend/src/plugins/Counters/types.ts index ef322e7b..c75046eb 100644 --- a/backend/src/plugins/Counters/types.ts +++ b/backend/src/plugins/Counters/types.ts @@ -1,5 +1,5 @@ import { EventEmitter } from "events"; -import { BasePluginType } from "knub"; +import { BasePluginType, pluginUtils } from "knub"; import z from "zod"; import { GuildCounters, MAX_COUNTER_VALUE, MIN_COUNTER_VALUE } from "../../data/GuildCounters"; import { @@ -10,6 +10,7 @@ import { } from "../../data/entities/CounterTrigger"; import { zBoundedCharacters, zBoundedRecord, zDelayString } from "../../utils"; import Timeout = NodeJS.Timeout; +import { CommonPlugin } from "../Common/CommonPlugin"; const MAX_COUNTERS = 5; const MAX_TRIGGERS_PER_COUNTER = 5; @@ -132,5 +133,6 @@ export interface CountersPluginType extends BasePluginType { decayTimers: Timeout[]; events: CounterEventEmitter; counterTriggersByCounterId: Map; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts index f85036a1..cdb9aae7 100644 --- a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts +++ b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts @@ -14,6 +14,7 @@ import { import { LogsPlugin } from "../Logs/LogsPlugin"; import { runEvent } from "./functions/runEvent"; import { CustomEventsPluginType, zCustomEventsConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions = { config: { @@ -28,6 +29,10 @@ export const CustomEventsPlugin = guildPlugin()({ configParser: (input) => zCustomEventsConfig.parse(input), defaultOptions, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const config = pluginData.config.get(); for (const [key, event] of Object.entries(config.events)) { diff --git a/backend/src/plugins/CustomEvents/functions/runEvent.ts b/backend/src/plugins/CustomEvents/functions/runEvent.ts index 5ea3ceca..3f75b894 100644 --- a/backend/src/plugins/CustomEvents/functions/runEvent.ts +++ b/backend/src/plugins/CustomEvents/functions/runEvent.ts @@ -39,7 +39,7 @@ export async function runEvent( } catch (e) { if (e instanceof ActionError) { if (event.trigger.type === "command") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage((eventData.msg as Message).channel, e.message); + void pluginData.state.common.sendErrorMessage((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/CustomEvents/types.ts b/backend/src/plugins/CustomEvents/types.ts index 6433b6d0..0372fd16 100644 --- a/backend/src/plugins/CustomEvents/types.ts +++ b/backend/src/plugins/CustomEvents/types.ts @@ -1,4 +1,4 @@ -import { BasePluginType } from "knub"; +import { BasePluginType, pluginUtils } from "knub"; import z from "zod"; import { zBoundedCharacters, zBoundedRecord } from "../../utils"; import { zAddRoleAction } from "./actions/addRoleAction"; @@ -8,6 +8,7 @@ import { zMakeRoleUnmentionableAction } from "./actions/makeRoleUnmentionableAct import { zMessageAction } from "./actions/messageAction"; import { zMoveToVoiceChannelAction } from "./actions/moveToVoiceChannelAction"; import { zSetChannelPermissionOverridesAction } from "./actions/setChannelPermissionOverrides"; +import { CommonPlugin } from "../Common/CommonPlugin"; const zCommandTrigger = z.strictObject({ type: z.literal("command"), @@ -43,5 +44,6 @@ export interface CustomEventsPluginType extends BasePluginType { config: z.infer; state: { clearTriggers: () => void; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/LocateUser/LocateUserPlugin.ts b/backend/src/plugins/LocateUser/LocateUserPlugin.ts index 3fb8f841..39057b00 100644 --- a/backend/src/plugins/LocateUser/LocateUserPlugin.ts +++ b/backend/src/plugins/LocateUser/LocateUserPlugin.ts @@ -9,6 +9,7 @@ import { VoiceStateUpdateAlertEvt } from "./events/SendAlertsEvts"; import { LocateUserPluginType, zLocateUserConfig } from "./types"; import { clearExpiredAlert } from "./utils/clearExpiredAlert"; import { fillActiveAlertsList } from "./utils/fillAlertsList"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -53,6 +54,10 @@ export const LocateUserPlugin = guildPlugin()({ state.usersWithAlerts = []; }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/LocateUser/commands/FollowCmd.ts b/backend/src/plugins/LocateUser/commands/FollowCmd.ts index a214241b..921ec47f 100644 --- a/backend/src/plugins/LocateUser/commands/FollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/FollowCmd.ts @@ -27,9 +27,7 @@ export const FollowCmd = locateUserCmd({ const active = args.active || false; if (time < 30 * SECONDS) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "Sorry, but the minimum duration for an alert is 30 seconds!"); + void pluginData.state.common.sendErrorMessage(msg, "Sorry, but the minimum duration for an alert is 30 seconds!"); return; } @@ -48,18 +46,14 @@ export const FollowCmd = locateUserCmd({ } if (active) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + void pluginData.state.common.sendSuccessMessage( msg, `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration( time, )} i will notify and move you.\nPlease make sure to be in a voice channel, otherwise i cannot move you!`, ); } else { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + void pluginData.state.common.sendSuccessMessage( msg, `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration( time, diff --git a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts index 271b401d..c993c5c7 100644 --- a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts @@ -13,7 +13,7 @@ export const ListFollowCmd = locateUserCmd({ async run({ message: msg, pluginData }) { const alerts = await pluginData.state.alerts.getAlertsByRequestorId(msg.member.id); if (alerts.length === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You have no active alerts!"); + void pluginData.state.common.sendErrorMessage(msg, "You have no active alerts!"); return; } @@ -46,7 +46,7 @@ export const DeleteFollowCmd = locateUserCmd({ alerts.sort(sorter("expires_at")); if (args.num > alerts.length || args.num <= 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown alert!"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown alert!"); return; } @@ -54,6 +54,6 @@ export const DeleteFollowCmd = locateUserCmd({ clearExpiringVCAlert(toDelete); await pluginData.state.alerts.delete(toDelete.id); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Alert deleted"); + void pluginData.state.common.sendSuccessMessage(msg, "Alert deleted"); }, }); diff --git a/backend/src/plugins/LocateUser/types.ts b/backend/src/plugins/LocateUser/types.ts index 4139f465..90695a6d 100644 --- a/backend/src/plugins/LocateUser/types.ts +++ b/backend/src/plugins/LocateUser/types.ts @@ -1,6 +1,7 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildVCAlerts } from "../../data/GuildVCAlerts"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zLocateUserConfig = z.strictObject({ can_where: z.boolean(), @@ -13,6 +14,7 @@ export interface LocateUserPluginType extends BasePluginType { alerts: GuildVCAlerts; usersWithAlerts: string[]; unregisterGuildEventListener: () => void; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts index f6dbd96b..f562fe30 100644 --- a/backend/src/plugins/LocateUser/utils/moveMember.ts +++ b/backend/src/plugins/LocateUser/utils/moveMember.ts @@ -16,14 +16,10 @@ export async function moveMember( channel: target.voice.channelId, }); } catch { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(errorChannel, "Failed to move you. Are you in a voice channel?"); + void pluginData.state.common.sendErrorMessage(errorChannel, "Failed to move you. Are you in a voice channel?"); return; } } else { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(errorChannel, "Failed to move you. Are you in a voice channel?"); + void pluginData.state.common.sendErrorMessage(errorChannel, "Failed to move you. Are you in a voice channel?"); } } diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts index 8d40e99c..78172509 100644 --- a/backend/src/plugins/LocateUser/utils/sendWhere.ts +++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts @@ -22,7 +22,7 @@ export async function sendWhere( try { invite = await createOrReuseInvite(voice); } catch { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(channel, "Cannot create an invite to that channel!"); + void pluginData.state.common.sendErrorMessage(channel, "Cannot create an invite to that channel!"); return; } channel.send({ diff --git a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts index 4c960904..9d62c2c7 100644 --- a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts +++ b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts @@ -4,6 +4,7 @@ import { SaveMessagesToDBCmd } from "./commands/SaveMessagesToDB"; import { SavePinsToDBCmd } from "./commands/SavePinsToDB"; import { MessageCreateEvt, MessageDeleteBulkEvt, MessageDeleteEvt, MessageUpdateEvt } from "./events/SaveMessagesEvts"; import { MessageSaverPluginType, zMessageSaverConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -43,4 +44,8 @@ export const MessageSaverPlugin = guildPlugin()({ const { state, guild } = pluginData; state.savedMessages = GuildSavedMessages.getGuildInstance(guild.id); }, + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, }); diff --git a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts index 6b9211f1..a34b103e 100644 --- a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts @@ -18,14 +18,12 @@ export const SaveMessagesToDBCmd = messageSaverCmd({ const { savedCount, failed } = await saveMessagesToDB(pluginData, args.channel, args.ids.trim().split(" ")); if (failed.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + void pluginData.state.common.sendSuccessMessage( msg, `Saved ${savedCount} messages. The following messages could not be saved: ${failed.join(", ")}`, ); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Saved ${savedCount} messages!`); + void pluginData.state.common.sendSuccessMessage(msg, `Saved ${savedCount} messages!`); } }, }); diff --git a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts index 92c5393d..d2910525 100644 --- a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts @@ -19,14 +19,12 @@ export const SavePinsToDBCmd = messageSaverCmd({ const { savedCount, failed } = await saveMessagesToDB(pluginData, args.channel, [...pins.keys()]); if (failed.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + void pluginData.state.common.sendSuccessMessage( msg, `Saved ${savedCount} messages. The following messages could not be saved: ${failed.join(", ")}`, ); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Saved ${savedCount} messages!`); + void pluginData.state.common.sendSuccessMessage(msg, `Saved ${savedCount} messages!`); } }, }); diff --git a/backend/src/plugins/MessageSaver/types.ts b/backend/src/plugins/MessageSaver/types.ts index f42fa2c3..671eb9d9 100644 --- a/backend/src/plugins/MessageSaver/types.ts +++ b/backend/src/plugins/MessageSaver/types.ts @@ -1,6 +1,7 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zMessageSaverConfig = z.strictObject({ can_manage: z.boolean(), @@ -10,6 +11,7 @@ export interface MessageSaverPluginType extends BasePluginType { config: z.infer; state: { savedMessages: GuildSavedMessages; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index 953e245d..bd6aa0c7 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -72,6 +72,7 @@ import { onModActionsEvent } from "./functions/onModActionsEvent"; import { updateCase } from "./functions/updateCase"; import { warnMember } from "./functions/warnMember"; import { AttachmentLinkReactionType, ModActionsPluginType, modActionsSlashGroup, zModActionsConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions = { config: { @@ -94,7 +95,6 @@ const defaultOptions = { "The user already has **{priorWarnings}** warnings!\n Please check their prior cases and assess whether or not to warn anyways.\n Proceed with the warning?", ban_delete_message_days: 1, attachment_link_reaction: "warn" as AttachmentLinkReactionType, - attachment_storing_channel: null, can_note: false, can_warn: false, @@ -236,6 +236,10 @@ export const ModActionsPlugin = guildPlugin()({ state.events = new EventEmitter(); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts index beb4cc3d..9f1b819b 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts @@ -2,8 +2,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { CaseTypes } from "../../../../data/CaseTypes"; import { hasPermission } from "../../../../pluginUtils"; import { resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualAddCaseCmd } from "../../functions/actualCommands/actualAddCaseCmd"; +import { actualAddCaseCmd } from "./actualAddCaseCmd"; import { modActionsMsgCmd } from "../../types"; const opts = { @@ -28,7 +27,7 @@ export const AddCaseMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -36,7 +35,7 @@ export const AddCaseMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -46,7 +45,7 @@ export const AddCaseMsgCmd = modActionsMsgCmd({ // Verify the case type is valid const type: string = args.type[0].toUpperCase() + args.type.slice(1).toLowerCase(); if (!CaseTypes[type]) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot add case: invalid case type"); + pluginData.state.common.sendErrorMessage(msg, "Cannot add case: invalid case type"); return; } diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts index 5f427686..828ec742 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts @@ -4,8 +4,7 @@ import { CaseTypes } from "../../../../data/CaseTypes"; import { hasPermission } from "../../../../pluginUtils"; import { resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualAddCaseCmd } from "../../functions/actualCommands/actualAddCaseCmd"; +import { actualAddCaseCmd } from "./actualAddCaseCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -49,9 +48,10 @@ export const AddCaseSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts b/backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts similarity index 76% rename from backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts rename to backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts index e65fe8d3..2c67dc2f 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualAddCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts @@ -5,11 +5,10 @@ import { Case } from "../../../../data/entities/Case"; import { canActOn } from "../../../../pluginUtils"; import { UnknownUser, renderUsername, resolveMember } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; export async function actualAddCaseCmd( pluginData: GuildPluginData, @@ -28,9 +27,10 @@ export async function actualAddCaseCmd( // If the user exists as a guild member, make sure we can act on them first const member = await resolveMember(pluginData.client, pluginData.guild, user.id); if (member && !canActOn(pluginData, author, member)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "Cannot add case on this user: insufficient permissions"); + pluginData.state.common.sendErrorMessage( + context, + "Cannot add case on this user: insufficient permissions" + ); return; } @@ -47,11 +47,12 @@ export async function actualAddCaseCmd( }); if (user) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(context, `Case #${theCase.case_number} created for **${renderUsername(user)}**`); + pluginData.state.common.sendSuccessMessage( + context, + `Case #${theCase.case_number} created for **${renderUsername(user)}**` + ); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, `Case #${theCase.case_number} created`); + pluginData.state.common.sendSuccessMessage(context, `Case #${theCase.case_number} created`); } // Log the action diff --git a/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts index 10b4344c..35b9f737 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts @@ -1,8 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualBanCmd } from "../../functions/actualCommands/actualBanCmd"; +import { actualBanCmd } from "./actualBanCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -38,7 +37,7 @@ export const BanMsgCmd = modActionsMsgCmd({ const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -46,7 +45,7 @@ export const BanMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -57,7 +56,7 @@ export const BanMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args) ?? undefined; } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + pluginData.state.common.sendErrorMessage(msg, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts index 21b5558a..16bda55b 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualBanCmd } from "../../functions/actualCommands/actualBanCmd"; +import { actualBanCmd } from "./actualBanCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -52,9 +51,13 @@ export const BanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -67,9 +70,10 @@ export const BanSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -80,13 +84,13 @@ export const BanSlashCmd = modActionsSlashCmd({ try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); + pluginData.state.common.sendErrorMessage(interaction, e.message); return; } const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; if (options.time && !convertedTime) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); + pluginData.state.common.sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts b/backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts similarity index 85% rename from backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts rename to backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts index e4bf5ff9..0b442239 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts @@ -9,13 +9,12 @@ import { UnknownUser, UserNotificationMethod, renderUsername, resolveMember } fr import { banLock } from "../../../../utils/lockNameHelpers"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { banUserId } from "../banUserId"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { isBanned } from "../isBanned"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { banUserId } from "../../functions/banUserId"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { isBanned } from "../../functions/isBanned"; export async function actualBanCmd( pluginData: GuildPluginData, @@ -54,7 +53,7 @@ export async function actualBanCmd( ); if (!reply) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "User not on server, ban cancelled by moderator"); + pluginData.state.common.sendErrorMessage(context, "User not on server, ban cancelled by moderator"); lock.unlock(); return; } else { @@ -63,7 +62,7 @@ export async function actualBanCmd( } else { // Abort if trying to ban user indefinitely if they are already banned indefinitely if (!existingTempban && !time) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `User is already banned indefinitely.`); + pluginData.state.common.sendErrorMessage(context, `User is already banned indefinitely.`); return; } @@ -75,9 +74,10 @@ export async function actualBanCmd( ); if (!reply) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "User already banned, update cancelled by moderator"); + pluginData.state.common.sendErrorMessage( + context, + "User already banned, update cancelled by moderator" + ); lock.unlock(); return; } @@ -122,9 +122,7 @@ export async function actualBanCmd( }); } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, `Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`, ); @@ -137,11 +135,9 @@ export async function actualBanCmd( if (!forceban && !canActOn(pluginData, author, memberToBan!)) { const ourLevel = getMemberLevel(pluginData, author); const targetLevel = getMemberLevel(pluginData, memberToBan!); - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - context, - `Cannot ban: target permission level is equal or higher to yours, ${targetLevel} >= ${ourLevel}`, + pluginData.state.common.sendErrorMessage( + context, + `Cannot ban: target permission level is equal or higher to yours, ${targetLevel} >= ${ourLevel}`, ); lock.unlock(); return; @@ -170,7 +166,7 @@ export async function actualBanCmd( ); if (banResult.status === "failed") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Failed to ban member: ${banResult.error}`); + pluginData.state.common.sendErrorMessage(context, `Failed to ban member: ${banResult.error}`); lock.unlock(); return; } @@ -190,5 +186,5 @@ export async function actualBanCmd( } lock.unlock(); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, response); + pluginData.state.common.sendSuccessMessage(context, response); } diff --git a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts index 4e278e23..6c727e45 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualCaseCmd } from "../../functions/actualCommands/actualCaseCmd"; +import { actualCaseCmd } from "./actualCaseCmd"; import { modActionsMsgCmd } from "../../types"; const opts = { diff --git a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts index 15f2d03f..b86bfb01 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts @@ -1,5 +1,5 @@ import { slashOptions } from "knub"; -import { actualCaseCmd } from "../../functions/actualCommands/actualCaseCmd"; +import { actualCaseCmd } from "./actualCaseCmd"; import { modActionsSlashCmd } from "../../types"; const opts = [ diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts b/backend/src/plugins/ModActions/commands/case/actualCaseCmd.ts similarity index 74% rename from backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts rename to backend/src/plugins/ModActions/commands/case/actualCaseCmd.ts index 92b27199..5be37726 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/actualCaseCmd.ts @@ -2,7 +2,6 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; import { sendContextResponse } from "../../../../pluginUtils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; export async function actualCaseCmd( @@ -15,12 +14,12 @@ export async function actualCaseCmd( const theCase = await pluginData.state.cases.findByCaseNumber(caseNumber); if (!theCase) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Case not found", undefined, undefined, show !== true); + void pluginData.state.common.sendErrorMessage(context, "Case not found", undefined, undefined, show !== true); return; } const casesPlugin = pluginData.getPlugin(CasesPlugin); const embed = await casesPlugin.getCaseEmbed(theCase.id, authorId); - sendContextResponse(context, { ...embed, ephemeral: show !== true }); + void sendContextResponse(context, { ...embed, ephemeral: show !== true }); } diff --git a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts index 57f45c74..d5f5f7fe 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualCasesCmd } from "../../functions/actualCommands/actualCasesCmd"; +import { actualCasesCmd } from "./actualCasesCmd"; import { modActionsMsgCmd } from "../../types"; const opts = { diff --git a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts index 8e885d1a..fe932311 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts @@ -1,6 +1,6 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { actualCasesCmd } from "../../functions/actualCommands/actualCasesCmd"; +import { actualCasesCmd } from "./actualCasesCmd"; import { modActionsSlashCmd } from "../../types"; const opts = [ diff --git a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts index c65226a6..b36b39c7 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts @@ -1,7 +1,6 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { resolveMember, resolveUser, UnknownUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualCasesCmd } from "../../functions/actualCommands/actualCasesCmd"; +import { actualCasesCmd } from "./actualCasesCmd"; import { modActionsMsgCmd } from "../../types"; const opts = { @@ -38,7 +37,7 @@ export const CasesUserMsgCmd = modActionsMsgCmd({ (await resolveUser(pluginData.client, args.user)); if (user instanceof UnknownUser) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts b/backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts similarity index 97% rename from backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts rename to backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts index 23c091a1..5973bcdb 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualCasesCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts @@ -18,7 +18,6 @@ import { asyncMap } from "../../../../utils/async"; import { createPaginatedMessage } from "../../../../utils/createPaginatedMessage"; import { getGuildPrefix } from "../../../../utils/getGuildPrefix"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; const casesPerPage = 5; @@ -160,9 +159,13 @@ async function casesModCmd( const totalCases = await casesPlugin.getTotalCasesByMod(modId ?? author.id, casesFilters); if (totalCases === 0) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, `No cases by **${modName}**`, undefined, undefined, !show); + pluginData.state.common.sendErrorMessage( + context, + `No cases by **${modName}**`, + undefined, + undefined, + !show + ); return; } diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts index b4c96a68..dad54847 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { trimLines } from "../../../../utils"; -import { actualDeleteCaseCmd } from "../../functions/actualCommands/actualDeleteCaseCmd"; +import { actualDeleteCaseCmd } from "./actualDeleteCaseCmd"; import { modActionsMsgCmd } from "../../types"; export const DeleteCaseMsgCmd = modActionsMsgCmd({ diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts index f852b666..c9038c74 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts @@ -1,6 +1,6 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { actualDeleteCaseCmd } from "../../functions/actualCommands/actualDeleteCaseCmd"; +import { actualDeleteCaseCmd } from "./actualDeleteCaseCmd"; import { modActionsSlashCmd } from "../../types"; const opts = [slashOptions.boolean({ name: "force", description: "Whether or not to force delete", required: false })]; diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts similarity index 85% rename from backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts rename to backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts index cedd03c6..707332e4 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualDeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts @@ -4,7 +4,6 @@ import { Case } from "../../../../data/entities/Case"; import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; import { SECONDS, renderUsername } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../../../TimeAndDate/TimeAndDatePlugin"; import { ModActionsPluginType } from "../../types"; @@ -31,7 +30,7 @@ export async function actualDeleteCaseCmd( } if (failed.length === caseNumbers.length) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "None of the cases were found!"); + pluginData.state.common.sendErrorMessage(context, "None of the cases were found!"); return; } @@ -83,13 +82,15 @@ export async function actualDeleteCaseCmd( : ""; const amt = validCases.length - cancelled; if (amt === 0) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "All deletions were cancelled, no cases were deleted."); + pluginData.state.common.sendErrorMessage( + context, + "All deletions were cancelled, no cases were deleted." + ); return; } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(context, `${amt} case${amt === 1 ? " was" : "s were"} deleted!${failedAddendum}`); + pluginData.state.common.sendSuccessMessage( + context, + `${amt} case${amt === 1 ? " was" : "s were"} deleted!${failedAddendum}` + ); } diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts index e15f3c13..5224e905 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts @@ -1,8 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualForceBanCmd } from "../../functions/actualCommands/actualForceBanCmd"; +import { actualForceBanCmd } from "./actualForceBanCmd"; import { isBanned } from "../../functions/isBanned"; import { modActionsMsgCmd } from "../../types"; @@ -27,21 +26,21 @@ export const ForceBanMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } // If the user exists as a guild member, make sure we can act on them first const member = await resolveMember(pluginData.client, pluginData.guild, user.id); if (member && !canActOn(pluginData, msg.member, member)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot forceban this user: insufficient permissions"); + pluginData.state.common.sendErrorMessage(msg, "Cannot forceban this user: insufficient permissions"); return; } // Make sure the user isn't already banned const banned = await isBanned(pluginData, user.id); if (banned) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User is already banned`); + pluginData.state.common.sendErrorMessage(msg, `User is already banned`); return; } @@ -49,7 +48,7 @@ export const ForceBanMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts index 7f7e824c..8389233b 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualForceBanCmd } from "../../functions/actualCommands/actualForceBanCmd"; +import { actualForceBanCmd } from "./actualForceBanCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -30,9 +29,13 @@ export const ForceBanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -45,9 +48,10 @@ export const ForceBanSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -56,7 +60,7 @@ export const ForceBanSlashCmd = modActionsSlashCmd({ const convertedTime = options.time ? convertDelayStringToMS(options.time) : null; if (options.time && !convertedTime) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); + pluginData.state.common.sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts b/backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts similarity index 83% rename from backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts rename to backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts index c093306f..448f4134 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualForceBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts @@ -4,12 +4,11 @@ import { CaseTypes } from "../../../../data/CaseTypes"; import { LogType } from "../../../../data/LogType"; import { DAYS, MINUTES, UnknownUser } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { ignoreEvent } from "../ignoreEvent"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ignoreEvent } from "../../functions/ignoreEvent"; export async function actualForceBanCmd( pluginData: GuildPluginData, @@ -37,7 +36,7 @@ export async function actualForceBanCmd( reason: formattedReasonWithAttachments ?? undefined, }); } catch { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Failed to forceban member"); + pluginData.state.common.sendErrorMessage(context, "Failed to forceban member"); return; } @@ -52,9 +51,7 @@ export async function actualForceBanCmd( }); // Confirm the action - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(context, `Member forcebanned (Case #${createdCase.case_number})`); + pluginData.state.common.sendSuccessMessage(context, `Member forcebanned (Case #${createdCase.case_number})`); // Log the action pluginData.getPlugin(LogsPlugin).logMemberForceban({ diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts index 9c2a9cbb..833fb181 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts @@ -1,8 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; +import { actualMuteCmd } from "../mute/actualMuteCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -36,7 +35,7 @@ export const ForceMuteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -44,7 +43,7 @@ export const ForceMuteMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to mute this user if (memberToMute && !canActOn(pluginData, msg.member, memberToMute)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot mute: insufficient permissions"); + pluginData.state.common.sendErrorMessage(msg, "Cannot mute: insufficient permissions"); return; } @@ -54,7 +53,7 @@ export const ForceMuteMsgCmd = modActionsMsgCmd({ if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -66,7 +65,7 @@ export const ForceMuteMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + pluginData.state.common.sendErrorMessage(msg, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts index 348ff047..ba262835 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; +import { actualMuteCmd } from "../mute/actualMuteCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -47,9 +46,13 @@ export const ForceMuteSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -63,9 +66,10 @@ export const ForceMuteSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -75,7 +79,7 @@ export const ForceMuteSlashCmd = modActionsSlashCmd({ const convertedTime = options.time ? convertDelayStringToMS(options.time) ?? undefined : undefined; if (options.time && !convertedTime) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); + pluginData.state.common.sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } @@ -83,7 +87,7 @@ export const ForceMuteSlashCmd = modActionsSlashCmd({ try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); + pluginData.state.common.sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts index f9351d8f..396052fd 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts @@ -1,8 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { actualUnmuteCmd } from "../unmute/actualUnmuteCmd"; import { modActionsMsgCmd } from "../../types"; const opts = { @@ -33,13 +32,13 @@ export const ForceUnmuteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } // Check if they're muted in the first place if (!(await pluginData.state.mutes.isMuted(user.id))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot unmute: member is not muted"); + pluginData.state.common.sendErrorMessage(msg, "Cannot unmute: member is not muted"); return; } @@ -48,7 +47,7 @@ export const ForceUnmuteMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to unmute this member if (memberToUnmute && !canActOn(pluginData, msg.member, memberToUnmute)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot unmute: insufficient permissions"); + pluginData.state.common.sendErrorMessage(msg, "Cannot unmute: insufficient permissions"); return; } @@ -58,7 +57,7 @@ export const ForceUnmuteMsgCmd = modActionsMsgCmd({ if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts index 326d5b73..bb03ee89 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { actualUnmuteCmd } from "../unmute/actualUnmuteCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -31,9 +30,13 @@ export const ForceUnmuteSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -47,9 +50,10 @@ export const ForceUnmuteSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -59,7 +63,7 @@ export const ForceUnmuteSlashCmd = modActionsSlashCmd({ const convertedTime = options.time ? convertDelayStringToMS(options.time) ?? undefined : undefined; if (options.time && !convertedTime) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); + pluginData.state.common.sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts index 3d160d5f..c04bf9a1 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualHideCaseCmd } from "../../functions/actualCommands/actualHideCaseCmd"; +import { actualHideCaseCmd } from "./actualHideCaseCmd"; import { modActionsMsgCmd } from "../../types"; export const HideCaseMsgCmd = modActionsMsgCmd({ diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts index a501a5b1..b6261d73 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts @@ -1,5 +1,5 @@ import { slashOptions } from "knub"; -import { actualHideCaseCmd } from "../../functions/actualCommands/actualHideCaseCmd"; +import { actualHideCaseCmd } from "./actualHideCaseCmd"; import { modActionsSlashCmd } from "../../types"; export const HideCaseSlashCmd = modActionsSlashCmd({ diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts similarity index 81% rename from backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts rename to backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts index 28527b4d..49bee81b 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualHideCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts @@ -1,6 +1,5 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; export async function actualHideCaseCmd( @@ -21,7 +20,7 @@ export async function actualHideCaseCmd( } if (failed.length === caseNumbers.length) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "None of the cases were found!"); + pluginData.state.common.sendErrorMessage(context, "None of the cases were found!"); return; } const failedAddendum = @@ -30,9 +29,7 @@ export async function actualHideCaseCmd( : ""; const amt = caseNumbers.length - failed.length; - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, `${amt} case${amt === 1 ? " is" : "s are"} now hidden! Use \`unhidecase\` to unhide them.${failedAddendum}`, ); diff --git a/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts index fb2754e0..c494a7c7 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts @@ -1,8 +1,7 @@ import { hasPermission } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualKickCmd } from "../../functions/actualCommands/actualKickCmd"; +import { actualKickCmd } from "./actualKickCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -30,7 +29,7 @@ export const KickMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -38,7 +37,7 @@ export const KickMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(await pluginData.config.getForMessage(msg), "can_act_as_other"))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -49,7 +48,7 @@ export const KickMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + pluginData.state.common.sendErrorMessage(msg, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts index 4776d093..5bd94f30 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualKickCmd } from "../../functions/actualCommands/actualKickCmd"; +import { actualKickCmd } from "./actualKickCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -51,9 +50,13 @@ export const KickSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -66,9 +69,10 @@ export const KickSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -79,7 +83,7 @@ export const KickSlashCmd = modActionsSlashCmd({ try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); + pluginData.state.common.sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts b/backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts similarity index 72% rename from backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts rename to backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts index f8ad0158..4a6b22a4 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualKickCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts @@ -3,13 +3,12 @@ import { GuildPluginData } from "knub"; import { LogType } from "../../../../data/LogType"; import { canActOn } from "../../../../pluginUtils"; import { DAYS, SECONDS, UnknownUser, UserNotificationMethod, renderUsername, resolveMember } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { ignoreEvent } from "../ignoreEvent"; -import { isBanned } from "../isBanned"; -import { kickMember } from "../kickMember"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ignoreEvent } from "../../functions/ignoreEvent"; +import { isBanned } from "../../functions/isBanned"; +import { kickMember } from "../../functions/kickMember"; export async function actualKickCmd( pluginData: GuildPluginData, @@ -31,9 +30,9 @@ export async function actualKickCmd( if (!memberToKick) { const banned = await isBanned(pluginData, user.id); if (banned) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `User is banned`); + pluginData.state.common.sendErrorMessage(context, `User is banned`); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `User not found on the server`); + pluginData.state.common.sendErrorMessage(context, `User not found on the server`); } return; @@ -41,7 +40,7 @@ export async function actualKickCmd( // Make sure we're allowed to kick this member if (!canActOn(pluginData, author, memberToKick)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Cannot kick: insufficient permissions"); + pluginData.state.common.sendErrorMessage(context, "Cannot kick: insufficient permissions"); return; } @@ -63,7 +62,7 @@ export async function actualKickCmd( try { await memberToKick.ban({ deleteMessageSeconds: (1 * DAYS) / SECONDS, reason: "kick -clean" }); } catch { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Failed to ban the user to clean messages (-clean)"); + pluginData.state.common.sendErrorMessage(context, "Failed to ban the user to clean messages (-clean)"); } pluginData.state.serverLogs.ignoreLog(LogType.MEMBER_UNBAN, memberToKick.id); @@ -72,14 +71,14 @@ export async function actualKickCmd( try { await pluginData.guild.bans.remove(memberToKick.id, "kick -clean"); } catch { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "Failed to unban the user after banning them (-clean)"); + pluginData.state.common.sendErrorMessage( + context, + "Failed to unban the user after banning them (-clean)"); } } if (kickResult.status === "failed") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Failed to kick user`); + pluginData.state.common.sendErrorMessage(context, `Failed to kick user`); return; } @@ -87,5 +86,5 @@ export async function actualKickCmd( let response = `Kicked **${renderUsername(memberToKick.user)}** (Case #${kickResult.case.case_number})`; if (kickResult.notifyResult.text) response += ` (${kickResult.notifyResult.text})`; - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, response); + pluginData.state.common.sendSuccessMessage(context, response); } diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts index d2f72c70..d47c61d5 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts @@ -1,8 +1,7 @@ import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMassBanCmd } from "../../functions/actualCommands/actualMassBanCmd"; +import { actualMassBanCmd } from "./actualMassBanCmd"; import { modActionsMsgCmd } from "../../types"; export const MassBanMsgCmd = modActionsMsgCmd({ @@ -22,7 +21,7 @@ export const MassBanMsgCmd = modActionsMsgCmd({ const banReasonReply = await waitForReply(pluginData.client, await getContextChannel(msg), msg.author.id); if (!banReasonReply || !banReasonReply.content || banReasonReply.content.toLowerCase().trim() === "cancel") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cancelled"); + pluginData.state.common.sendErrorMessage(msg, "Cancelled"); return; } diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts index de374434..a358893e 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts @@ -1,8 +1,7 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMassBanCmd } from "../../functions/actualCommands/actualMassBanCmd"; +import { actualMassBanCmd } from "./actualMassBanCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -31,9 +30,13 @@ export const MassBanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts b/backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts similarity index 85% rename from backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts rename to backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts index fcb9610d..207194df 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts @@ -6,12 +6,11 @@ import { humanizeDurationShort } from "../../../../humanizeDurationShort"; import { canActOn, getContextChannel, isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; import { DAYS, MINUTES, SECONDS, noop } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { ignoreEvent } from "../ignoreEvent"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ignoreEvent } from "../../functions/ignoreEvent"; export async function actualMassBanCmd( pluginData: GuildPluginData, @@ -23,7 +22,7 @@ export async function actualMassBanCmd( ) { // Limit to 100 users at once (arbitrary?) if (userIds.length > 100) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Can only massban max 100 users at once`); + pluginData.state.common.sendErrorMessage(context, `Can only massban max 100 users at once`); return; } @@ -38,9 +37,9 @@ export async function actualMassBanCmd( for (const userId of userIds) { const member = pluginData.guild.members.cache.get(userId as Snowflake); // TODO: Get members on demand? if (member && !canActOn(pluginData, author, member)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "Cannot massban one or more users: insufficient permissions"); + pluginData.state.common.sendErrorMessage( + context, + "Cannot massban one or more users: insufficient permissions"); return; } } @@ -146,7 +145,7 @@ export async function actualMassBanCmd( const successfulBanCount = userIds.length - failedBans.length; if (successfulBanCount === 0) { // All bans failed - don't create a log entry and notify the user - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "All bans failed. Make sure the IDs are valid."); + pluginData.state.common.sendErrorMessage(context, "All bans failed. Make sure the IDs are valid."); } else { // Some or all bans were successful. Create a log entry for the mass ban and notify the user. pluginData.getPlugin(LogsPlugin).logMassBan({ @@ -156,18 +155,17 @@ export async function actualMassBanCmd( }); if (failedBans.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - context, - `Banned ${successfulBanCount} users in ${formattedTimeTaken}, ${ - failedBans.length - } failed: ${failedBans.join(" ")}`, - ); + pluginData.state.common.sendSuccessMessage( + context, + `Banned ${successfulBanCount} users in ${formattedTimeTaken}, ${ + failedBans.length + } failed: ${failedBans.join(" ")}`, + ); } else { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(context, `Banned ${successfulBanCount} users successfully in ${formattedTimeTaken}`); + pluginData.state.common.sendSuccessMessage( + context, + `Banned ${successfulBanCount} users successfully in ${formattedTimeTaken}` + ); } } }); diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts index 713e89dd..bbcfd715 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts @@ -1,8 +1,7 @@ import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMassMuteCmd } from "../../functions/actualCommands/actualMassMuteCmd"; +import { actualMassMuteCmd } from "./actualMassMuteCmd"; import { modActionsMsgCmd } from "../../types"; export const MassMuteMsgCmd = modActionsMsgCmd({ @@ -25,7 +24,7 @@ export const MassMuteMsgCmd = modActionsMsgCmd({ !muteReasonReceived.content || muteReasonReceived.content.toLowerCase().trim() === "cancel" ) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cancelled"); + pluginData.state.common.sendErrorMessage(msg, "Cancelled"); return; } diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts index ecdadbc7..d7ad927a 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts @@ -1,8 +1,7 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMassMuteCmd } from "../../functions/actualCommands/actualMassMuteCmd"; +import { actualMassMuteCmd } from "./actualMassMuteCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -31,9 +30,13 @@ export const MassMuteSlashSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts b/backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts similarity index 80% rename from backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts rename to backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts index 53a82421..e8ed7111 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassMuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts @@ -3,12 +3,11 @@ import { GuildPluginData } from "knub"; import { LogType } from "../../../../data/LogType"; import { logger } from "../../../../logger"; import { canActOn, isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; export async function actualMassMuteCmd( pluginData: GuildPluginData, @@ -20,7 +19,7 @@ export async function actualMassMuteCmd( ) { // Limit to 100 users at once (arbitrary?) if (userIds.length > 100) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Can only massmute max 100 users at once`); + pluginData.state.common.sendErrorMessage(context, `Can only massmute max 100 users at once`); return; } @@ -35,9 +34,10 @@ export async function actualMassMuteCmd( for (const userId of userIds) { const member = pluginData.guild.members.cache.get(userId as Snowflake); if (member && !canActOn(pluginData, author, member)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "Cannot massmute one or more users: insufficient permissions"); + pluginData.state.common.sendErrorMessage( + context, + "Cannot massmute one or more users: insufficient permissions" + ); return; } } @@ -77,7 +77,7 @@ export async function actualMassMuteCmd( const successfulMuteCount = userIds.length - failedMutes.length; if (successfulMuteCount === 0) { // All mutes failed - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "All mutes failed. Make sure the IDs are valid."); + pluginData.state.common.sendErrorMessage(context, "All mutes failed. Make sure the IDs are valid."); } else { // Success on all or some mutes pluginData.getPlugin(LogsPlugin).logMassMute({ @@ -86,14 +86,12 @@ export async function actualMassMuteCmd( }); if (failedMutes.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, `Muted ${successfulMuteCount} users, ${failedMutes.length} failed: ${failedMutes.join(" ")}`, ); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, `Muted ${successfulMuteCount} users successfully`); + pluginData.state.common.sendSuccessMessage(context, `Muted ${successfulMuteCount} users successfully`); } } } diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts index 121be1cb..c10df41f 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts @@ -1,8 +1,7 @@ import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMassUnbanCmd } from "../../functions/actualCommands/actualMassUnbanCmd"; +import { actualMassUnbanCmd } from "./actualMassUnbanCmd"; import { modActionsMsgCmd } from "../../types"; export const MassUnbanMsgCmd = modActionsMsgCmd({ @@ -21,7 +20,7 @@ export const MassUnbanMsgCmd = modActionsMsgCmd({ sendContextResponse(msg, "Unban reason? `cancel` to cancel"); const unbanReasonReply = await waitForReply(pluginData.client, await getContextChannel(msg), msg.author.id); if (!unbanReasonReply || !unbanReasonReply.content || unbanReasonReply.content.toLowerCase().trim() === "cancel") { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cancelled"); + pluginData.state.common.sendErrorMessage(msg, "Cancelled"); return; } diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts index 1a2cf558..4a733552 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts @@ -1,8 +1,7 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMassUnbanCmd } from "../../functions/actualCommands/actualMassUnbanCmd"; +import { actualMassUnbanCmd } from "./actualMassUnbanCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -31,9 +30,13 @@ export const MassUnbanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts similarity index 84% rename from backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts rename to backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts index 8cf1b4ac..6f4a0ebf 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts @@ -5,13 +5,12 @@ import { LogType } from "../../../../data/LogType"; import { isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; import { MINUTES, noop } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { ignoreEvent } from "../ignoreEvent"; -import { isBanned } from "../isBanned"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ignoreEvent } from "../../functions/ignoreEvent"; +import { isBanned } from "../../functions/isBanned"; export async function actualMassUnbanCmd( pluginData: GuildPluginData, @@ -23,7 +22,7 @@ export async function actualMassUnbanCmd( ) { // Limit to 100 users at once (arbitrary?) if (userIds.length > 100) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Can only mass-unban max 100 users at once`); + pluginData.state.common.sendErrorMessage(context, `Can only mass-unban max 100 users at once`); return; } @@ -76,9 +75,10 @@ export async function actualMassUnbanCmd( const successfulUnbanCount = userIds.length - failedUnbans.length; if (successfulUnbanCount === 0) { // All unbans failed - don't create a log entry and notify the user - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "All unbans failed. Make sure the IDs are valid and banned."); + pluginData.state.common.sendErrorMessage( + context, + "All unbans failed. Make sure the IDs are valid and banned." + ); } else { // Some or all unbans were successful. Create a log entry for the mass unban and notify the user. pluginData.getPlugin(LogsPlugin).logMassUnban({ @@ -105,16 +105,12 @@ export async function actualMassUnbanCmd( }); } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, `Unbanned ${successfulUnbanCount} users, ${failedUnbans.length} failed:\n${failedMsg}`, ); } else { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(context, `Unbanned ${successfulUnbanCount} users successfully`); + pluginData.state.common.sendSuccessMessage(context, `Unbanned ${successfulUnbanCount} users successfully`); } } } diff --git a/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts index 469d7162..d6aeb284 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts @@ -2,8 +2,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; +import { actualMuteCmd } from "./actualMuteCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -38,7 +37,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -48,9 +47,10 @@ export const MuteMsgCmd = modActionsMsgCmd({ const _isBanned = await isBanned(pluginData, user.id); const prefix = pluginData.fullConfig.prefix; if (_isBanned) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.`); + pluginData.state.common.sendErrorMessage( + msg, + `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.` + ); return; } else { // Ask the mod if we should upgrade to a forcemute as the user is not on the server @@ -61,7 +61,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ ); if (!reply) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "User not on server, mute cancelled by moderator"); + pluginData.state.common.sendErrorMessage(msg, "User not on server, mute cancelled by moderator"); return; } } @@ -69,7 +69,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to mute this member if (memberToMute && !canActOn(pluginData, msg.member, memberToMute)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot mute: insufficient permissions"); + pluginData.state.common.sendErrorMessage(msg, "Cannot mute: insufficient permissions"); return; } @@ -79,7 +79,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } @@ -91,7 +91,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + pluginData.state.common.sendErrorMessage(msg, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts index 5913d67e..b662b33d 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts @@ -4,8 +4,7 @@ import { canActOn, hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualMuteCmd } from "../../functions/actualCommands/actualMuteCmd"; +import { actualMuteCmd } from "./actualMuteCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; @@ -53,9 +52,10 @@ export const MuteSlashCmd = modActionsSlashCmd({ const _isBanned = await isBanned(pluginData, options.user.id); const prefix = pluginData.fullConfig.prefix; if (_isBanned) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.`); + pluginData.state.common.sendErrorMessage( + interaction, + `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.` + ); return; } else { // Ask the mod if we should upgrade to a forcemute as the user is not on the server @@ -66,9 +66,10 @@ export const MuteSlashCmd = modActionsSlashCmd({ ); if (!reply) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "User not on server, mute cancelled by moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "User not on server, mute cancelled by moderator" + ); return; } } @@ -76,7 +77,7 @@ export const MuteSlashCmd = modActionsSlashCmd({ // Make sure we're allowed to mute this member if (memberToMute && !canActOn(pluginData, interaction.member as GuildMember, memberToMute)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot mute: insufficient permissions"); + pluginData.state.common.sendErrorMessage(interaction, "Cannot mute: insufficient permissions"); return; } @@ -89,9 +90,10 @@ export const MuteSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -101,7 +103,7 @@ export const MuteSlashCmd = modActionsSlashCmd({ const convertedTime = options.time ? convertDelayStringToMS(options.time) ?? undefined : undefined; if (options.time && !convertedTime) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); + pluginData.state.common.sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } @@ -109,7 +111,7 @@ export const MuteSlashCmd = modActionsSlashCmd({ try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); + pluginData.state.common.sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts b/backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts similarity index 85% rename from backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts rename to backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts index 2cff62ff..6500d072 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualMuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts @@ -10,12 +10,11 @@ import { isDiscordAPIError, renderUsername, } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { MuteResult } from "../../../Mutes/types"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; /** * The actual function run by both !mute and !forcemute. @@ -57,11 +56,12 @@ export async function actualMuteCmd( }); } catch (e) { if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "Could not mute the user: no mute role set in config"); + pluginData.state.common.sendErrorMessage( + context, + "Could not mute the user: no mute role set in config" + ); } else if (isDiscordAPIError(e) && e.code === 10007) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Could not mute the user: unknown member"); + pluginData.state.common.sendErrorMessage(context, "Could not mute the user: unknown member"); } else { logger.error(`Failed to mute user ${user.id}: ${e.stack}`); if (user.id == null) { @@ -69,7 +69,7 @@ export async function actualMuteCmd( // tslint:disable-next-line:no-console console.trace("[DEBUG] Null user.id for mute"); } - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Could not mute the user"); + pluginData.state.common.sendErrorMessage(context, "Could not mute the user"); } return; @@ -104,5 +104,5 @@ export async function actualMuteCmd( } if (muteResult.notifyResult.text) response += ` (${muteResult.notifyResult.text})`; - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, response); + pluginData.state.common.sendSuccessMessage(context, response); } diff --git a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts index 9861702f..2cccbd6d 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts @@ -1,7 +1,6 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualNoteCmd } from "../../functions/actualCommands/actualNoteCmd"; +import { actualNoteCmd } from "./actualNoteCmd"; import { modActionsMsgCmd } from "../../types"; export const NoteMsgCmd = modActionsMsgCmd({ @@ -17,12 +16,12 @@ export const NoteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } if (!args.note && msg.attachments.size === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Text or attachment required"); + pluginData.state.common.sendErrorMessage(msg, "Text or attachment required"); return; } diff --git a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts index 8962be11..c13bbb60 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts @@ -1,7 +1,6 @@ import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualNoteCmd } from "../../functions/actualCommands/actualNoteCmd"; +import { actualNoteCmd } from "./actualNoteCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -26,9 +25,13 @@ export const NoteSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.note || options.note.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts b/backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts similarity index 85% rename from backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts rename to backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts index 06772113..5c70cb04 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualNoteCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts @@ -3,11 +3,10 @@ import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../../data/CaseTypes"; import { UnknownUser, renderUsername } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; export async function actualNoteCmd( pluginData: GuildPluginData, @@ -39,9 +38,7 @@ export async function actualNoteCmd( reason, }); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, `Note added on **${userName}** (Case #${createdCase.case_number})`, undefined, diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts index 531efc4a..ec346acc 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts @@ -1,8 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { hasPermission } from "../../../../pluginUtils"; import { resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualUnbanCmd } from "../../functions/actualCommands/actualUnbanCmd"; +import { actualUnbanCmd } from "./actualUnbanCmd"; import { modActionsMsgCmd } from "../../types"; const opts = { @@ -26,7 +25,7 @@ export const UnbanMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -34,7 +33,7 @@ export const UnbanMsgCmd = modActionsMsgCmd({ let mod = msg.member; if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg, channelId: msg.channel.id }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts index 954a90ae..a5b0124b 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualUnbanCmd } from "../../functions/actualCommands/actualUnbanCmd"; +import { actualUnbanCmd } from "./actualUnbanCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -30,9 +29,13 @@ export const UnbanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -45,9 +48,10 @@ export const UnbanSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts b/backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts similarity index 81% rename from backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts rename to backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts index 85f9abba..e49b5b21 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts @@ -5,12 +5,11 @@ import { LogType } from "../../../../data/LogType"; import { clearExpiringTempban } from "../../../../data/loops/expiringTempbansLoop"; import { UnknownUser } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { IgnoredEventType, ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { ignoreEvent } from "../ignoreEvent"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ignoreEvent } from "../../functions/ignoreEvent"; export async function actualUnbanCmd( pluginData: GuildPluginData, @@ -32,9 +31,10 @@ export async function actualUnbanCmd( ignoreEvent(pluginData, IgnoredEventType.Unban, user.id); await pluginData.guild.bans.remove(user.id as Snowflake, formattedReason ?? undefined); } catch { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(context, "Failed to unban member; are you sure they're banned?"); + pluginData.state.common.sendErrorMessage( + context, + "Failed to unban member; are you sure they're banned?" + ); return; } @@ -56,7 +56,7 @@ export async function actualUnbanCmd( } // Confirm the action - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, `Member unbanned (Case #${createdCase.case_number})`); + pluginData.state.common.sendSuccessMessage(context, `Member unbanned (Case #${createdCase.case_number})`); // Log the action pluginData.getPlugin(LogsPlugin).logMemberUnban({ diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts index 8e71c8e3..308c34f2 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts @@ -1,5 +1,5 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualHideCaseCmd } from "../../functions/actualCommands/actualHideCaseCmd"; +import { actualHideCaseCmd } from "../hidecase/actualHideCaseCmd"; import { modActionsMsgCmd } from "../../types"; export const UnhideCaseMsgCmd = modActionsMsgCmd({ diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts index 2dbdc309..f4b4b80f 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts @@ -1,5 +1,5 @@ import { slashOptions } from "knub"; -import { actualUnhideCaseCmd } from "../../functions/actualCommands/actualUnhideCaseCmd"; +import { actualUnhideCaseCmd } from "./actualUnhideCaseCmd"; import { modActionsSlashCmd } from "../../types"; export const UnhideCaseSlashCmd = modActionsSlashCmd({ diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts similarity index 73% rename from backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts rename to backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts index 313261ee..f1e8405e 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualUnhideCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts @@ -1,6 +1,5 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; export async function actualUnhideCaseCmd( @@ -21,7 +20,7 @@ export async function actualUnhideCaseCmd( } if (failed.length === caseNumbers.length) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "None of the cases were found!"); + pluginData.state.common.sendErrorMessage(context, "None of the cases were found!"); return; } @@ -31,7 +30,8 @@ export async function actualUnhideCaseCmd( : ""; const amt = caseNumbers.length - failed.length; - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(context, `${amt} case${amt === 1 ? " is" : "s are"} no longer hidden!${failedAddendum}`); + pluginData.state.common.sendSuccessMessage( + context, + `${amt} case${amt === 1 ? " is" : "s are"} no longer hidden!${failedAddendum}` + ); } diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts index b917d83b..a0654d13 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts @@ -2,9 +2,8 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { actualUnmuteCmd } from "./actualUnmuteCmd"; import { isBanned } from "../../functions/isBanned"; import { modActionsMsgCmd } from "../../types"; @@ -36,7 +35,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -50,7 +49,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ !hasMuteRole && !memberToUnmute?.isCommunicationDisabled() ) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot unmute: member is not muted"); + pluginData.state.common.sendErrorMessage(msg, "Cannot unmute: member is not muted"); return; } @@ -58,9 +57,10 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ const banned = await isBanned(pluginData, user.id); const prefix = pluginData.fullConfig.prefix; if (banned) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.`); + pluginData.state.common.sendErrorMessage( + msg, + `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.` + ); return; } else { // Ask the mod if we should upgrade to a forceunmute as the user is not on the server @@ -71,7 +71,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ ); if (!reply) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "User not on server, unmute cancelled by moderator"); + pluginData.state.common.sendErrorMessage(msg, "User not on server, unmute cancelled by moderator"); return; } } @@ -79,7 +79,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to unmute this member if (memberToUnmute && !canActOn(pluginData, msg.member, memberToUnmute)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot unmute: insufficient permissions"); + pluginData.state.common.sendErrorMessage(msg, "Cannot unmute: insufficient permissions"); return; } @@ -89,7 +89,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ if (args.mod) { if (!(await hasPermission(pluginData, "can_act_as_other", { message: msg }))) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You don't have permission to use -mod"); + pluginData.state.common.sendErrorMessage(msg, "You don't have permission to use -mod"); return; } diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts index b3ab730c..609c7451 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts @@ -4,9 +4,8 @@ import { canActOn, hasPermission } from "../../../../pluginUtils"; import { convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { actualUnmuteCmd } from "../../functions/actualCommands/actualUnmuteCmd"; +import { actualUnmuteCmd } from "./actualUnmuteCmd"; import { isBanned } from "../../functions/isBanned"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; @@ -34,9 +33,13 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -51,7 +54,7 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ !hasMuteRole && !memberToUnmute?.isCommunicationDisabled() ) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot unmute: member is not muted"); + pluginData.state.common.sendErrorMessage(interaction, "Cannot unmute: member is not muted"); return; } @@ -59,9 +62,10 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ const banned = await isBanned(pluginData, options.user.id); const prefix = pluginData.fullConfig.prefix; if (banned) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.`); + pluginData.state.common.sendErrorMessage( + interaction, + `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.` + ); return; } else { // Ask the mod if we should upgrade to a forceunmute as the user is not on the server @@ -72,9 +76,10 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ ); if (!reply) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "User not on server, unmute cancelled by moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "User not on server, unmute cancelled by moderator" + ); return; } } @@ -82,7 +87,7 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ // Make sure we're allowed to unmute this member if (memberToUnmute && !canActOn(pluginData, interaction.member as GuildMember, memberToUnmute)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot unmute: insufficient permissions"); + pluginData.state.common.sendErrorMessage(interaction, "Cannot unmute: insufficient permissions"); return; } @@ -95,9 +100,10 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -107,7 +113,7 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ const convertedTime = options.time ? convertDelayStringToMS(options.time) ?? undefined : undefined; if (options.time && !convertedTime) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); + pluginData.state.common.sendErrorMessage(interaction, `Could not convert ${options.time} to a delay`); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts b/backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts similarity index 81% rename from backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts rename to backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts index 11a668b4..3e3be312 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualUnmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts @@ -2,11 +2,10 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message, User } f import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { UnknownUser, asSingleLine, renderUsername } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; export async function actualUnmuteCmd( pluginData: GuildPluginData, @@ -35,14 +34,14 @@ export async function actualUnmuteCmd( }); if (!result) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "User is not muted!"); + pluginData.state.common.sendErrorMessage(context, "User is not muted!"); return; } // Confirm the action to the moderator if (time) { const timeUntilUnmute = time && humanizeDuration(time); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, asSingleLine(` Unmuting **${renderUsername(user)}** @@ -50,7 +49,7 @@ export async function actualUnmuteCmd( `), ); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage( + pluginData.state.common.sendSuccessMessage( context, asSingleLine(` Unmuted **${renderUsername(user)}** diff --git a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts index d6175356..1d9e331f 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts @@ -1,8 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { errorMessage, resolveMember, resolveUser } from "../../../../utils"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualWarnCmd } from "../../functions/actualCommands/actualWarnCmd"; +import { actualWarnCmd } from "./actualWarnCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; @@ -24,7 +23,7 @@ export const WarnMsgCmd = modActionsMsgCmd({ async run({ pluginData, message: msg, args }) { const user = await resolveUser(pluginData.client, args.user); if (!user.id) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found`); + await pluginData.state.common.sendErrorMessage(msg, `User not found`); return; } @@ -33,9 +32,9 @@ export const WarnMsgCmd = modActionsMsgCmd({ if (!memberToWarn) { const _isBanned = await isBanned(pluginData, user.id); if (_isBanned) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User is banned`); + await pluginData.state.common.sendErrorMessage(msg, `User is banned`); } else { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `User not found on the server`); + await pluginData.state.common.sendErrorMessage(msg, `User not found on the server`); } return; @@ -43,7 +42,7 @@ export const WarnMsgCmd = modActionsMsgCmd({ // Make sure we're allowed to warn this member if (!canActOn(pluginData, msg.member, memberToWarn)) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot warn: insufficient permissions"); + await pluginData.state.common.sendErrorMessage(msg, "Cannot warn: insufficient permissions"); return; } @@ -62,7 +61,7 @@ export const WarnMsgCmd = modActionsMsgCmd({ try { contactMethods = readContactMethodsFromArgs(args); } catch (e) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + await pluginData.state.common.sendErrorMessage(msg, e.message); return; } diff --git a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts index 180d52c8..82f80ba0 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts @@ -3,8 +3,7 @@ import { slashOptions } from "knub"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; -import { actualWarnCmd } from "../../functions/actualCommands/actualWarnCmd"; +import { actualWarnCmd } from "./actualWarnCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; @@ -47,9 +46,13 @@ export const WarnSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - await pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); + await pluginData.state.common.sendErrorMessage( + interaction, + "Text or attachment required", + undefined, + undefined, + true + ); return; } @@ -59,9 +62,9 @@ export const WarnSlashCmd = modActionsSlashCmd({ if (!memberToWarn) { const _isBanned = await isBanned(pluginData, options.user.id); if (_isBanned) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `User is banned`); + await pluginData.state.common.sendErrorMessage(interaction, `User is banned`); } else { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, `User not found on the server`); + await pluginData.state.common.sendErrorMessage(interaction, `User not found on the server`); } return; @@ -69,7 +72,7 @@ export const WarnSlashCmd = modActionsSlashCmd({ // Make sure we're allowed to warn this member if (!canActOn(pluginData, interaction.member as GuildMember, memberToWarn)) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, "Cannot warn: insufficient permissions"); + await pluginData.state.common.sendErrorMessage(interaction, "Cannot warn: insufficient permissions"); return; } @@ -81,9 +84,10 @@ export const WarnSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - await pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(interaction, "You don't have permission to act as another moderator"); + await pluginData.state.common.sendErrorMessage( + interaction, + "You don't have permission to act as another moderator" + ); return; } @@ -94,7 +98,7 @@ export const WarnSlashCmd = modActionsSlashCmd({ try { contactMethods = readContactMethodsFromArgs(options) ?? undefined; } catch (e) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(interaction, e.message); + await pluginData.state.common.sendErrorMessage(interaction, e.message); return; } diff --git a/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts b/backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts similarity index 83% rename from backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts rename to backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts index ac43d8df..c764d29d 100644 --- a/backend/src/plugins/ModActions/functions/actualCommands/actualWarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts @@ -4,11 +4,10 @@ import { CaseTypes } from "../../../../data/CaseTypes"; import { UserNotificationMethod, renderUsername } from "../../../../utils"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../../Common/CommonPlugin"; import { ModActionsPluginType } from "../../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../formatReasonForAttachments"; -import { warnMember } from "../warnMember"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { warnMember } from "../../functions/warnMember"; export async function actualWarnCmd( pluginData: GuildPluginData, @@ -37,7 +36,7 @@ export async function actualWarnCmd( { confirmText: "Yes", cancelText: "No", restrictToId: authorId }, ); if (!reply) { - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Warn cancelled by moderator"); + await pluginData.state.common.sendErrorMessage(context, "Warn cancelled by moderator"); return; } } @@ -55,16 +54,14 @@ export async function actualWarnCmd( if (warnResult.status === "failed") { const failReason = warnResult.error ? `: ${warnResult.error}` : ""; - await pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, `Failed to warn user${failReason}`); + await pluginData.state.common.sendErrorMessage(context, `Failed to warn user${failReason}`); return; } const messageResultText = warnResult.notifyResult.text ? ` (${warnResult.notifyResult.text})` : ""; - await pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( + await pluginData.state.common.sendSuccessMessage( context, `Warned **${renderUsername(memberToWarn.user)}** (Case #${warnResult.case.case_number})${messageResultText}`, ); diff --git a/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts b/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts index 868786ed..b10e063e 100644 --- a/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts +++ b/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts @@ -1,6 +1,5 @@ import { ChatInputCommandInteraction, Message, TextBasedChannel } from "discord.js"; import { AnyPluginData, GuildPluginData } from "knub"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { ModActionsPluginType } from "../types"; export function shouldReactToAttachmentLink(pluginData: GuildPluginData) { @@ -22,16 +21,14 @@ export function sendAttachmentLinkDetectionErrorMessage( context: TextBasedChannel | Message | ChatInputCommandInteraction, restricted = false, ) { - const emoji = pluginData.getPlugin(CommonPlugin).getErrorEmoji(); + const emoji = pluginData.state.common.getErrorEmoji(); - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - context, - "You manually added a Discord attachment link to the reason. This link will only work for a limited time.\n" + - "You should instead **re-upload** the attachment with the command, in the same message.\n\n" + - (restricted ? `${emoji} **Command canceled.** ${emoji}` : "").trim(), - ); + pluginData.state.common.sendErrorMessage( + context, + "You manually added a Discord attachment link to the reason. This link will only work for a limited time.\n" + + "You should instead **re-upload** the attachment with the command, in the same message.\n\n" + + (restricted ? `${emoji} **Command canceled.** ${emoji}` : "").trim(), + ); } export async function handleAttachmentLinkDetectionAndGetRestriction( diff --git a/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts b/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts index 4cb16e82..8932aa26 100644 --- a/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts +++ b/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts @@ -1,4 +1,4 @@ -import { Attachment, ChatInputCommandInteraction, Message, TextBasedChannel } from "discord.js"; +import { Attachment, ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; import { isContextMessage } from "../../../pluginUtils"; import { ModActionsPluginType } from "../types"; @@ -19,17 +19,9 @@ export async function formatReasonWithMessageLinkForAttachments( return reason; } - const attachmentChannelId = pluginData.config.get().attachment_storing_channel; - const channel = attachmentChannelId - ? (pluginData.guild.channels.cache.get(attachmentChannelId) as TextBasedChannel) ?? context.channel - : context.channel; + const attachmentsMessage = await pluginData.state.common.storeAttachmentsAsMessage(attachments, context.channel); - const message = await channel!.send({ - content: `Storing ${attachments.length} attachment${attachments.length === 1 ? "" : "s"}`, - files: attachments.map((a) => a.url), - }); - - return ((reason || "") + " " + message.url).trim(); + return ((reason || "") + " " + attachmentsMessage.url).trim(); } export function formatReasonWithAttachments(reason: string, attachments: Attachment[]) { diff --git a/backend/src/plugins/ModActions/functions/updateCase.ts b/backend/src/plugins/ModActions/functions/updateCase.ts index e4011fb7..8cfffa98 100644 --- a/backend/src/plugins/ModActions/functions/updateCase.ts +++ b/backend/src/plugins/ModActions/functions/updateCase.ts @@ -3,7 +3,6 @@ import { GuildPluginData } from "knub"; import { CaseTypes } from "../../../data/CaseTypes"; import { Case } from "../../../data/entities/Case"; import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { ModActionsPluginType } from "../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "./attachmentLinkReaction"; @@ -25,12 +24,12 @@ export async function updateCase( } if (!theCase) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Case not found"); + pluginData.state.common.sendErrorMessage(context, "Case not found"); return; } if (note.length === 0 && attachments.length === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(context, "Text or attachment required"); + pluginData.state.common.sendErrorMessage(context, "Text or attachment required"); return; } @@ -54,5 +53,5 @@ export async function updateCase( note: formattedNote, }); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(context, `Case \`#${theCase.case_number}\` updated`); + pluginData.state.common.sendSuccessMessage(context, `Case \`#${theCase.case_number}\` updated`); } diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index ee128986..a3f36c11 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -1,11 +1,11 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { EventEmitter } from "events"; import { - BasePluginType, + BasePluginType, pluginUtils, guildPluginEventListener, guildPluginMessageCommand, guildPluginSlashCommand, - guildPluginSlashGroup, + guildPluginSlashGroup } from "knub"; import z from "zod"; import { Queue } from "../../Queue"; @@ -16,6 +16,7 @@ import { GuildTempbans } from "../../data/GuildTempbans"; import { Case } from "../../data/entities/Case"; import { UserNotificationMethod, UserNotificationResult } from "../../utils"; import { CaseArgs } from "../Cases/types"; +import { CommonPlugin } from "../Common/CommonPlugin"; export type AttachmentLinkReactionType = "none" | "warn" | "restrict" | null; @@ -38,7 +39,6 @@ export const zModActionsConfig = z.strictObject({ warn_notify_message: z.string(), ban_delete_message_days: z.number(), attachment_link_reaction: z.nullable(z.union([z.literal("none"), z.literal("warn"), z.literal("restrict")])), - attachment_storing_channel: z.nullable(z.string()), can_note: z.boolean(), can_warn: z.boolean(), can_mute: z.boolean(), @@ -84,6 +84,8 @@ export interface ModActionsPluginType extends BasePluginType { massbanQueue: Queue; events: ModActionsEventEmitter; + + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Mutes/MutesPlugin.ts b/backend/src/plugins/Mutes/MutesPlugin.ts index db8548be..c1a8c84b 100644 --- a/backend/src/plugins/Mutes/MutesPlugin.ts +++ b/backend/src/plugins/Mutes/MutesPlugin.ts @@ -24,6 +24,7 @@ import { onMutesEvent } from "./functions/onMutesEvent"; import { renewTimeoutMute } from "./functions/renewTimeoutMute"; import { unmuteUser } from "./functions/unmuteUser"; import { MutesPluginType, zMutesConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions = { config: { @@ -109,6 +110,10 @@ export const MutesPlugin = guildPlugin()({ state.events = new EventEmitter(); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts index 3884ae89..64b77233 100644 --- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts @@ -25,6 +25,6 @@ export const ClearBannedMutesCmd = mutesCmd({ } } - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Cleared ${cleared} mutes from banned users!`); + void pluginData.state.common.sendSuccessMessage(msg, `Cleared ${cleared} mutes from banned users!`); }, }); diff --git a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts index a71dc402..b8f75022 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts @@ -23,15 +23,11 @@ export const ClearMutesCmd = mutesCmd({ } if (failed.length !== args.userIds.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `**${args.userIds.length - failed.length} active mute(s) cleared**`); + void pluginData.state.common.sendSuccessMessage(msg, `**${args.userIds.length - failed.length} active mute(s) cleared**`); } if (failed.length) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( + void pluginData.state.common.sendErrorMessage( msg, `**${failed.length}/${args.userIds.length} IDs failed**, they are not muted: ${failed.join(" ")}`, ); diff --git a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts index 1e52f6b3..c5f7be13 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts @@ -26,8 +26,6 @@ export const ClearMutesWithoutRoleCmd = mutesCmd({ } } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `Cleared ${cleared} mutes from members that don't have the mute role`); + void pluginData.state.common.sendSuccessMessage(msg, `Cleared ${cleared} mutes from members that don't have the mute role`); }, }); diff --git a/backend/src/plugins/Mutes/types.ts b/backend/src/plugins/Mutes/types.ts index e1f266a9..59790782 100644 --- a/backend/src/plugins/Mutes/types.ts +++ b/backend/src/plugins/Mutes/types.ts @@ -1,6 +1,6 @@ import { GuildMember } from "discord.js"; import { EventEmitter } from "events"; -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildArchives } from "../../data/GuildArchives"; import { GuildCases } from "../../data/GuildCases"; @@ -10,6 +10,7 @@ import { Case } from "../../data/entities/Case"; import { Mute } from "../../data/entities/Mute"; import { UserNotificationMethod, UserNotificationResult, zSnowflake } from "../../utils"; import { CaseArgs } from "../Cases/types"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zMutesConfig = z.strictObject({ mute_role: zSnowflake.nullable(), @@ -53,6 +54,8 @@ export interface MutesPluginType extends BasePluginType { unregisterTimeoutMuteToRenewListener: () => void; events: MutesEventEmitter; + + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts index ee226f3e..f8d5f990 100644 --- a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts +++ b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts @@ -4,6 +4,7 @@ import { GuildNicknameHistory } from "../../data/GuildNicknameHistory"; import { UsernameHistory } from "../../data/UsernameHistory"; import { NamesCmd } from "./commands/NamesCmd"; import { NameHistoryPluginType, zNameHistoryConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -44,4 +45,8 @@ export const NameHistoryPlugin = guildPlugin()({ state.usernameHistory = new UsernameHistory(); state.updateQueue = new Queue(); }, + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, }); diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts index f584857f..9f3bb418 100644 --- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts +++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts @@ -21,7 +21,7 @@ export const NamesCmd = nameHistoryCmd({ const usernames = await pluginData.state.usernameHistory.getByUserId(args.userId); if (nicknames.length === 0 && usernames.length === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No name history found"); + void pluginData.state.common.sendErrorMessage(msg, "No name history found"); return; } diff --git a/backend/src/plugins/NameHistory/types.ts b/backend/src/plugins/NameHistory/types.ts index 70101b53..df96a56b 100644 --- a/backend/src/plugins/NameHistory/types.ts +++ b/backend/src/plugins/NameHistory/types.ts @@ -1,8 +1,9 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { Queue } from "../../Queue"; import { GuildNicknameHistory } from "../../data/GuildNicknameHistory"; import { UsernameHistory } from "../../data/UsernameHistory"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zNameHistoryConfig = z.strictObject({ can_view: z.boolean(), @@ -14,6 +15,7 @@ export interface NameHistoryPluginType extends BasePluginType { nicknameHistory: GuildNicknameHistory; usernameHistory: UsernameHistory; updateQueue: Queue; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts index 68dbcd2e..118cf044 100644 --- a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts +++ b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts @@ -3,6 +3,7 @@ import { GuildPingableRoles } from "../../data/GuildPingableRoles"; import { PingableRoleDisableCmd } from "./commands/PingableRoleDisableCmd"; import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd"; import { PingableRolesPluginType, zPingableRolesConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -44,4 +45,8 @@ export const PingableRolesPlugin = guildPlugin()({ state.cache = new Map(); state.timeouts = new Map(); }, + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, }); diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts index 00006cee..3bc1ad58 100644 --- a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts +++ b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts @@ -14,17 +14,13 @@ export const PingableRoleDisableCmd = pingableRolesCmd({ async run({ message: msg, args, pluginData }) { const pingableRole = await pluginData.state.pingableRoles.getByChannelAndRoleId(args.channelId, args.role.id); if (!pingableRole) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `**${args.role.name}** is not set as pingable in <#${args.channelId}>`); + void pluginData.state.common.sendErrorMessage(msg, `**${args.role.name}** is not set as pingable in <#${args.channelId}>`); return; } await pluginData.state.pingableRoles.delete(args.channelId, args.role.id); pluginData.state.cache.delete(args.channelId); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `**${args.role.name}** is no longer set as pingable in <#${args.channelId}>`); + void pluginData.state.common.sendSuccessMessage(msg, `**${args.role.name}** is no longer set as pingable in <#${args.channelId}>`); }, }); diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts index 7a93990f..004c0741 100644 --- a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts +++ b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts @@ -17,17 +17,13 @@ export const PingableRoleEnableCmd = pingableRolesCmd({ args.role.id, ); if (existingPingableRole) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `**${args.role.name}** is already set as pingable in <#${args.channelId}>`); + void pluginData.state.common.sendErrorMessage(msg, `**${args.role.name}** is already set as pingable in <#${args.channelId}>`); return; } await pluginData.state.pingableRoles.add(args.channelId, args.role.id); pluginData.state.cache.delete(args.channelId); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `**${args.role.name}** has been set as pingable in <#${args.channelId}>`); + void pluginData.state.common.sendSuccessMessage(msg, `**${args.role.name}** has been set as pingable in <#${args.channelId}>`); }, }); diff --git a/backend/src/plugins/PingableRoles/types.ts b/backend/src/plugins/PingableRoles/types.ts index 3bd6faa8..55edd97c 100644 --- a/backend/src/plugins/PingableRoles/types.ts +++ b/backend/src/plugins/PingableRoles/types.ts @@ -1,7 +1,8 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildPingableRoles } from "../../data/GuildPingableRoles"; import { PingableRole } from "../../data/entities/PingableRole"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zPingableRolesConfig = z.strictObject({ can_manage: z.boolean(), @@ -14,6 +15,7 @@ export interface PingableRolesPluginType extends BasePluginType { pingableRoles: GuildPingableRoles; cache: Map; timeouts: Map; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Post/PostPlugin.ts b/backend/src/plugins/Post/PostPlugin.ts index 0deb881b..93376dcf 100644 --- a/backend/src/plugins/Post/PostPlugin.ts +++ b/backend/src/plugins/Post/PostPlugin.ts @@ -14,6 +14,7 @@ import { ScheduledPostsListCmd } from "./commands/ScheduledPostsListCmd"; import { ScheduledPostsShowCmd } from "./commands/ScheduledPostsShowCmd"; import { PostPluginType, zPostConfig } from "./types"; import { postScheduledPost } from "./util/postScheduledPost"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -55,6 +56,10 @@ export const PostPlugin = guildPlugin()({ state.logs = new GuildLogs(guild.id); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/Post/commands/EditCmd.ts b/backend/src/plugins/Post/commands/EditCmd.ts index cd607aa6..fb785929 100644 --- a/backend/src/plugins/Post/commands/EditCmd.ts +++ b/backend/src/plugins/Post/commands/EditCmd.ts @@ -15,18 +15,18 @@ export const EditCmd = postCmd({ async run({ message: msg, args, pluginData }) { const targetMessage = await args.message.channel.messages.fetch(args.message.messageId); if (!targetMessage) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown message"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown message"); return; } if (targetMessage.author.id !== pluginData.client.user!.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Message wasn't posted by me"); + void pluginData.state.common.sendErrorMessage(msg, "Message wasn't posted by me"); return; } targetMessage.channel.messages.edit(targetMessage.id, { content: formatContent(args.content), }); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Message edited"); + void pluginData.state.common.sendSuccessMessage(msg, "Message edited"); }, }); diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts index 7d42c040..4cdfdd8b 100644 --- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts @@ -30,14 +30,14 @@ export const EditEmbedCmd = postCmd({ if (colorRgb) { color = rgbToInt(colorRgb); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid color specified"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid color specified"); return; } } const targetMessage = await args.message.channel.messages.fetch(args.message.messageId); if (!targetMessage) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown message"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown message"); return; } @@ -51,12 +51,12 @@ export const EditEmbedCmd = postCmd({ try { parsed = JSON.parse(content); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Syntax error in embed JSON: ${e.message}`); + void pluginData.state.common.sendErrorMessage(msg, `Syntax error in embed JSON: ${e.message}`); return; } if (!isValidEmbed(parsed)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Embed is not valid"); + void pluginData.state.common.sendErrorMessage(msg, "Embed is not valid"); return; } @@ -69,7 +69,7 @@ export const EditEmbedCmd = postCmd({ args.message.channel.messages.edit(targetMessage.id, { embeds: [embed], }); - await pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Embed edited"); + await pluginData.state.common.sendSuccessMessage(msg, "Embed edited"); if (args.content) { const prefix = pluginData.fullConfig.prefix || "!"; diff --git a/backend/src/plugins/Post/commands/PostEmbedCmd.ts b/backend/src/plugins/Post/commands/PostEmbedCmd.ts index a78abacb..e54649e6 100644 --- a/backend/src/plugins/Post/commands/PostEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/PostEmbedCmd.ts @@ -31,7 +31,7 @@ export const PostEmbedCmd = postCmd({ const content = args.content || args.maincontent; if (!args.title && !content) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Title or content required"); + void pluginData.state.common.sendErrorMessage(msg, "Title or content required"); return; } @@ -41,7 +41,7 @@ export const PostEmbedCmd = postCmd({ if (colorRgb) { color = rgbToInt(colorRgb); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid color specified"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid color specified"); return; } } @@ -56,12 +56,12 @@ export const PostEmbedCmd = postCmd({ try { parsed = JSON.parse(content); } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Syntax error in embed JSON: ${e.message}`); + void pluginData.state.common.sendErrorMessage(msg, `Syntax error in embed JSON: ${e.message}`); return; } if (!isValidEmbed(parsed)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Embed is not valid"); + void pluginData.state.common.sendErrorMessage(msg, "Embed is not valid"); return; } diff --git a/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts index 565135e6..d3c6063a 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts @@ -17,12 +17,12 @@ export const ScheduledPostsDeleteCmd = postCmd({ scheduledPosts.sort(sorter("post_at")); const post = scheduledPosts[args.num - 1]; if (!post) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Scheduled post not found"); + void pluginData.state.common.sendErrorMessage(msg, "Scheduled post not found"); return; } clearUpcomingScheduledPost(post); await pluginData.state.scheduledPosts.delete(post.id); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Scheduled post deleted!"); + void pluginData.state.common.sendSuccessMessage(msg, "Scheduled post deleted!"); }, }); diff --git a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts index 2895cc68..a990e6d9 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts @@ -17,7 +17,7 @@ export const ScheduledPostsShowCmd = postCmd({ scheduledPosts.sort(sorter("post_at")); const post = scheduledPosts[args.num - 1]; if (!post) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Scheduled post not found"); + void pluginData.state.common.sendErrorMessage(msg, "Scheduled post not found"); return; } diff --git a/backend/src/plugins/Post/types.ts b/backend/src/plugins/Post/types.ts index e0ec7d2c..7a0a1db7 100644 --- a/backend/src/plugins/Post/types.ts +++ b/backend/src/plugins/Post/types.ts @@ -1,8 +1,9 @@ -import { BasePluginType, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildScheduledPosts } from "../../data/GuildScheduledPosts"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zPostConfig = z.strictObject({ can_post: z.boolean(), @@ -14,6 +15,7 @@ export interface PostPluginType extends BasePluginType { savedMessages: GuildSavedMessages; scheduledPosts: GuildScheduledPosts; logs: GuildLogs; + common: pluginUtils.PluginPublicInterface; unregisterGuildEventListener: () => void; }; diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index 537d469f..b75bcc53 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -40,15 +40,11 @@ export async function actualPostCmd( if (opts.repeat) { if (opts.repeat < MIN_REPEAT_TIME) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Minimum time for -repeat is ${humanizeDuration(MIN_REPEAT_TIME)}`); + void pluginData.state.common.sendErrorMessage(msg, `Minimum time for -repeat is ${humanizeDuration(MIN_REPEAT_TIME)}`); return; } if (opts.repeat > MAX_REPEAT_TIME) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Max time for -repeat is ${humanizeDuration(MAX_REPEAT_TIME)}`); + void pluginData.state.common.sendErrorMessage(msg, `Max time for -repeat is ${humanizeDuration(MAX_REPEAT_TIME)}`); return; } } @@ -59,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) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid schedule time"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid schedule time"); return; } } else if (opts.repeat) { @@ -76,41 +72,35 @@ export async function actualPostCmd( // Invalid time if (!repeatUntil) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid time specified for -repeat-until"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid time specified for -repeat-until"); return; } if (repeatUntil.isBefore(moment.utc())) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You can't set -repeat-until in the past"); + void pluginData.state.common.sendErrorMessage(msg, "You can't set -repeat-until in the past"); return; } if (repeatUntil.isAfter(MAX_REPEAT_UNTIL)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - msg, - "Unfortunately, -repeat-until can only be at most 100 years into the future. Maybe 99 years would be enough?", - ); + void pluginData.state.common.sendErrorMessage( + msg, + "Unfortunately, -repeat-until can only be at most 100 years into the future. Maybe 99 years would be enough?", + ); return; } } else if (opts["repeat-times"]) { repeatTimes = opts["repeat-times"]; if (repeatTimes <= 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "-repeat-times must be 1 or more"); + void pluginData.state.common.sendErrorMessage(msg, "-repeat-times must be 1 or more"); return; } } if (repeatUntil && repeatTimes) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "You can only use one of -repeat-until or -repeat-times at once"); + void pluginData.state.common.sendErrorMessage(msg, "You can only use one of -repeat-until or -repeat-times at once"); return; } if (opts.repeat && !repeatUntil && !repeatTimes) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "You must specify -repeat-until or -repeat-times for repeated messages"); + void pluginData.state.common.sendErrorMessage(msg, "You must specify -repeat-until or -repeat-times for repeated messages"); return; } @@ -125,7 +115,7 @@ export async function actualPostCmd( // Save schedule/repeat information in DB if (postAt) { if (postAt < moment.utc()) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Post can't be scheduled to be posted in the past"); + void pluginData.state.common.sendErrorMessage(msg, "Post can't be scheduled to be posted in the past"); return; } @@ -201,6 +191,6 @@ export async function actualPostCmd( } if (targetChannel.id !== msg.channel.id || opts.schedule || opts.repeat) { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, successMessage); + void pluginData.state.common.sendSuccessMessage(msg, successMessage); } } diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts index 8622b3b9..1848e663 100644 --- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts +++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts @@ -9,6 +9,7 @@ import { RefreshReactionRolesCmd } from "./commands/RefreshReactionRolesCmd"; import { AddReactionRoleEvt } from "./events/AddReactionRoleEvt"; import { MessageDeletedEvt } from "./events/MessageDeletedEvt"; import { ReactionRolesPluginType, zReactionRolesConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const MIN_AUTO_REFRESH = 1000 * 60 * 15; // 15min minimum, let's not abuse the API @@ -63,6 +64,10 @@ export const ReactionRolesPlugin = guildPlugin()({ state.pendingRefreshes = new Set(); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const config = pluginData.config.get(); if (config.button_groups) { diff --git a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts index 1dc632a7..18baef48 100644 --- a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts @@ -15,7 +15,7 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ async run({ message: msg, args, pluginData }) { const existingReactionRoles = pluginData.state.reactionRoles.getForMessage(args.message.messageId); if (!existingReactionRoles) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Message doesn't have reaction roles on it"); + void pluginData.state.common.sendErrorMessage(msg, "Message doesn't have reaction roles on it"); return; } @@ -26,7 +26,7 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ targetMessage = await args.message.channel.messages.fetch(args.message.messageId); } catch (err) { if (isDiscordAPIError(err) && err.code === 50001) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Missing access to the specified message"); + void pluginData.state.common.sendErrorMessage(msg, "Missing access to the specified message"); return; } @@ -35,6 +35,6 @@ export const ClearReactionRolesCmd = reactionRolesCmd({ await targetMessage.reactions.removeAll(); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Reaction roles cleared"); + void pluginData.state.common.sendSuccessMessage(msg, "Reaction roles cleared"); }, }); diff --git a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts index 26d49039..1c166039 100644 --- a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts @@ -34,9 +34,7 @@ export const InitReactionRolesCmd = reactionRolesCmd({ async run({ message: msg, args, pluginData }) { if (!canReadChannel(args.message.channel, msg.member)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "You can't add reaction roles to channels you can't see yourself"); + void pluginData.state.common.sendErrorMessage(msg, "You can't add reaction roles to channels you can't see yourself"); return; } @@ -45,7 +43,7 @@ export const InitReactionRolesCmd = reactionRolesCmd({ targetMessage = await args.message.channel.messages.fetch(args.message.messageId); } catch (e) { if (isDiscordAPIError(e)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Error ${e.code} while getting message: ${e.message}`); + void pluginData.state.common.sendErrorMessage(msg, `Error ${e.code} while getting message: ${e.message}`); return; } @@ -73,26 +71,22 @@ export const InitReactionRolesCmd = reactionRolesCmd({ // Verify the specified emojis and roles are valid and usable for (const pair of emojiRolePairs) { if (pair[0] === CLEAR_ROLES_EMOJI) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `The emoji for clearing roles (${CLEAR_ROLES_EMOJI}) is reserved and cannot be used`); + void pluginData.state.common.sendErrorMessage(msg, `The emoji for clearing roles (${CLEAR_ROLES_EMOJI}) is reserved and cannot be used`); return; } if (!isValidEmoji(pair[0])) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Invalid emoji: ${pair[0]}`); + void pluginData.state.common.sendErrorMessage(msg, `Invalid emoji: ${pair[0]}`); return; } if (!canUseEmoji(pluginData.client, pair[0])) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "I can only use regular emojis and custom emojis from servers I'm on"); + void pluginData.state.common.sendErrorMessage(msg, "I can only use regular emojis and custom emojis from servers I'm on"); return; } if (!pluginData.guild.roles.cache.has(pair[1] as Snowflake)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Unknown role ${pair[1]}`); + void pluginData.state.common.sendErrorMessage(msg, `Unknown role ${pair[1]}`); return; } } @@ -123,11 +117,9 @@ export const InitReactionRolesCmd = reactionRolesCmd({ ); if (errors?.length) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Errors while adding reaction roles:\n${errors.join("\n")}`); + void pluginData.state.common.sendErrorMessage(msg, `Errors while adding reaction roles:\n${errors.join("\n")}`); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Reaction roles added"); + void pluginData.state.common.sendSuccessMessage(msg, "Reaction roles added"); } (await progressMessage).delete().catch(noop); diff --git a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts index 6d26ff48..fa0e8ac1 100644 --- a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts @@ -13,12 +13,12 @@ export const RefreshReactionRolesCmd = reactionRolesCmd({ async run({ message: msg, args, pluginData }) { if (pluginData.state.pendingRefreshes.has(`${args.message.channel.id}-${args.message.messageId}`)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Another refresh in progress"); + void pluginData.state.common.sendErrorMessage(msg, "Another refresh in progress"); return; } await refreshReactionRoles(pluginData, args.message.channel.id, args.message.messageId); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Reaction roles refreshed"); + void pluginData.state.common.sendSuccessMessage(msg, "Reaction roles refreshed"); }, }); diff --git a/backend/src/plugins/ReactionRoles/types.ts b/backend/src/plugins/ReactionRoles/types.ts index b955c6fa..c985ece4 100644 --- a/backend/src/plugins/ReactionRoles/types.ts +++ b/backend/src/plugins/ReactionRoles/types.ts @@ -1,8 +1,9 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { Queue } from "../../Queue"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zReactionRolesConfig = z.strictObject({ auto_refresh_interval: z.number(), @@ -37,6 +38,8 @@ export interface ReactionRolesPluginType extends BasePluginType { pendingRefreshes: Set; autoRefreshTimeout: NodeJS.Timeout; + + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Reminders/RemindersPlugin.ts b/backend/src/plugins/Reminders/RemindersPlugin.ts index d43961c3..a6070112 100644 --- a/backend/src/plugins/Reminders/RemindersPlugin.ts +++ b/backend/src/plugins/Reminders/RemindersPlugin.ts @@ -7,6 +7,7 @@ import { RemindersCmd } from "./commands/RemindersCmd"; import { RemindersDeleteCmd } from "./commands/RemindersDeleteCmd"; import { postReminder } from "./functions/postReminder"; import { RemindersPluginType, zRemindersConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -44,6 +45,10 @@ export const RemindersPlugin = guildPlugin()({ state.unloaded = false; }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state, guild } = pluginData; diff --git a/backend/src/plugins/Reminders/commands/RemindCmd.ts b/backend/src/plugins/Reminders/commands/RemindCmd.ts index 88ceeaa3..d0fb4eb0 100644 --- a/backend/src/plugins/Reminders/commands/RemindCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindCmd.ts @@ -38,7 +38,7 @@ export const RemindCmd = remindersCmd({ // "Delay string" i.e. e.g. "2h30m" const ms = convertDelayStringToMS(args.time); if (ms === null) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid reminder time"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid reminder time"); return; } @@ -46,7 +46,7 @@ export const RemindCmd = remindersCmd({ } if (!reminderTime.isValid() || reminderTime.isBefore(now)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid reminder time"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid reminder time"); return; } @@ -67,8 +67,6 @@ export const RemindCmd = remindersCmd({ pluginData.getPlugin(TimeAndDatePlugin).getDateFormat("pretty_datetime"), ); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `I will remind you in **${timeUntilReminder}** at **${prettyReminderTime}**`); + void pluginData.state.common.sendSuccessMessage(msg, `I will remind you in **${timeUntilReminder}** at **${prettyReminderTime}**`); }, }); diff --git a/backend/src/plugins/Reminders/commands/RemindersCmd.ts b/backend/src/plugins/Reminders/commands/RemindersCmd.ts index 7b2da150..9f6dacc7 100644 --- a/backend/src/plugins/Reminders/commands/RemindersCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersCmd.ts @@ -12,7 +12,7 @@ export const RemindersCmd = remindersCmd({ async run({ message: msg, pluginData }) { const reminders = await pluginData.state.reminders.getRemindersByUserId(msg.author.id); if (reminders.length === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No reminders"); + void pluginData.state.common.sendErrorMessage(msg, "No reminders"); return; } diff --git a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts index 5566a133..7a57f79b 100644 --- a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts @@ -17,7 +17,7 @@ export const RemindersDeleteCmd = remindersCmd({ reminders.sort(sorter("remind_at")); if (args.num > reminders.length || args.num <= 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown reminder"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown reminder"); return; } @@ -25,6 +25,6 @@ export const RemindersDeleteCmd = remindersCmd({ clearUpcomingReminder(toDelete); await pluginData.state.reminders.delete(toDelete.id); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Reminder deleted"); + void pluginData.state.common.sendSuccessMessage(msg, "Reminder deleted"); }, }); diff --git a/backend/src/plugins/Reminders/types.ts b/backend/src/plugins/Reminders/types.ts index 4356fac0..ee2ad9bb 100644 --- a/backend/src/plugins/Reminders/types.ts +++ b/backend/src/plugins/Reminders/types.ts @@ -1,6 +1,7 @@ -import { BasePluginType, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildReminders } from "../../data/GuildReminders"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zRemindersConfig = z.strictObject({ can_use: z.boolean(), @@ -12,6 +13,7 @@ export interface RemindersPluginType extends BasePluginType { state: { reminders: GuildReminders; tries: Map; + common: pluginUtils.PluginPublicInterface; unregisterGuildEventListener: () => void; diff --git a/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts b/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts index d7f9111a..ecd25e8d 100644 --- a/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts +++ b/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts @@ -6,6 +6,7 @@ import { resetButtonsCmd } from "./commands/resetButtons"; import { onButtonInteraction } from "./events/buttonInteraction"; import { applyAllRoleButtons } from "./functions/applyAllRoleButtons"; import { RoleButtonsPluginType, zRoleButtonsConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const RoleButtonsPlugin = guildPlugin()({ name: "role_buttons", @@ -37,6 +38,10 @@ export const RoleButtonsPlugin = guildPlugin()({ pluginData.state.roleButtons = GuildRoleButtons.getGuildInstance(pluginData.guild.id); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + async afterLoad(pluginData) { await applyAllRoleButtons(pluginData); }, diff --git a/backend/src/plugins/RoleButtons/commands/resetButtons.ts b/backend/src/plugins/RoleButtons/commands/resetButtons.ts index edd99eb0..78b3e6a2 100644 --- a/backend/src/plugins/RoleButtons/commands/resetButtons.ts +++ b/backend/src/plugins/RoleButtons/commands/resetButtons.ts @@ -16,14 +16,12 @@ export const resetButtonsCmd = guildPluginMessageCommand( async run({ pluginData, args, message }) { const config = pluginData.config.get(); if (!config.buttons[args.name]) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(message, `Can't find role buttons with the name "${args.name}"`); + void pluginData.state.common.sendErrorMessage(message, `Can't find role buttons with the name "${args.name}"`); return; } await pluginData.state.roleButtons.deleteRoleButtonItem(args.name); await applyAllRoleButtons(pluginData); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(message, "Done!"); + void pluginData.state.common.sendSuccessMessage(message, "Done!"); }, }); diff --git a/backend/src/plugins/RoleButtons/types.ts b/backend/src/plugins/RoleButtons/types.ts index 95e46f79..42fa6bf9 100644 --- a/backend/src/plugins/RoleButtons/types.ts +++ b/backend/src/plugins/RoleButtons/types.ts @@ -1,10 +1,11 @@ import { ButtonStyle } from "discord.js"; -import { BasePluginType } from "knub"; +import { BasePluginType, pluginUtils } from "knub"; import z from "zod"; import { GuildRoleButtons } from "../../data/GuildRoleButtons"; import { zBoundedCharacters, zBoundedRecord, zMessageContent, zSnowflake } from "../../utils"; import { TooManyComponentsError } from "./functions/TooManyComponentsError"; import { createButtonComponents } from "./functions/createButtonComponents"; +import { CommonPlugin } from "../Common/CommonPlugin"; const zRoleButtonOption = z.strictObject({ role_id: zSnowflake, @@ -109,5 +110,6 @@ export interface RoleButtonsPluginType extends BasePluginType { config: z.infer; state: { roleButtons: GuildRoleButtons; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Roles/RolesPlugin.ts b/backend/src/plugins/Roles/RolesPlugin.ts index 89b3b6c9..4d4bdbb9 100644 --- a/backend/src/plugins/Roles/RolesPlugin.ts +++ b/backend/src/plugins/Roles/RolesPlugin.ts @@ -7,6 +7,7 @@ import { MassAddRoleCmd } from "./commands/MassAddRoleCmd"; import { MassRemoveRoleCmd } from "./commands/MassRemoveRoleCmd"; import { RemoveRoleCmd } from "./commands/RemoveRoleCmd"; import { RolesPluginType, zRolesConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -50,4 +51,8 @@ export const RolesPlugin = guildPlugin()({ state.logs = new GuildLogs(guild.id); }, + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, }); diff --git a/backend/src/plugins/Roles/commands/AddRoleCmd.ts b/backend/src/plugins/Roles/commands/AddRoleCmd.ts index a66ff365..66506c9e 100644 --- a/backend/src/plugins/Roles/commands/AddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/AddRoleCmd.ts @@ -19,21 +19,19 @@ export const AddRoleCmd = rolesCmd({ async run({ message: msg, args, pluginData }) { if (!canActOn(pluginData, msg.member, args.member, true)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "Cannot add roles to this user: insufficient permissions"); + void pluginData.state.common.sendErrorMessage(msg, "Cannot add roles to this user: insufficient permissions"); return; } const roleId = await resolveRoleId(pluginData.client, pluginData.guild.id, args.role); if (!roleId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid role id"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid role id"); return; } const config = await pluginData.config.getForMessage(msg); if (!config.assignable_roles.includes(roleId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot assign that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot assign that role"); return; } @@ -43,12 +41,12 @@ export const AddRoleCmd = rolesCmd({ pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown role configured for 'roles' plugin: ${roleId}`, }); - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot assign that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot assign that role"); return; } if (args.member.roles.cache.has(roleId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member already has that role"); + void pluginData.state.common.sendErrorMessage(msg, "Member already has that role"); return; } @@ -60,8 +58,6 @@ export const AddRoleCmd = rolesCmd({ roles: [role], }); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `Added role **${role.name}** to ${verboseUserMention(args.member.user)}!`); + void pluginData.state.common.sendSuccessMessage(msg, `Added role **${role.name}** to ${verboseUserMention(args.member.user)}!`); }, }); diff --git a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts index 05db86ba..991cdcdb 100644 --- a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts @@ -30,22 +30,20 @@ export const MassAddRoleCmd = rolesCmd({ for (const member of members) { if (!canActOn(pluginData, msg.member, member, true)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "Cannot add roles to 1 or more specified members: insufficient permissions"); + void pluginData.state.common.sendErrorMessage(msg, "Cannot add roles to 1 or more specified members: insufficient permissions"); return; } } const roleId = await resolveRoleId(pluginData.client, pluginData.guild.id, args.role); if (!roleId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid role id"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid role id"); return; } const config = await pluginData.config.getForMessage(msg); if (!config.assignable_roles.includes(roleId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot assign that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot assign that role"); return; } @@ -54,7 +52,7 @@ export const MassAddRoleCmd = rolesCmd({ pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown role configured for 'roles' plugin: ${roleId}`, }); - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot assign that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot assign that role"); return; } diff --git a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts index 06a5337d..6ba75d53 100644 --- a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts @@ -29,22 +29,20 @@ export const MassRemoveRoleCmd = rolesCmd({ for (const member of members) { if (!canActOn(pluginData, msg.member, member, true)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "Cannot add roles to 1 or more specified members: insufficient permissions"); + void pluginData.state.common.sendErrorMessage(msg, "Cannot add roles to 1 or more specified members: insufficient permissions"); return; } } const roleId = await resolveRoleId(pluginData.client, pluginData.guild.id, args.role); if (!roleId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid role id"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid role id"); return; } const config = await pluginData.config.getForMessage(msg); if (!config.assignable_roles.includes(roleId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot remove that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot remove that role"); return; } @@ -53,7 +51,7 @@ export const MassRemoveRoleCmd = rolesCmd({ pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown role configured for 'roles' plugin: ${roleId}`, }); - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot remove that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot remove that role"); return; } diff --git a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts index e3dc979d..d1b8a7fa 100644 --- a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts @@ -19,21 +19,19 @@ export const RemoveRoleCmd = rolesCmd({ async run({ message: msg, args, pluginData }) { if (!canActOn(pluginData, msg.member, args.member, true)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "Cannot remove roles from this user: insufficient permissions"); + void pluginData.state.common.sendErrorMessage(msg, "Cannot remove roles from this user: insufficient permissions"); return; } const roleId = await resolveRoleId(pluginData.client, pluginData.guild.id, args.role); if (!roleId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid role id"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid role id"); return; } const config = await pluginData.config.getForMessage(msg); if (!config.assignable_roles.includes(roleId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot remove that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot remove that role"); return; } @@ -43,12 +41,12 @@ export const RemoveRoleCmd = rolesCmd({ pluginData.getPlugin(LogsPlugin).logBotAlert({ body: `Unknown role configured for 'roles' plugin: ${roleId}`, }); - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "You cannot remove that role"); + void pluginData.state.common.sendErrorMessage(msg, "You cannot remove that role"); return; } if (!args.member.roles.cache.has(roleId)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member doesn't have that role"); + void pluginData.state.common.sendErrorMessage(msg, "Member doesn't have that role"); return; } @@ -59,8 +57,6 @@ export const RemoveRoleCmd = rolesCmd({ roles: [role], }); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `Removed role **${role.name}** from ${verboseUserMention(args.member.user)}!`); + void pluginData.state.common.sendSuccessMessage(msg, `Removed role **${role.name}** from ${verboseUserMention(args.member.user)}!`); }, }); diff --git a/backend/src/plugins/Roles/types.ts b/backend/src/plugins/Roles/types.ts index caf55b76..c3f48670 100644 --- a/backend/src/plugins/Roles/types.ts +++ b/backend/src/plugins/Roles/types.ts @@ -1,6 +1,7 @@ -import { BasePluginType, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildLogs } from "../../data/GuildLogs"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zRolesConfig = z.strictObject({ can_assign: z.boolean(), @@ -12,6 +13,7 @@ export interface RolesPluginType extends BasePluginType { config: z.infer; state: { logs: GuildLogs; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts index 9a9e770c..a6a823d8 100644 --- a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts +++ b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts @@ -3,6 +3,7 @@ import { RoleAddCmd } from "./commands/RoleAddCmd"; import { RoleHelpCmd } from "./commands/RoleHelpCmd"; import { RoleRemoveCmd } from "./commands/RoleRemoveCmd"; import { SelfGrantableRolesPluginType, zSelfGrantableRolesConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -27,4 +28,8 @@ export const SelfGrantableRolesPlugin = guildPlugin Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, { - users: [msg.author.id], - }); + void pluginData.state.common.sendErrorMessage(msg, `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, { + users: [msg.author.id], + }); lock.unlock(); return; } @@ -83,11 +81,9 @@ export const RoleAddCmd = selfGrantableRolesCmd({ roles: Array.from(newRoleIds) as Snowflake[], }); } catch { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `<@!${msg.author.id}> Got an error while trying to grant you the roles`, { - users: [msg.author.id], - }); + void pluginData.state.common.sendErrorMessage(msg, `<@!${msg.author.id}> Got an error while trying to grant you the roles`, { + users: [msg.author.id], + }); return; } @@ -118,7 +114,7 @@ export const RoleAddCmd = selfGrantableRolesCmd({ messageParts.push("couldn't recognize some of the roles"); } - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `<@!${msg.author.id}> ${messageParts.join("; ")}`, { + void pluginData.state.common.sendSuccessMessage(msg, `<@!${msg.author.id}> ${messageParts.join("; ")}`, { users: [msg.author.id], }); diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts index b688203f..11e4a4cd 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts @@ -46,34 +46,26 @@ export const RoleRemoveCmd = selfGrantableRolesCmd({ const removedRolesWord = rolesToRemove.length === 1 ? "role" : "roles"; if (rolesToRemove.length !== roleNames.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord};` + - ` couldn't recognize the other roles you mentioned`, - { users: [msg.author.id] }, - ); + void pluginData.state.common.sendSuccessMessage( + msg, + `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord};` + + ` couldn't recognize the other roles you mentioned`, + { users: [msg.author.id] }, + ); } else { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord}`, { - users: [msg.author.id], - }); - } - } catch { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `<@!${msg.author.id}> Got an error while trying to remove the roles`, { + void pluginData.state.common.sendSuccessMessage(msg, `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord}`, { users: [msg.author.id], }); - } - } else { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, { + } + } catch { + void pluginData.state.common.sendSuccessMessage(msg, `<@!${msg.author.id}> Got an error while trying to remove the roles`, { users: [msg.author.id], }); + } + } else { + void pluginData.state.common.sendErrorMessage(msg, `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, { + users: [msg.author.id], + }); } lock.unlock(); diff --git a/backend/src/plugins/SelfGrantableRoles/types.ts b/backend/src/plugins/SelfGrantableRoles/types.ts index e3c7a786..7d8c4a0f 100644 --- a/backend/src/plugins/SelfGrantableRoles/types.ts +++ b/backend/src/plugins/SelfGrantableRoles/types.ts @@ -1,6 +1,7 @@ -import { BasePluginType, CooldownManager, guildPluginMessageCommand } from "knub"; +import { BasePluginType, CooldownManager, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { zBoundedCharacters, zBoundedRecord } from "../../utils"; +import { CommonPlugin } from "../Common/CommonPlugin"; const zRoleMap = z.record( zBoundedCharacters(1, 100), @@ -27,6 +28,7 @@ export interface SelfGrantableRolesPluginType extends BasePluginType { config: z.infer; state: { cooldowns: CooldownManager; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Slowmode/SlowmodePlugin.ts b/backend/src/plugins/Slowmode/SlowmodePlugin.ts index 8e97adb1..8a0b7de9 100644 --- a/backend/src/plugins/Slowmode/SlowmodePlugin.ts +++ b/backend/src/plugins/Slowmode/SlowmodePlugin.ts @@ -12,6 +12,7 @@ import { SlowmodeSetCmd } from "./commands/SlowmodeSetCmd"; import { SlowmodePluginType, zSlowmodeConfig } from "./types"; import { clearExpiredSlowmodes } from "./util/clearExpiredSlowmodes"; import { onMessageCreate } from "./util/onMessageCreate"; +import { CommonPlugin } from "../Common/CommonPlugin"; const BOT_SLOWMODE_CLEAR_INTERVAL = 60 * SECONDS; @@ -63,6 +64,10 @@ export const SlowmodePlugin = guildPlugin()({ state.channelSlowmodeCache = new Map(); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state } = pluginData; diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts index d3c8cedb..29465e79 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts @@ -22,16 +22,14 @@ export const SlowmodeClearCmd = slowmodeCmd({ async run({ message: msg, args, pluginData }) { const channelSlowmode = await pluginData.state.slowmodes.getChannelSlowmode(args.channel.id); if (!channelSlowmode) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Channel doesn't have slowmode!"); + void pluginData.state.common.sendErrorMessage(msg, "Channel doesn't have slowmode!"); return; } const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; const missingPermissions = getMissingChannelPermissions(me, args.channel, BOT_SLOWMODE_CLEAR_PERMISSIONS); if (missingPermissions) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Unable to clear slowmode. ${missingPermissionError(missingPermissions)}`); + void pluginData.state.common.sendErrorMessage(msg, `Unable to clear slowmode. ${missingPermissionError(missingPermissions)}`); return; } @@ -39,7 +37,7 @@ export const SlowmodeClearCmd = slowmodeCmd({ if (args.channel.type === ChannelType.GuildText) { await clearBotSlowmodeFromUserId(pluginData, args.channel, args.user.id, args.force); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage( + void pluginData.state.common.sendErrorMessage( msg, asSingleLine(` Failed to clear slowmode from **${renderUsername(args.user)}** in <#${args.channel.id}>: @@ -49,7 +47,7 @@ export const SlowmodeClearCmd = slowmodeCmd({ return; } } catch (e) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage( + void pluginData.state.common.sendErrorMessage( msg, asSingleLine(` Failed to clear slowmode from **${renderUsername(args.user)}** in <#${args.channel.id}>: @@ -59,8 +57,6 @@ export const SlowmodeClearCmd = slowmodeCmd({ return; } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `Slowmode cleared from **${renderUsername(args.user)}** in <#${args.channel.id}>`); + void pluginData.state.common.sendSuccessMessage(msg, `Slowmode cleared from **${renderUsername(args.user)}** in <#${args.channel.id}>`); }, }); diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index 0d088b43..6f951084 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -40,9 +40,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ const channel = args.channel || msg.channel; if (!channel.isTextBased() || channel.isThread()) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, "Slowmode can only be set on non-thread text-based channels"); + void pluginData.state.common.sendErrorMessage(msg, "Slowmode can only be set on non-thread text-based channels"); return; } @@ -58,25 +56,23 @@ export const SlowmodeSetCmd = slowmodeCmd({ const mode = (args.mode as TMode) || defaultMode; if (!validModes.includes(mode)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "--mode must be 'bot' or 'native'"); + void pluginData.state.common.sendErrorMessage(msg, "--mode must be 'bot' or 'native'"); return; } // Validate durations if (mode === "native" && args.time > MAX_NATIVE_SLOWMODE) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Native slowmode can only be set to 6h or less"); + void pluginData.state.common.sendErrorMessage(msg, "Native slowmode can only be set to 6h or less"); return; } if (mode === "bot" && args.time > MAX_BOT_SLOWMODE) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Sorry, bot managed slowmodes can be at most 100 years long. Maybe 99 would be enough?`); + void pluginData.state.common.sendErrorMessage(msg, `Sorry, bot managed slowmodes can be at most 100 years long. Maybe 99 would be enough?`); return; } if (mode === "bot" && args.time < MIN_BOT_SLOWMODE) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage( + void pluginData.state.common.sendErrorMessage( msg, asSingleLine(` Bot managed slowmode must be 15min or more. @@ -95,9 +91,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ NATIVE_SLOWMODE_PERMISSIONS, ); if (missingPermissions) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Unable to set native slowmode. ${missingPermissionError(missingPermissions)}`); + void pluginData.state.common.sendErrorMessage(msg, `Unable to set native slowmode. ${missingPermissionError(missingPermissions)}`); return; } } @@ -108,9 +102,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ BOT_SLOWMODE_PERMISSIONS, ); if (missingPermissions) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Unable to set bot managed slowmode. ${missingPermissionError(missingPermissions)}`); + void pluginData.state.common.sendErrorMessage(msg, `Unable to set bot managed slowmode. ${missingPermissionError(missingPermissions)}`); return; } } @@ -129,9 +121,7 @@ export const SlowmodeSetCmd = slowmodeCmd({ try { await channel.setRateLimitPerUser(rateLimitSeconds); } catch (e) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Failed to set native slowmode: ${escapeInlineCode(e.message)}`); + void pluginData.state.common.sendErrorMessage(msg, `Failed to set native slowmode: ${escapeInlineCode(e.message)}`); return; } } else { @@ -150,8 +140,6 @@ export const SlowmodeSetCmd = slowmodeCmd({ const humanizedSlowmodeTime = humanizeDuration(args.time); const slowmodeType = mode === "native" ? "native slowmode" : "bot-maintained slowmode"; - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `Set ${humanizedSlowmodeTime} slowmode for <#${channel.id}> (${slowmodeType})`); + void pluginData.state.common.sendSuccessMessage(msg, `Set ${humanizedSlowmodeTime} slowmode for <#${channel.id}> (${slowmodeType})`); }, }); diff --git a/backend/src/plugins/Slowmode/types.ts b/backend/src/plugins/Slowmode/types.ts index 7c8d5b56..73bd3cb8 100644 --- a/backend/src/plugins/Slowmode/types.ts +++ b/backend/src/plugins/Slowmode/types.ts @@ -1,9 +1,10 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildSlowmodes } from "../../data/GuildSlowmodes"; import { SlowmodeChannel } from "../../data/entities/SlowmodeChannel"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zSlowmodeConfig = z.strictObject({ use_native_slowmode: z.boolean(), @@ -21,6 +22,7 @@ export interface SlowmodePluginType extends BasePluginType { clearInterval: NodeJS.Timeout; serverLogs: GuildLogs; channelSlowmodeCache: Map; + common: pluginUtils.PluginPublicInterface; onMessageCreateFn; }; diff --git a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts index 72c86a04..da245eb4 100644 --- a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts +++ b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts @@ -11,16 +11,14 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { const hasNativeSlowmode = args.channel.rateLimitPerUser; if (!botSlowmode && hasNativeSlowmode === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Channel is not on slowmode!"); + void pluginData.state.common.sendErrorMessage(msg, "Channel is not on slowmode!"); return; } const me = pluginData.guild.members.cache.get(pluginData.client.user!.id); const missingPermissions = getMissingChannelPermissions(me, args.channel, BOT_SLOWMODE_DISABLE_PERMISSIONS); if (missingPermissions) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Unable to disable slowmode. ${missingPermissionError(missingPermissions)}`); + void pluginData.state.common.sendErrorMessage(msg, `Unable to disable slowmode. ${missingPermissionError(missingPermissions)}`); return; } @@ -39,14 +37,12 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { } if (failedUsers.length) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `Slowmode disabled! Failed to clear slowmode from the following users:\n\n<@!${failedUsers.join(">\n<@!")}>`, - ); + void pluginData.state.common.sendSuccessMessage( + msg, + `Slowmode disabled! Failed to clear slowmode from the following users:\n\n<@!${failedUsers.join(">\n<@!")}>`, + ); } else { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Slowmode disabled!"); + void pluginData.state.common.sendSuccessMessage(msg, "Slowmode disabled!"); initMsg.delete().catch(noop); } } diff --git a/backend/src/plugins/Starboard/StarboardPlugin.ts b/backend/src/plugins/Starboard/StarboardPlugin.ts index 7e12102c..9888b013 100644 --- a/backend/src/plugins/Starboard/StarboardPlugin.ts +++ b/backend/src/plugins/Starboard/StarboardPlugin.ts @@ -7,6 +7,7 @@ import { StarboardReactionAddEvt } from "./events/StarboardReactionAddEvt"; import { StarboardReactionRemoveAllEvt, StarboardReactionRemoveEvt } from "./events/StarboardReactionRemoveEvts"; import { StarboardPluginType, zStarboardConfig } from "./types"; import { onMessageDelete } from "./util/onMessageDelete"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -50,6 +51,10 @@ export const StarboardPlugin = guildPlugin()({ state.starboardReactions = GuildStarboardReactions.getGuildInstance(guild.id); }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state } = pluginData; diff --git a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts index d074c948..114b293f 100644 --- a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts +++ b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts @@ -19,13 +19,13 @@ export const MigratePinsCmd = starboardCmd({ const config = await pluginData.config.get(); const starboard = config.boards[args.starboardName]; if (!starboard) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown starboard specified"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown starboard specified"); return; } const starboardChannel = pluginData.guild.channels.cache.get(starboard.channel_id as Snowflake); if (!starboardChannel || !(starboardChannel instanceof TextChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Starboard has an unknown/invalid channel id"); + void pluginData.state.common.sendErrorMessage(msg, "Starboard has an unknown/invalid channel id"); return; } @@ -43,8 +43,6 @@ export const MigratePinsCmd = starboardCmd({ await saveMessageToStarboard(pluginData, pin, starboard); } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `Pins migrated from <#${args.pinChannel.id}> to <#${starboardChannel.id}>!`); + void pluginData.state.common.sendSuccessMessage(msg, `Pins migrated from <#${args.pinChannel.id}> to <#${starboardChannel.id}>!`); }, }); diff --git a/backend/src/plugins/Starboard/types.ts b/backend/src/plugins/Starboard/types.ts index bb8845fe..2e625d5a 100644 --- a/backend/src/plugins/Starboard/types.ts +++ b/backend/src/plugins/Starboard/types.ts @@ -1,9 +1,10 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildStarboardMessages } from "../../data/GuildStarboardMessages"; import { GuildStarboardReactions } from "../../data/GuildStarboardReactions"; import { zBoundedRecord, zSnowflake } from "../../utils"; +import { CommonPlugin } from "../Common/CommonPlugin"; const zStarboardOpts = z.strictObject({ channel_id: zSnowflake, @@ -29,6 +30,7 @@ export interface StarboardPluginType extends BasePluginType { savedMessages: GuildSavedMessages; starboardMessages: GuildStarboardMessages; starboardReactions: GuildStarboardReactions; + common: pluginUtils.PluginPublicInterface; onMessageDeleteFn; }; diff --git a/backend/src/plugins/Tags/TagsPlugin.ts b/backend/src/plugins/Tags/TagsPlugin.ts index 09379d6d..97d667c4 100644 --- a/backend/src/plugins/Tags/TagsPlugin.ts +++ b/backend/src/plugins/Tags/TagsPlugin.ts @@ -20,6 +20,7 @@ import { findTagByName } from "./util/findTagByName"; import { onMessageCreate } from "./util/onMessageCreate"; import { onMessageDelete } from "./util/onMessageDelete"; import { renderTagBody } from "./util/renderTagBody"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -91,6 +92,10 @@ export const TagsPlugin = guildPlugin()({ state.tagFunctions = {}; }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { state } = pluginData; diff --git a/backend/src/plugins/Tags/commands/TagCreateCmd.ts b/backend/src/plugins/Tags/commands/TagCreateCmd.ts index 0ee452f5..8aab9647 100644 --- a/backend/src/plugins/Tags/commands/TagCreateCmd.ts +++ b/backend/src/plugins/Tags/commands/TagCreateCmd.ts @@ -17,7 +17,7 @@ export const TagCreateCmd = tagsCmd({ parseTemplate(args.body); } catch (e) { if (e instanceof TemplateParseError) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Invalid tag syntax: ${e.message}`); + void pluginData.state.common.sendErrorMessage(msg, `Invalid tag syntax: ${e.message}`); return; } else { throw e; @@ -27,6 +27,6 @@ export const TagCreateCmd = tagsCmd({ await pluginData.state.tags.createOrUpdate(args.tag, args.body, msg.author.id); const prefix = pluginData.config.get().prefix; - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `Tag set! Use it with: \`${prefix}${args.tag}\``); + void pluginData.state.common.sendSuccessMessage(msg, `Tag set! Use it with: \`${prefix}${args.tag}\``); }, }); diff --git a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts index 174b7b64..618b6796 100644 --- a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts +++ b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts @@ -13,11 +13,11 @@ export const TagDeleteCmd = tagsCmd({ async run({ message: msg, args, pluginData }) { const tag = await pluginData.state.tags.find(args.tag); if (!tag) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No tag with that name"); + void pluginData.state.common.sendErrorMessage(msg, "No tag with that name"); return; } await pluginData.state.tags.delete(args.tag); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Tag deleted!"); + void pluginData.state.common.sendSuccessMessage(msg, "Tag deleted!"); }, }); diff --git a/backend/src/plugins/Tags/commands/TagEvalCmd.ts b/backend/src/plugins/Tags/commands/TagEvalCmd.ts index 580c938b..9cdab774 100644 --- a/backend/src/plugins/Tags/commands/TagEvalCmd.ts +++ b/backend/src/plugins/Tags/commands/TagEvalCmd.ts @@ -29,7 +29,7 @@ export const TagEvalCmd = tagsCmd({ )) as MessageCreateOptions; if (!rendered.content && !rendered.embeds?.length) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Evaluation resulted in an empty text"); + void pluginData.state.common.sendErrorMessage(msg, "Evaluation resulted in an empty text"); return; } @@ -37,7 +37,7 @@ export const TagEvalCmd = tagsCmd({ } catch (e) { const errorMessage = e instanceof TemplateParseError ? e.message : "Internal error"; - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Failed to render tag: ${errorMessage}`); + void pluginData.state.common.sendErrorMessage(msg, `Failed to render tag: ${errorMessage}`); if (!(e instanceof TemplateParseError)) { logger.warn(`Internal error evaluating tag in ${pluginData.guild.id}: ${e}`); diff --git a/backend/src/plugins/Tags/commands/TagSourceCmd.ts b/backend/src/plugins/Tags/commands/TagSourceCmd.ts index 6690f8f7..0a16c41b 100644 --- a/backend/src/plugins/Tags/commands/TagSourceCmd.ts +++ b/backend/src/plugins/Tags/commands/TagSourceCmd.ts @@ -18,18 +18,18 @@ export const TagSourceCmd = tagsCmd({ if (args.delete) { const actualTag = await pluginData.state.tags.find(args.tag); if (!actualTag) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No tag with that name"); + void pluginData.state.common.sendErrorMessage(msg, "No tag with that name"); return; } await pluginData.state.tags.delete(args.tag); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, "Tag deleted!"); + void pluginData.state.common.sendSuccessMessage(msg, "Tag deleted!"); return; } const tag = await pluginData.state.tags.find(args.tag); if (!tag) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No tag with that name"); + void pluginData.state.common.sendErrorMessage(msg, "No tag with that name"); return; } diff --git a/backend/src/plugins/Tags/types.ts b/backend/src/plugins/Tags/types.ts index 8b8b472b..c750edc8 100644 --- a/backend/src/plugins/Tags/types.ts +++ b/backend/src/plugins/Tags/types.ts @@ -1,10 +1,11 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { GuildArchives } from "../../data/GuildArchives"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildTags } from "../../data/GuildTags"; import { zBoundedCharacters, zStrictMessageContent } from "../../utils"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zTag = z.union([zBoundedCharacters(0, 4000), zStrictMessageContent]); export type TTag = z.infer; @@ -59,6 +60,7 @@ export interface TagsPluginType extends BasePluginType { tags: GuildTags; savedMessages: GuildSavedMessages; logs: GuildLogs; + common: pluginUtils.PluginPublicInterface; onMessageCreateFn; diff --git a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts index 78dd8fa0..4c84c4ff 100644 --- a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts +++ b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts @@ -11,6 +11,7 @@ import { getMemberTz } from "./functions/getMemberTz"; import { inGuildTz } from "./functions/inGuildTz"; import { inMemberTz } from "./functions/inMemberTz"; import { TimeAndDatePluginType, zTimeAndDateConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -57,4 +58,8 @@ export const TimeAndDatePlugin = guildPlugin()({ state.memberTimezones = GuildMemberTimezones.getGuildInstance(guild.id); }, + + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, }); diff --git a/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts index 2c39519e..88eddd18 100644 --- a/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts @@ -11,8 +11,6 @@ export const ResetTimezoneCmd = timeAndDateCmd({ async run({ pluginData, message }) { await pluginData.state.memberTimezones.reset(message.author.id); const serverTimezone = getGuildTz(pluginData); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(message, `Your timezone has been reset to server default, **${serverTimezone}**`); + void pluginData.state.common.sendSuccessMessage(message, `Your timezone has been reset to server default, **${serverTimezone}**`); }, }); diff --git a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts index 70acf129..684f60f7 100644 --- a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts @@ -16,7 +16,7 @@ export const SetTimezoneCmd = timeAndDateCmd({ async run({ pluginData, message, args }) { const parsedTz = parseFuzzyTimezone(args.timezone); if (!parsedTz) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage( + void pluginData.state.common.sendErrorMessage( message, trimLines(` Invalid timezone: \`${escapeInlineCode(args.timezone)}\` @@ -28,6 +28,6 @@ export const SetTimezoneCmd = timeAndDateCmd({ } await pluginData.state.memberTimezones.set(message.author.id, parsedTz); - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(message, `Your timezone is now set to **${parsedTz}**`); + void pluginData.state.common.sendSuccessMessage(message, `Your timezone is now set to **${parsedTz}**`); }, }); diff --git a/backend/src/plugins/TimeAndDate/types.ts b/backend/src/plugins/TimeAndDate/types.ts index 7a942518..5bb5253d 100644 --- a/backend/src/plugins/TimeAndDate/types.ts +++ b/backend/src/plugins/TimeAndDate/types.ts @@ -1,10 +1,11 @@ -import { BasePluginType, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; import { U } from "ts-toolbelt"; import z from "zod"; import { GuildMemberTimezones } from "../../data/GuildMemberTimezones"; import { keys } from "../../utils"; import { zValidTimezone } from "../../utils/zValidTimezone"; import { defaultDateFormats } from "./defaultDateFormats"; +import { CommonPlugin } from "../Common/CommonPlugin"; const zDateFormatKeys = z.enum(keys(defaultDateFormats) as U.ListOf); @@ -18,6 +19,7 @@ export interface TimeAndDatePluginType extends BasePluginType { config: z.infer; state: { memberTimezones: GuildMemberTimezones; + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/plugins/Utility/UtilityPlugin.ts b/backend/src/plugins/Utility/UtilityPlugin.ts index 59da3e97..bd35837e 100644 --- a/backend/src/plugins/Utility/UtilityPlugin.ts +++ b/backend/src/plugins/Utility/UtilityPlugin.ts @@ -193,11 +193,15 @@ export const UtilityPlugin = guildPlugin()({ } }, + beforeStart(pluginData) { + pluginData.state.common = pluginData.getPlugin(CommonPlugin); + }, + afterLoad(pluginData) { const { guild } = pluginData; if (activeReloads.has(guild.id)) { - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(activeReloads.get(guild.id)!, "Reloaded!"); + pluginData.state.common.sendSuccessMessage(activeReloads.get(guild.id)!, "Reloaded!"); activeReloads.delete(guild.id); } }, diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index e06c7d89..b0b7ce7e 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -24,7 +24,7 @@ export const AvatarCmd = utilityCmd({ }; msg.channel.send({ embeds: [embed] }); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid user ID"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid user ID"); } }, }); diff --git a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts index 5b4a70bb..dc0901bc 100644 --- a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts @@ -16,7 +16,7 @@ export const ChannelInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { const embed = await getChannelInfoEmbed(pluginData, args.channel); if (!embed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown channel"); + void pluginData.state.common.sendErrorMessage(message, "Unknown channel"); return; } diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index 11e7bcfb..6eac645e 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -83,22 +83,18 @@ export interface CleanArgs { export async function cleanCmd(pluginData: GuildPluginData, args: CleanArgs | any, msg) { if (args.count > MAX_CLEAN_COUNT || args.count <= 0) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - msg, - `Clean count must be between 1 and ${MAX_CLEAN_COUNT}`, - undefined, - args["response-interaction"], - ); + void pluginData.state.common.sendErrorMessage( + msg, + `Clean count must be between 1 and ${MAX_CLEAN_COUNT}`, + undefined, + args["response-interaction"], + ); return; } const targetChannel = args.channel ? pluginData.guild.channels.cache.get(args.channel as Snowflake) : msg.channel; if (!targetChannel?.isTextBased()) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Invalid channel specified`, undefined, args["response-interaction"]); + void pluginData.state.common.sendErrorMessage(msg, `Invalid channel specified`, undefined, args["response-interaction"]); return; } @@ -110,14 +106,12 @@ export async function cleanCmd(pluginData: GuildPluginData, a categoryId: targetChannel.parentId, }); if (configForTargetChannel.can_clean !== true) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - msg, - `Missing permissions to use clean on that channel`, - undefined, - args["response-interaction"], - ); + void pluginData.state.common.sendErrorMessage( + msg, + `Missing permissions to use clean on that channel`, + undefined, + args["response-interaction"], + ); return; } } @@ -223,14 +217,10 @@ export async function cleanCmd(pluginData: GuildPluginData, a } } - responseMsg = await pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, responseText, undefined, args["response-interaction"]); + responseMsg = await pluginData.state.common.sendSuccessMessage(msg, responseText, undefined, args["response-interaction"]); } else { const responseText = `Found no messages to clean${note ? ` (${note})` : ""}!`; - responseMsg = await pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, responseText, undefined, args["response-interaction"]); + responseMsg = await pluginData.state.common.sendErrorMessage(msg, responseText, undefined, args["response-interaction"]); } cleaningMessage?.delete(); diff --git a/backend/src/plugins/Utility/commands/ContextCmd.ts b/backend/src/plugins/Utility/commands/ContextCmd.ts index eb613f57..9db76606 100644 --- a/backend/src/plugins/Utility/commands/ContextCmd.ts +++ b/backend/src/plugins/Utility/commands/ContextCmd.ts @@ -23,7 +23,7 @@ export const ContextCmd = utilityCmd({ async run({ message: msg, args, pluginData }) { if (args.channel && !(args.channel instanceof TextChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Channel must be a text channel"); + void pluginData.state.common.sendErrorMessage(msg, "Channel must be a text channel"); return; } @@ -31,7 +31,7 @@ export const ContextCmd = utilityCmd({ const messageId = args.messageId ?? args.message.messageId; if (!canReadChannel(channel, msg.member)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Message context not found"); + void pluginData.state.common.sendErrorMessage(msg, "Message context not found"); return; } @@ -42,7 +42,7 @@ export const ContextCmd = utilityCmd({ }) )[0]; if (!previousMessage) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Message context not found"); + void pluginData.state.common.sendErrorMessage(msg, "Message context not found"); return; } diff --git a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts index 114652a9..e5806aec 100644 --- a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts @@ -17,13 +17,13 @@ export const EmojiInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { const emojiId = getCustomEmojiId(args.emoji); if (!emojiId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Emoji not found"); + void pluginData.state.common.sendErrorMessage(message, "Emoji not found"); return; } const embed = await getEmojiInfoEmbed(pluginData, emojiId); if (!embed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Emoji not found"); + void pluginData.state.common.sendErrorMessage(message, "Emoji not found"); return; } diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index 23ffa8ac..9314dbce 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -146,11 +146,9 @@ export const InfoCmd = utilityCmd({ } // 10. No can do - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - message, - "Could not find anything with that value or you are lacking permission for the snowflake type", - ); + void pluginData.state.common.sendErrorMessage( + message, + "Could not find anything with that value or you are lacking permission for the snowflake type", + ); }, }); diff --git a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts index 262ab94a..bbecd794 100644 --- a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts @@ -18,7 +18,7 @@ export const InviteInfoCmd = utilityCmd({ const inviteCode = parseInviteCodeInput(args.inviteCode); const embed = await getInviteInfoEmbed(pluginData, inviteCode); if (!embed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown invite"); + void pluginData.state.common.sendErrorMessage(message, "Unknown invite"); return; } diff --git a/backend/src/plugins/Utility/commands/JumboCmd.ts b/backend/src/plugins/Utility/commands/JumboCmd.ts index a8cf8678..d29dc608 100644 --- a/backend/src/plugins/Utility/commands/JumboCmd.ts +++ b/backend/src/plugins/Utility/commands/JumboCmd.ts @@ -51,7 +51,7 @@ export const JumboCmd = utilityCmd({ let file: AttachmentBuilder | undefined; if (!isEmoji(args.emoji)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Invalid emoji"); + void pluginData.state.common.sendErrorMessage(msg, "Invalid emoji"); return; } @@ -87,7 +87,7 @@ export const JumboCmd = utilityCmd({ } } if (!image) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Error occurred while jumboing default emoji"); + void pluginData.state.common.sendErrorMessage(msg, "Error occurred while jumboing default emoji"); return; } diff --git a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts index 88df8eff..4ea7da69 100644 --- a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts @@ -16,13 +16,13 @@ export const MessageInfoCmd = utilityCmd({ async run({ message, args, pluginData }) { if (!canReadChannel(args.message.channel, message.member)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown message"); + void pluginData.state.common.sendErrorMessage(message, "Unknown message"); return; } const embed = await getMessageInfoEmbed(pluginData, args.message.channel.id, args.message.messageId); if (!embed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Unknown message"); + void pluginData.state.common.sendErrorMessage(message, "Unknown message"); return; } diff --git a/backend/src/plugins/Utility/commands/NicknameCmd.ts b/backend/src/plugins/Utility/commands/NicknameCmd.ts index 63d5eac8..fd33a755 100644 --- a/backend/src/plugins/Utility/commands/NicknameCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameCmd.ts @@ -46,11 +46,9 @@ export const NicknameCmd = utilityCmd({ return; } - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `Changed nickname of <@!${args.member.id}> from **${oldNickname}** to **${args.nickname}**`, - ); + void pluginData.state.common.sendSuccessMessage( + msg, + `Changed nickname of <@!${args.member.id}> from **${oldNickname}** to **${args.nickname}**`, + ); }, }); diff --git a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts index 61417419..8fd23c84 100644 --- a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts @@ -32,6 +32,6 @@ export const NicknameResetCmd = utilityCmd({ return; } - pluginData.getPlugin(CommonPlugin).sendSuccessMessage(msg, `The nickname of <@!${args.member.id}> has been reset`); + void pluginData.state.common.sendSuccessMessage(msg, `The nickname of <@!${args.member.id}> has been reset`); }, }); diff --git a/backend/src/plugins/Utility/commands/RolesCmd.ts b/backend/src/plugins/Utility/commands/RolesCmd.ts index d04903f9..08ec5dc1 100644 --- a/backend/src/plugins/Utility/commands/RolesCmd.ts +++ b/backend/src/plugins/Utility/commands/RolesCmd.ts @@ -62,7 +62,7 @@ export const RolesCmd = utilityCmd({ } else if (sort === "name") { roles.sort(sorter((r) => r.name.toLowerCase(), sortDir)); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown sorting method"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown sorting method"); return; } diff --git a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts index 2e5d7ba5..0388d8cd 100644 --- a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts @@ -17,7 +17,7 @@ export const ServerInfoCmd = utilityCmd({ const serverId = args.serverId || pluginData.guild.id; const serverInfoEmbed = await getServerInfoEmbed(pluginData, serverId); if (!serverInfoEmbed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "Could not find information for that server"); + void pluginData.state.common.sendErrorMessage(message, "Could not find information for that server"); return; } diff --git a/backend/src/plugins/Utility/commands/SourceCmd.ts b/backend/src/plugins/Utility/commands/SourceCmd.ts index be3a4bab..5fccc109 100644 --- a/backend/src/plugins/Utility/commands/SourceCmd.ts +++ b/backend/src/plugins/Utility/commands/SourceCmd.ts @@ -17,13 +17,13 @@ export const SourceCmd = utilityCmd({ async run({ message: cmdMessage, args, pluginData }) { if (!canReadChannel(args.message.channel, cmdMessage.member)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(cmdMessage, "Unknown message"); + void pluginData.state.common.sendErrorMessage(cmdMessage, "Unknown message"); return; } const message = await args.message.channel.messages.fetch(args.message.messageId); if (!message) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(cmdMessage, "Unknown message"); + void pluginData.state.common.sendErrorMessage(cmdMessage, "Unknown message"); return; } diff --git a/backend/src/plugins/Utility/commands/UserInfoCmd.ts b/backend/src/plugins/Utility/commands/UserInfoCmd.ts index 6ba99548..9f2698a9 100644 --- a/backend/src/plugins/Utility/commands/UserInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/UserInfoCmd.ts @@ -19,7 +19,7 @@ export const UserInfoCmd = utilityCmd({ const userId = args.user?.id || message.author.id; const embed = await getUserInfoEmbed(pluginData, userId, args.compact); if (!embed) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(message, "User not found"); + void pluginData.state.common.sendErrorMessage(message, "User not found"); return; } diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index 6ad01cdb..797f5dda 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -18,12 +18,12 @@ export const VcdisconnectCmd = utilityCmd({ async run({ message: msg, args, pluginData }) { if (!canActOn(pluginData, msg.member, args.member)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cannot move: insufficient permissions"); + void pluginData.state.common.sendErrorMessage(msg, "Cannot move: insufficient permissions"); return; } if (!args.member.voice?.channelId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member is not in a voice channel"); + void pluginData.state.common.sendErrorMessage(msg, "Member is not in a voice channel"); return; } const channel = pluginData.guild.channels.cache.get(args.member.voice.channelId) as VoiceChannel; @@ -31,7 +31,7 @@ export const VcdisconnectCmd = utilityCmd({ try { await args.member.voice.disconnect(); } catch { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Failed to disconnect member"); + void pluginData.state.common.sendErrorMessage(msg, "Failed to disconnect member"); return; } @@ -41,8 +41,9 @@ export const VcdisconnectCmd = utilityCmd({ oldChannel: channel, }); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `**${renderUsername(args.member)}** disconnected from **${channel.name}**`); + pluginData.state.common.sendSuccessMessage( + msg, + `**${renderUsername(args.member)}** disconnected from **${channel.name}**` + ); }, }); diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index abf47bbb..eee432c7 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -24,7 +24,7 @@ export const VcmoveCmd = utilityCmd({ // Snowflake -> resolve channel directly const potentialChannel = pluginData.guild.channels.cache.get(args.channel as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown or non-voice channel"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown or non-voice channel"); return; } @@ -34,7 +34,7 @@ export const VcmoveCmd = utilityCmd({ const channelId = args.channel.match(channelMentionRegex)![1]; const potentialChannel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown or non-voice channel"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown or non-voice channel"); return; } @@ -46,7 +46,7 @@ export const VcmoveCmd = utilityCmd({ ); const closestMatch = simpleClosestStringMatch(args.channel, voiceChannels, (ch) => ch.name); if (!closestMatch) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No matching voice channels"); + void pluginData.state.common.sendErrorMessage(msg, "No matching voice channels"); return; } @@ -54,12 +54,12 @@ export const VcmoveCmd = utilityCmd({ } if (!args.member.voice?.channelId) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member is not in a voice channel"); + void pluginData.state.common.sendErrorMessage(msg, "Member is not in a voice channel"); return; } if (args.member.voice.channelId === channel.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Member is already on that channel!"); + void pluginData.state.common.sendErrorMessage(msg, "Member is already on that channel!"); return; } @@ -70,7 +70,7 @@ export const VcmoveCmd = utilityCmd({ channel: channel.id, }); } catch { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Failed to move member"); + void pluginData.state.common.sendErrorMessage(msg, "Failed to move member"); return; } @@ -81,9 +81,7 @@ export const VcmoveCmd = utilityCmd({ newChannel: channel, }); - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage(msg, `**${renderUsername(args.member)}** moved to **${channel.name}**`); + void pluginData.state.common.sendSuccessMessage(msg, `**${renderUsername(args.member)}** moved to **${channel.name}**`); }, }); @@ -105,7 +103,7 @@ export const VcmoveAllCmd = utilityCmd({ // Snowflake -> resolve channel directly const potentialChannel = pluginData.guild.channels.cache.get(args.channel as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown or non-voice channel"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown or non-voice channel"); return; } @@ -115,7 +113,7 @@ export const VcmoveAllCmd = utilityCmd({ const channelId = args.channel.match(channelMentionRegex)![1]; const potentialChannel = pluginData.guild.channels.cache.get(channelId as Snowflake); if (!potentialChannel || !(potentialChannel instanceof VoiceChannel)) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown or non-voice channel"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown or non-voice channel"); return; } @@ -127,7 +125,7 @@ export const VcmoveAllCmd = utilityCmd({ ); const closestMatch = simpleClosestStringMatch(args.channel, voiceChannels, (ch) => ch.name); if (!closestMatch) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No matching voice channels"); + void pluginData.state.common.sendErrorMessage(msg, "No matching voice channels"); return; } @@ -135,12 +133,12 @@ export const VcmoveAllCmd = utilityCmd({ } if (args.oldChannel.members.size === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Voice channel is empty"); + void pluginData.state.common.sendErrorMessage(msg, "Voice channel is empty"); return; } if (args.oldChannel.id === channel.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Cant move from and to the same channel!"); + void pluginData.state.common.sendErrorMessage(msg, "Cant move from and to the same channel!"); return; } @@ -153,12 +151,10 @@ export const VcmoveAllCmd = utilityCmd({ // Check for permissions but allow self-moves if (currMember.id !== msg.member.id && !canActOn(pluginData, msg.member, currMember)) { - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage( - msg, - `Failed to move ${renderUsername(currMember)} (${currMember.id}): You cannot act on this member`, - ); + void pluginData.state.common.sendErrorMessage( + msg, + `Failed to move ${renderUsername(currMember)} (${currMember.id}): You cannot act on this member`, + ); errAmt++; continue; } @@ -169,12 +165,10 @@ export const VcmoveAllCmd = utilityCmd({ }); } catch { if (msg.member.id === currMember.id) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "Unknown error when trying to move members"); + void pluginData.state.common.sendErrorMessage(msg, "Unknown error when trying to move members"); return; } - pluginData - .getPlugin(CommonPlugin) - .sendErrorMessage(msg, `Failed to move ${renderUsername(currMember)} (${currMember.id})`); + void pluginData.state.common.sendErrorMessage(msg, `Failed to move ${renderUsername(currMember)} (${currMember.id})`); errAmt++; continue; } @@ -188,14 +182,12 @@ export const VcmoveAllCmd = utilityCmd({ } if (moveAmt !== errAmt) { - pluginData - .getPlugin(CommonPlugin) - .sendSuccessMessage( - msg, - `${moveAmt - errAmt} members from **${args.oldChannel.name}** moved to **${channel.name}**`, - ); + void pluginData.state.common.sendSuccessMessage( + msg, + `${moveAmt - errAmt} members from **${args.oldChannel.name}** moved to **${channel.name}**`, + ); } else { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, `Failed to move any members.`); + void pluginData.state.common.sendErrorMessage(msg, `Failed to move any members.`); } }, }); diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 191ea1ca..4b50ab1f 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -25,7 +25,6 @@ import { } from "../../utils"; import { asyncFilter } from "../../utils/async"; import { hasDiscordPermissions } from "../../utils/hasDiscordPermissions"; -import { CommonPlugin } from "../Common/CommonPlugin"; import { banSearchSignature } from "./commands/BanSearchCmd"; import { searchCmdSignature } from "./commands/SearchCmd"; import { getUserInfoEmbed } from "./functions/getUserInfoEmbed"; @@ -123,12 +122,12 @@ export async function displaySearch( } } catch (e) { if (e instanceof SearchError) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + void pluginData.state.common.sendErrorMessage(msg, e.message); return; } if (e instanceof InvalidRegexError) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + void pluginData.state.common.sendErrorMessage(msg, e.message); return; } @@ -136,7 +135,7 @@ export async function displaySearch( } if (searchResult.totalResults === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No results found"); + void pluginData.state.common.sendErrorMessage(msg, "No results found"); return; } @@ -267,12 +266,12 @@ export async function archiveSearch( } } catch (e) { if (e instanceof SearchError) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + void pluginData.state.common.sendErrorMessage(msg, e.message); return; } if (e instanceof InvalidRegexError) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, e.message); + void pluginData.state.common.sendErrorMessage(msg, e.message); return; } @@ -280,7 +279,7 @@ export async function archiveSearch( } if (results.totalResults === 0) { - pluginData.getPlugin(CommonPlugin).sendErrorMessage(msg, "No results found"); + void pluginData.state.common.sendErrorMessage(msg, "No results found"); return; } diff --git a/backend/src/plugins/Utility/types.ts b/backend/src/plugins/Utility/types.ts index 77b3d8ac..0bcb56dd 100644 --- a/backend/src/plugins/Utility/types.ts +++ b/backend/src/plugins/Utility/types.ts @@ -1,4 +1,4 @@ -import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand } from "knub"; +import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; import { RegExpRunner } from "../../RegExpRunner"; import { GuildArchives } from "../../data/GuildArchives"; @@ -6,6 +6,7 @@ import { GuildCases } from "../../data/GuildCases"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { Supporters } from "../../data/Supporters"; +import { CommonPlugin } from "../Common/CommonPlugin"; export const zUtilityConfig = z.strictObject({ can_roles: z.boolean(), @@ -48,6 +49,8 @@ export interface UtilityPluginType extends BasePluginType { regexRunner: RegExpRunner; lastReload: number; + + common: pluginUtils.PluginPublicInterface; }; } diff --git a/backend/src/utils/loadYamlSafely.ts b/backend/src/utils/loadYamlSafely.ts index 8cc0d90c..6960a0bf 100644 --- a/backend/src/utils/loadYamlSafely.ts +++ b/backend/src/utils/loadYamlSafely.ts @@ -5,7 +5,7 @@ import { validateNoObjectAliases } from "./validateNoObjectAliases"; * Loads a YAML file safely while removing object anchors/aliases (including arrays) */ export function loadYamlSafely(yamlStr: string): any { - let loaded = yaml.safeLoad(yamlStr); + let loaded = yaml.load(yamlStr); if (loaded == null || typeof loaded !== "object") { loaded = {}; } diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index 59054d72..1486bef3 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -34,13 +34,11 @@ export async function waitForButtonConfirm( .setCustomId(`cancelButton:${idMod}:${uuidv4()}`), ]); const sendMethod = () => { - return contextIsInteraction - ? context.replied - ? context.editReply.bind(context) - : context.reply.bind(context) - : "send" in context - ? context.send.bind(context) - : context.channel.send.bind(context.channel); + if (contextIsInteraction) { + return context.replied ? context.editReply.bind(context) : context.reply.bind(context); + } else { + return "send" in context ? context.send.bind(context) : context.channel.send.bind(context.channel); + } }; const extraParameters = contextIsInteraction ? { fetchReply: true, ephemeral: true } : {}; const message = (await sendMethod()({ ...toPost, components: [row], ...extraParameters })) as Message; From 1f0c7a4349c881a235729b918d1d1098a10a07e6 Mon Sep 17 00:00:00 2001 From: Lily Bergonzat Date: Sun, 12 May 2024 21:34:17 +0200 Subject: [PATCH 29/30] Ran prettier to fix style issues --- .../AutoReactions/AutoReactionsPlugin.ts | 4 +-- .../commands/DisableAutoReactionsCmd.ts | 1 - .../commands/NewAutoReactionsCmd.ts | 6 ++-- backend/src/plugins/Automod/AutomodPlugin.ts | 2 +- backend/src/plugins/Automod/types.ts | 2 +- .../commands/AddDashboardUserCmd.ts | 1 - .../commands/AddServerFromInviteCmd.ts | 1 - .../BotControl/commands/AllowServerCmd.ts | 1 - .../BotControl/commands/ChannelToServerCmd.ts | 1 - .../BotControl/commands/DisallowServerCmd.ts | 1 - .../BotControl/commands/EligibleCmd.ts | 1 - .../BotControl/commands/LeaveServerCmd.ts | 1 - .../commands/ListDashboardPermsCmd.ts | 1 - .../commands/ListDashboardUsersCmd.ts | 1 - .../commands/RateLimitPerformanceCmd.ts | 1 - .../commands/ReloadGlobalPluginsCmd.ts | 1 - .../BotControl/commands/ReloadServerCmd.ts | 1 - .../commands/RemoveDashboardUserCmd.ts | 5 +-- backend/src/plugins/BotControl/types.ts | 2 +- .../ChannelArchiver/ChannelArchiverPlugin.ts | 4 +-- .../commands/ArchiveChannelCmd.ts | 1 - backend/src/plugins/ChannelArchiver/types.ts | 2 +- backend/src/plugins/Common/CommonPlugin.ts | 4 +-- .../src/plugins/ContextMenus/actions/ban.ts | 4 +-- .../src/plugins/ContextMenus/actions/note.ts | 4 +-- .../src/plugins/ContextMenus/actions/warn.ts | 4 +-- .../commands/ModMenuUserCtxCmd.ts | 3 +- .../src/plugins/Counters/CountersPlugin.ts | 2 +- .../Counters/commands/AddCounterCmd.ts | 1 - .../Counters/commands/CountersListCmd.ts | 1 - .../commands/ResetAllCounterValuesCmd.ts | 11 +++++-- .../Counters/commands/ResetCounterCmd.ts | 1 - .../Counters/commands/SetCounterCmd.ts | 1 - .../Counters/commands/ViewCounterCmd.ts | 1 - backend/src/plugins/Counters/types.ts | 2 +- .../CustomEvents/CustomEventsPlugin.ts | 2 +- .../CustomEvents/functions/runEvent.ts | 1 - backend/src/plugins/CustomEvents/types.ts | 2 +- .../plugins/LocateUser/LocateUserPlugin.ts | 2 +- .../plugins/LocateUser/commands/FollowCmd.ts | 19 +++++------- .../LocateUser/commands/ListFollowCmd.ts | 1 - .../plugins/LocateUser/utils/moveMember.ts | 1 - .../src/plugins/LocateUser/utils/sendWhere.ts | 1 - .../MessageSaver/MessageSaverPlugin.ts | 2 +- .../MessageSaver/commands/SaveMessagesToDB.ts | 7 ++--- .../MessageSaver/commands/SavePinsToDB.ts | 7 ++--- .../plugins/ModActions/ModActionsPlugin.ts | 2 +- .../commands/addcase/AddCaseMsgCmd.ts | 2 +- .../commands/addcase/AddCaseSlashCmd.ts | 7 ++--- .../commands/addcase/actualAddCaseCmd.ts | 9 ++---- .../ModActions/commands/ban/BanMsgCmd.ts | 2 +- .../ModActions/commands/ban/BanSlashCmd.ts | 15 ++------- .../ModActions/commands/ban/actualBanCmd.ts | 20 ++++++------ .../ModActions/commands/case/CaseMsgCmd.ts | 2 +- .../ModActions/commands/case/CaseSlashCmd.ts | 2 +- .../commands/cases/CasesModMsgCmd.ts | 2 +- .../commands/cases/CasesSlashCmd.ts | 2 +- .../commands/cases/CasesUserMsgCmd.ts | 2 +- .../commands/cases/actualCasesCmd.ts | 8 +---- .../commands/deletecase/DeleteCaseMsgCmd.ts | 2 +- .../commands/deletecase/DeleteCaseSlashCmd.ts | 2 +- .../deletecase/actualDeleteCaseCmd.ts | 7 ++--- .../commands/forceban/ForceBanMsgCmd.ts | 2 +- .../commands/forceban/ForceBanSlashCmd.ts | 15 ++------- .../commands/forceban/actualForceBanCmd.ts | 7 +++-- .../commands/forcemute/ForceMuteMsgCmd.ts | 2 +- .../commands/forcemute/ForceMuteSlashCmd.ts | 15 ++------- .../commands/forceunmute/ForceUnmuteMsgCmd.ts | 2 +- .../forceunmute/ForceUnmuteSlashCmd.ts | 15 ++------- .../commands/hidecase/HideCaseMsgCmd.ts | 2 +- .../commands/hidecase/HideCaseSlashCmd.ts | 2 +- .../commands/hidecase/actualHideCaseCmd.ts | 6 ++-- .../ModActions/commands/kick/KickMsgCmd.ts | 2 +- .../ModActions/commands/kick/KickSlashCmd.ts | 15 ++------- .../ModActions/commands/kick/actualKickCmd.ts | 11 ++++--- .../commands/massban/MassBanMsgCmd.ts | 2 +- .../commands/massban/MassBanSlashCmd.ts | 10 ++---- .../commands/massban/actualMassBanCmd.ts | 19 ++++++------ .../commands/massmute/MassMuteMsgCmd.ts | 2 +- .../commands/massmute/MassMuteSlashCmd.ts | 10 ++---- .../commands/massmute/actualMassMuteCmd.ts | 18 +++++------ .../commands/massunban/MassUnbanMsgCmd.ts | 2 +- .../commands/massunban/MassUnbanSlashCmd.ts | 10 ++---- .../commands/massunban/actualMassUnbanCmd.ts | 13 +++----- .../ModActions/commands/mute/MuteMsgCmd.ts | 4 +-- .../ModActions/commands/mute/MuteSlashCmd.ts | 14 +++------ .../ModActions/commands/mute/actualMuteCmd.ts | 12 +++---- .../ModActions/commands/note/NoteMsgCmd.ts | 2 +- .../ModActions/commands/note/NoteSlashCmd.ts | 10 ++---- .../ModActions/commands/note/actualNoteCmd.ts | 14 ++++----- .../ModActions/commands/unban/UnbanMsgCmd.ts | 2 +- .../commands/unban/UnbanSlashCmd.ts | 15 ++------- .../commands/unban/actualUnbanCmd.ts | 7 ++--- .../commands/unhidecase/UnhideCaseMsgCmd.ts | 2 +- .../commands/unhidecase/UnhideCaseSlashCmd.ts | 2 +- .../unhidecase/actualUnhideCaseCmd.ts | 2 +- .../commands/unmute/UnmuteMsgCmd.ts | 4 +-- .../commands/unmute/UnmuteSlashCmd.ts | 22 +++---------- .../commands/unmute/actualUnmuteCmd.ts | 2 +- .../ModActions/commands/warn/WarnMsgCmd.ts | 2 +- .../ModActions/commands/warn/WarnSlashCmd.ts | 6 ++-- .../ModActions/commands/warn/actualWarnCmd.ts | 13 +++++--- backend/src/plugins/ModActions/types.ts | 5 +-- backend/src/plugins/Mutes/MutesPlugin.ts | 2 +- .../Mutes/commands/ClearBannedMutesCmd.ts | 1 - .../plugins/Mutes/commands/ClearMutesCmd.ts | 12 ++++--- .../commands/ClearMutesWithoutRoleCmd.ts | 6 ++-- .../plugins/NameHistory/NameHistoryPlugin.ts | 2 +- .../plugins/NameHistory/commands/NamesCmd.ts | 1 - .../PingableRoles/PingableRolesPlugin.ts | 2 +- .../commands/PingableRoleDisableCmd.ts | 11 +++++-- .../commands/PingableRoleEnableCmd.ts | 11 +++++-- backend/src/plugins/Post/PostPlugin.ts | 2 +- backend/src/plugins/Post/commands/EditCmd.ts | 1 - .../src/plugins/Post/commands/EditEmbedCmd.ts | 1 - .../src/plugins/Post/commands/PostEmbedCmd.ts | 1 - .../Post/commands/ScheduledPostsDeleteCmd.ts | 1 - .../Post/commands/ScheduledPostsShowCmd.ts | 1 - .../src/plugins/Post/util/actualPostCmd.ts | 21 ++++++++++--- .../ReactionRoles/ReactionRolesPlugin.ts | 2 +- .../commands/ClearReactionRolesCmd.ts | 1 - .../commands/InitReactionRolesCmd.ts | 16 +++++++--- .../commands/RefreshReactionRolesCmd.ts | 1 - .../src/plugins/Reminders/RemindersPlugin.ts | 2 +- .../plugins/Reminders/commands/RemindCmd.ts | 6 ++-- .../Reminders/commands/RemindersCmd.ts | 1 - .../Reminders/commands/RemindersDeleteCmd.ts | 1 - .../plugins/RoleButtons/RoleButtonsPlugin.ts | 2 +- .../RoleButtons/commands/resetButtons.ts | 1 - backend/src/plugins/RoleButtons/types.ts | 2 +- backend/src/plugins/Roles/RolesPlugin.ts | 2 +- .../src/plugins/Roles/commands/AddRoleCmd.ts | 6 ++-- .../plugins/Roles/commands/MassAddRoleCmd.ts | 6 ++-- .../Roles/commands/MassRemoveRoleCmd.ts | 6 ++-- .../plugins/Roles/commands/RemoveRoleCmd.ts | 11 +++++-- .../SelfGrantableRolesPlugin.ts | 2 +- .../SelfGrantableRoles/commands/RoleAddCmd.ts | 21 ++++++++----- .../commands/RoleRemoveCmd.ts | 31 +++++++++++++------ .../src/plugins/Slowmode/SlowmodePlugin.ts | 2 +- .../Slowmode/commands/SlowmodeClearCmd.ts | 11 +++++-- .../Slowmode/commands/SlowmodeSetCmd.ts | 26 ++++++++++++---- .../Slowmode/util/actualDisableSlowmodeCmd.ts | 6 ++-- .../src/plugins/Starboard/StarboardPlugin.ts | 2 +- .../Starboard/commands/MigratePinsCmd.ts | 6 ++-- backend/src/plugins/Tags/TagsPlugin.ts | 2 +- .../src/plugins/Tags/commands/TagCreateCmd.ts | 1 - .../src/plugins/Tags/commands/TagDeleteCmd.ts | 1 - .../src/plugins/Tags/commands/TagEvalCmd.ts | 1 - .../src/plugins/Tags/commands/TagSourceCmd.ts | 1 - .../plugins/TimeAndDate/TimeAndDatePlugin.ts | 2 +- .../TimeAndDate/commands/ResetTimezoneCmd.ts | 6 ++-- .../TimeAndDate/commands/SetTimezoneCmd.ts | 1 - backend/src/plugins/TimeAndDate/types.ts | 2 +- .../src/plugins/Utility/commands/AvatarCmd.ts | 1 - .../Utility/commands/ChannelInfoCmd.ts | 1 - .../src/plugins/Utility/commands/CleanCmd.ts | 22 ++++++++++--- .../plugins/Utility/commands/ContextCmd.ts | 1 - .../plugins/Utility/commands/EmojiInfoCmd.ts | 1 - .../src/plugins/Utility/commands/InfoCmd.ts | 1 - .../plugins/Utility/commands/InviteInfoCmd.ts | 1 - .../src/plugins/Utility/commands/JumboCmd.ts | 1 - .../Utility/commands/MessageInfoCmd.ts | 1 - .../plugins/Utility/commands/NicknameCmd.ts | 1 - .../Utility/commands/NicknameResetCmd.ts | 1 - .../src/plugins/Utility/commands/RolesCmd.ts | 1 - .../plugins/Utility/commands/ServerInfoCmd.ts | 1 - .../src/plugins/Utility/commands/SourceCmd.ts | 1 - .../plugins/Utility/commands/UserInfoCmd.ts | 1 - .../Utility/commands/VcdisconnectCmd.ts | 3 +- .../src/plugins/Utility/commands/VcmoveCmd.ts | 11 +++++-- 170 files changed, 396 insertions(+), 453 deletions(-) diff --git a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts index df5ebd3a..bd901d49 100644 --- a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts +++ b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts @@ -1,12 +1,12 @@ import { PluginOptions, guildPlugin } from "knub"; import { GuildAutoReactions } from "../../data/GuildAutoReactions"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { DisableAutoReactionsCmd } from "./commands/DisableAutoReactionsCmd"; import { NewAutoReactionsCmd } from "./commands/NewAutoReactionsCmd"; import { AddReactionsEvt } from "./events/AddReactionsEvt"; import { AutoReactionsPluginType, zAutoReactionsConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { @@ -54,5 +54,5 @@ export const AutoReactionsPlugin = guildPlugin()({ beforeStart(pluginData) { pluginData.state.common = pluginData.getPlugin(CommonPlugin); - } + }, }); diff --git a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts index f6539174..9d57a0dd 100644 --- a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { autoReactionsCmd } from "../types"; export const DisableAutoReactionsCmd = autoReactionsCmd({ diff --git a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts index 7f3355fb..420948cc 100644 --- a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts @@ -4,7 +4,6 @@ import { canUseEmoji, customEmojiRegex, isEmoji } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; import { readChannelPermissions } from "../../../utils/readChannelPermissions"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { autoReactionsCmd } from "../types"; const requiredPermissions = readChannelPermissions | PermissionsBitField.Flags.AddReactions; @@ -44,7 +43,10 @@ export const NewAutoReactionsCmd = autoReactionsCmd({ if (customEmojiMatch) { // Custom emoji if (!canUseEmoji(pluginData.client, customEmojiMatch[2])) { - pluginData.state.common.sendErrorMessage(msg, "I can only use regular emojis and custom emojis from this server"); + pluginData.state.common.sendErrorMessage( + msg, + "I can only use regular emojis and custom emojis from this server", + ); return; } diff --git a/backend/src/plugins/Automod/AutomodPlugin.ts b/backend/src/plugins/Automod/AutomodPlugin.ts index 5da233a1..abe0990c 100644 --- a/backend/src/plugins/Automod/AutomodPlugin.ts +++ b/backend/src/plugins/Automod/AutomodPlugin.ts @@ -8,6 +8,7 @@ import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; import { MINUTES, SECONDS } from "../../utils"; import { registerEventListenersFromMap } from "../../utils/registerEventListenersFromMap"; import { unregisterEventListenersFromMap } from "../../utils/unregisterEventListenersFromMap"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { CountersPlugin } from "../Counters/CountersPlugin"; import { InternalPosterPlugin } from "../InternalPoster/InternalPosterPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; @@ -32,7 +33,6 @@ import { clearOldRecentNicknameChanges } from "./functions/clearOldNicknameChang import { clearOldRecentActions } from "./functions/clearOldRecentActions"; import { clearOldRecentSpam } from "./functions/clearOldRecentSpam"; import { AutomodPluginType, zAutomodConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions = { config: { diff --git a/backend/src/plugins/Automod/types.ts b/backend/src/plugins/Automod/types.ts index 75cd8daa..5028a377 100644 --- a/backend/src/plugins/Automod/types.ts +++ b/backend/src/plugins/Automod/types.ts @@ -9,6 +9,7 @@ import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { SavedMessage } from "../../data/entities/SavedMessage"; import { entries, zBoundedRecord, zDelayString } from "../../utils"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { CounterEvents } from "../Counters/types"; import { ModActionType, ModActionsEvents } from "../ModActions/types"; import { MutesEvents } from "../Mutes/types"; @@ -17,7 +18,6 @@ import { RecentActionType } from "./constants"; import { availableTriggers } from "./triggers/availableTriggers"; import Timeout = NodeJS.Timeout; -import { CommonPlugin } from "../Common/CommonPlugin"; export type ZTriggersMapHelper = { [TriggerName in keyof typeof availableTriggers]: (typeof availableTriggers)[TriggerName]["configSchema"]; diff --git a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts index 8e97cf56..abe73595 100644 --- a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts @@ -2,7 +2,6 @@ import { ApiPermissions } from "@zeppelinbot/shared"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter } from "../../../pluginUtils"; import { renderUsername } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const AddDashboardUserCmd = botControlCmd({ diff --git a/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts b/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts index e5245bb3..3dfdaf81 100644 --- a/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts @@ -2,7 +2,6 @@ import { ApiPermissions } from "@zeppelinbot/shared"; import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { DBDateFormat, isGuildInvite, resolveInvite } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { isEligible } from "../functions/isEligible"; import { botControlCmd } from "../types"; diff --git a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts index 9d0a6cea..9580e7e2 100644 --- a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts @@ -3,7 +3,6 @@ import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter } from "../../../pluginUtils"; import { DBDateFormat, isSnowflake } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const AllowServerCmd = botControlCmd({ diff --git a/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts b/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts index f19a41c9..f2a62213 100644 --- a/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts @@ -1,6 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter } from "../../../pluginUtils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const ChannelToServerCmd = botControlCmd({ diff --git a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts index 8a31ddf5..43033341 100644 --- a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts @@ -2,7 +2,6 @@ import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter } from "../../../pluginUtils"; import { noop } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const DisallowServerCmd = botControlCmd({ diff --git a/backend/src/plugins/BotControl/commands/EligibleCmd.ts b/backend/src/plugins/BotControl/commands/EligibleCmd.ts index 60adcea2..f934037f 100644 --- a/backend/src/plugins/BotControl/commands/EligibleCmd.ts +++ b/backend/src/plugins/BotControl/commands/EligibleCmd.ts @@ -1,6 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isGuildInvite, resolveInvite } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { isEligible } from "../functions/isEligible"; import { botControlCmd } from "../types"; diff --git a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts index c22a885f..652c049d 100644 --- a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts @@ -1,7 +1,6 @@ import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter } from "../../../pluginUtils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const LeaveServerCmd = botControlCmd({ diff --git a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts index 83f0cc37..ea237ef2 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts @@ -2,7 +2,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { AllowedGuild } from "../../../data/entities/AllowedGuild"; import { ApiPermissionAssignment } from "../../../data/entities/ApiPermissionAssignment"; import { renderUsername, resolveUser } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const ListDashboardPermsCmd = botControlCmd({ diff --git a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts index 2892e6e6..34c98dd2 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts @@ -1,6 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { renderUsername, resolveUser } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const ListDashboardUsersCmd = botControlCmd({ diff --git a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts index 9ba9d23c..6114c681 100644 --- a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts +++ b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts @@ -2,7 +2,6 @@ import moment from "moment-timezone"; import { GuildArchives } from "../../../data/GuildArchives"; import { getBaseUrl } from "../../../pluginUtils"; import { getRateLimitStats } from "../../../rateLimitStats"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const RateLimitPerformanceCmd = botControlCmd({ diff --git a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts index 957fca95..dc13a45e 100644 --- a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts @@ -1,5 +1,4 @@ import { isStaffPreFilter } from "../../../pluginUtils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { getActiveReload, setActiveReload } from "../activeReload"; import { botControlCmd } from "../types"; diff --git a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts index a171af5f..0ea4f59d 100644 --- a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts @@ -1,7 +1,6 @@ import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter } from "../../../pluginUtils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const ReloadServerCmd = botControlCmd({ diff --git a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts index 502570a7..4c0ed1d8 100644 --- a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts @@ -1,7 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isStaffPreFilter } from "../../../pluginUtils"; import { renderUsername } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { botControlCmd } from "../types"; export const RemoveDashboardUserCmd = botControlCmd({ @@ -37,8 +36,6 @@ export const RemoveDashboardUserCmd = botControlCmd({ const userNameList = args.users.map((user) => `<@!${user.id}> (**${renderUsername(user)}**, \`${user.id}\`)`); - msg.channel.send( - `The following users were removed from the dashboard for **${guild.name}**:\n\n${userNameList}`, - ); + msg.channel.send(`The following users were removed from the dashboard for **${guild.name}**:\n\n${userNameList}`); }, }); diff --git a/backend/src/plugins/BotControl/types.ts b/backend/src/plugins/BotControl/types.ts index 592189c1..1c1ccea6 100644 --- a/backend/src/plugins/BotControl/types.ts +++ b/backend/src/plugins/BotControl/types.ts @@ -1,4 +1,4 @@ -import { BasePluginType, globalPluginEventListener, globalPluginMessageCommand, pluginUtils } from "knub"; +import { BasePluginType, globalPluginEventListener, globalPluginMessageCommand } from "knub"; import z from "zod"; import { AllowedGuilds } from "../../data/AllowedGuilds"; import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; diff --git a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts index b9c310d7..79937321 100644 --- a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts +++ b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts @@ -1,9 +1,9 @@ import { guildPlugin } from "knub"; import z from "zod"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { ArchiveChannelCmd } from "./commands/ArchiveChannelCmd"; import { ChannelArchiverPluginType } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; export const ChannelArchiverPlugin = guildPlugin()({ name: "channel_archiver", @@ -18,5 +18,5 @@ export const ChannelArchiverPlugin = guildPlugin()({ beforeStart(pluginData) { pluginData.state.common = pluginData.getPlugin(CommonPlugin); - } + }, }); diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index 34bdeef7..5e0235a4 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -3,7 +3,6 @@ import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isOwner } from "../../../pluginUtils"; import { SECONDS, confirm, noop, renderUsername } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { rehostAttachment } from "../rehostAttachment"; import { channelArchiverCmd } from "../types"; diff --git a/backend/src/plugins/ChannelArchiver/types.ts b/backend/src/plugins/ChannelArchiver/types.ts index a560af39..5dffc8d7 100644 --- a/backend/src/plugins/ChannelArchiver/types.ts +++ b/backend/src/plugins/ChannelArchiver/types.ts @@ -4,7 +4,7 @@ import { CommonPlugin } from "../Common/CommonPlugin"; export interface ChannelArchiverPluginType extends BasePluginType { state: { common: pluginUtils.PluginPublicInterface; - } + }; } export const channelArchiverCmd = guildPluginMessageCommand(); diff --git a/backend/src/plugins/Common/CommonPlugin.ts b/backend/src/plugins/Common/CommonPlugin.ts index 144c355c..6482272e 100644 --- a/backend/src/plugins/Common/CommonPlugin.ts +++ b/backend/src/plugins/Common/CommonPlugin.ts @@ -139,7 +139,7 @@ export const CommonPlugin = guildPlugin()({ if (!channel) { throw new Error( - 'Cannot store attachments: no attachment storing channel configured, and no backup channel passed' + "Cannot store attachments: no attachment storing channel configured, and no backup channel passed", ); } @@ -148,6 +148,6 @@ export const CommonPlugin = guildPlugin()({ files: attachments.map((a) => a.url), }); }, - } + }; }, }); diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts index 9f7114c6..ab5951b5 100644 --- a/backend/src/plugins/ContextMenus/actions/ban.ts +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -9,11 +9,11 @@ import { } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { canActOn } from "../../../pluginUtils"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { logger } from "../../../logger"; +import { canActOn } from "../../../pluginUtils"; import { convertDelayStringToMS, renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; import { ContextMenuPluginType, ModMenuActionType } from "../types"; import { updateAction } from "./update"; diff --git a/backend/src/plugins/ContextMenus/actions/note.ts b/backend/src/plugins/ContextMenus/actions/note.ts index bbdc6a8e..1065639d 100644 --- a/backend/src/plugins/ContextMenus/actions/note.ts +++ b/backend/src/plugins/ContextMenus/actions/note.ts @@ -8,13 +8,13 @@ import { TextInputStyle, } from "discord.js"; import { GuildPluginData } from "knub"; -import { canActOn } from "../../../pluginUtils"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { CaseTypes } from "../../../data/CaseTypes"; import { logger } from "../../../logger"; +import { canActOn } from "../../../pluginUtils"; import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; import { renderUserUsername } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; import { ContextMenuPluginType, ModMenuActionType } from "../types"; diff --git a/backend/src/plugins/ContextMenus/actions/warn.ts b/backend/src/plugins/ContextMenus/actions/warn.ts index 1e93f42d..94c094ef 100644 --- a/backend/src/plugins/ContextMenus/actions/warn.ts +++ b/backend/src/plugins/ContextMenus/actions/warn.ts @@ -8,11 +8,11 @@ import { TextInputStyle, } from "discord.js"; import { GuildPluginData } from "knub"; -import { canActOn } from "../../../pluginUtils"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { logger } from "../../../logger"; +import { canActOn } from "../../../pluginUtils"; import { renderUserUsername } from "../../../utils"; import { CaseArgs } from "../../Cases/types"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; import { ContextMenuPluginType, ModMenuActionType } from "../types"; import { updateAction } from "./update"; diff --git a/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts index fd538997..dab9f87d 100644 --- a/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts @@ -12,13 +12,12 @@ import { import { GuildPluginData, guildPluginUserContextMenuCommand } from "knub"; import { Case } from "../../../data/entities/Case"; import { logger } from "../../../logger"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { SECONDS, UnknownUser, emptyEmbedValue, renderUserUsername, resolveUser, trimLines } from "../../../utils"; import { asyncMap } from "../../../utils/async"; import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { UtilityPlugin } from "../../Utility/UtilityPlugin"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { getUserInfoEmbed } from "../../Utility/functions/getUserInfoEmbed"; import { launchBanActionModal } from "../actions/ban"; import { launchMuteActionModal } from "../actions/mute"; diff --git a/backend/src/plugins/Counters/CountersPlugin.ts b/backend/src/plugins/Counters/CountersPlugin.ts index dd226865..edee10be 100644 --- a/backend/src/plugins/Counters/CountersPlugin.ts +++ b/backend/src/plugins/Counters/CountersPlugin.ts @@ -4,6 +4,7 @@ import { GuildCounters } from "../../data/GuildCounters"; import { CounterTrigger, parseCounterConditionString } from "../../data/entities/CounterTrigger"; import { makePublicFn } from "../../pluginUtils"; import { MINUTES, convertDelayStringToMS, values } from "../../utils"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { AddCounterCmd } from "./commands/AddCounterCmd"; import { CountersListCmd } from "./commands/CountersListCmd"; import { ResetAllCounterValuesCmd } from "./commands/ResetAllCounterValuesCmd"; @@ -19,7 +20,6 @@ import { offCounterEvent } from "./functions/offCounterEvent"; import { onCounterEvent } from "./functions/onCounterEvent"; import { setCounterValue } from "./functions/setCounterValue"; import { CountersPluginType, zCountersConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const DECAY_APPLY_INTERVAL = 5 * MINUTES; diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index 558c23de..9df3ea34 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -3,7 +3,6 @@ import { guildPluginMessageCommand } from "knub"; import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { UnknownUser, resolveUser } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { changeCounterValue } from "../functions/changeCounterValue"; import { CountersPluginType } from "../types"; diff --git a/backend/src/plugins/Counters/commands/CountersListCmd.ts b/backend/src/plugins/Counters/commands/CountersListCmd.ts index fc79b62c..70ecb810 100644 --- a/backend/src/plugins/Counters/commands/CountersListCmd.ts +++ b/backend/src/plugins/Counters/commands/CountersListCmd.ts @@ -1,7 +1,6 @@ import { guildPluginMessageCommand } from "knub"; import { trimMultilineString, ucfirst } from "../../../utils"; import { getGuildPrefix } from "../../../utils/getGuildPrefix"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { CountersPluginType } from "../types"; export const CountersListCmd = guildPluginMessageCommand()({ diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index 5f7aa5d4..45b46006 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -1,7 +1,6 @@ import { guildPluginMessageCommand } from "knub"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { confirm, noop, trimMultilineString } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { resetAllCounterValues } from "../functions/resetAllCounterValues"; import { CountersPluginType } from "../types"; @@ -23,7 +22,10 @@ export const ResetAllCounterValuesCmd = guildPluginMessageCommand()({ diff --git a/backend/src/plugins/Counters/types.ts b/backend/src/plugins/Counters/types.ts index c75046eb..a323abf4 100644 --- a/backend/src/plugins/Counters/types.ts +++ b/backend/src/plugins/Counters/types.ts @@ -9,8 +9,8 @@ import { parseCounterConditionString, } from "../../data/entities/CounterTrigger"; import { zBoundedCharacters, zBoundedRecord, zDelayString } from "../../utils"; -import Timeout = NodeJS.Timeout; import { CommonPlugin } from "../Common/CommonPlugin"; +import Timeout = NodeJS.Timeout; const MAX_COUNTERS = 5; const MAX_TRIGGERS_PER_COUNTER = 5; diff --git a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts index cdb9aae7..41d8c1f2 100644 --- a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts +++ b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts @@ -11,10 +11,10 @@ import { messageToTemplateSafeMessage, userToTemplateSafeUser, } from "../../utils/templateSafeObjects"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { runEvent } from "./functions/runEvent"; import { CustomEventsPluginType, zCustomEventsConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions = { config: { diff --git a/backend/src/plugins/CustomEvents/functions/runEvent.ts b/backend/src/plugins/CustomEvents/functions/runEvent.ts index 3f75b894..a2bf0d57 100644 --- a/backend/src/plugins/CustomEvents/functions/runEvent.ts +++ b/backend/src/plugins/CustomEvents/functions/runEvent.ts @@ -1,7 +1,6 @@ import { Message } from "discord.js"; import { GuildPluginData } from "knub"; import { TemplateSafeValueContainer } from "../../../templateFormatter"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { ActionError } from "../ActionError"; import { addRoleAction } from "../actions/addRoleAction"; import { createCaseAction } from "../actions/createCaseAction"; diff --git a/backend/src/plugins/CustomEvents/types.ts b/backend/src/plugins/CustomEvents/types.ts index 0372fd16..df325b98 100644 --- a/backend/src/plugins/CustomEvents/types.ts +++ b/backend/src/plugins/CustomEvents/types.ts @@ -1,6 +1,7 @@ import { BasePluginType, pluginUtils } from "knub"; import z from "zod"; import { zBoundedCharacters, zBoundedRecord } from "../../utils"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { zAddRoleAction } from "./actions/addRoleAction"; import { zCreateCaseAction } from "./actions/createCaseAction"; import { zMakeRoleMentionableAction } from "./actions/makeRoleMentionableAction"; @@ -8,7 +9,6 @@ import { zMakeRoleUnmentionableAction } from "./actions/makeRoleUnmentionableAct import { zMessageAction } from "./actions/messageAction"; import { zMoveToVoiceChannelAction } from "./actions/moveToVoiceChannelAction"; import { zSetChannelPermissionOverridesAction } from "./actions/setChannelPermissionOverrides"; -import { CommonPlugin } from "../Common/CommonPlugin"; const zCommandTrigger = z.strictObject({ type: z.literal("command"), diff --git a/backend/src/plugins/LocateUser/LocateUserPlugin.ts b/backend/src/plugins/LocateUser/LocateUserPlugin.ts index 39057b00..0730919c 100644 --- a/backend/src/plugins/LocateUser/LocateUserPlugin.ts +++ b/backend/src/plugins/LocateUser/LocateUserPlugin.ts @@ -1,6 +1,7 @@ import { PluginOptions, guildPlugin } from "knub"; import { onGuildEvent } from "../../data/GuildEvents"; import { GuildVCAlerts } from "../../data/GuildVCAlerts"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { FollowCmd } from "./commands/FollowCmd"; import { DeleteFollowCmd, ListFollowCmd } from "./commands/ListFollowCmd"; import { WhereCmd } from "./commands/WhereCmd"; @@ -9,7 +10,6 @@ import { VoiceStateUpdateAlertEvt } from "./events/SendAlertsEvts"; import { LocateUserPluginType, zLocateUserConfig } from "./types"; import { clearExpiredAlert } from "./utils/clearExpiredAlert"; import { fillActiveAlertsList } from "./utils/fillAlertsList"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/LocateUser/commands/FollowCmd.ts b/backend/src/plugins/LocateUser/commands/FollowCmd.ts index 921ec47f..f0debc59 100644 --- a/backend/src/plugins/LocateUser/commands/FollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/FollowCmd.ts @@ -3,7 +3,6 @@ import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { registerExpiringVCAlert } from "../../../data/loops/expiringVCAlertsLoop"; import { MINUTES, SECONDS } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { locateUserCmd } from "../types"; export const FollowCmd = locateUserCmd({ @@ -47,18 +46,16 @@ export const FollowCmd = locateUserCmd({ if (active) { void pluginData.state.common.sendSuccessMessage( - msg, - `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration( - time, - )} i will notify and move you.\nPlease make sure to be in a voice channel, otherwise i cannot move you!`, - ); + msg, + `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration( + time, + )} i will notify and move you.\nPlease make sure to be in a voice channel, otherwise i cannot move you!`, + ); } else { void pluginData.state.common.sendSuccessMessage( - msg, - `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration( - time, - )} i will notify you`, - ); + msg, + `Every time <@${args.member.id}> joins or switches VC in the next ${humanizeDuration(time)} i will notify you`, + ); } }, }); diff --git a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts index c993c5c7..bbe30513 100644 --- a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts @@ -1,7 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { clearExpiringVCAlert } from "../../../data/loops/expiringVCAlertsLoop"; import { createChunkedMessage, sorter } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { locateUserCmd } from "../types"; export const ListFollowCmd = locateUserCmd({ diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts index f562fe30..6438bde1 100644 --- a/backend/src/plugins/LocateUser/utils/moveMember.ts +++ b/backend/src/plugins/LocateUser/utils/moveMember.ts @@ -1,6 +1,5 @@ import { GuildMember, GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { LocateUserPluginType } from "../types"; export async function moveMember( diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts index 78172509..6ce4181f 100644 --- a/backend/src/plugins/LocateUser/utils/sendWhere.ts +++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts @@ -1,7 +1,6 @@ import { GuildMember, GuildTextBasedChannel, Invite, VoiceChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { getInviteLink } from "knub/helpers"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { LocateUserPluginType } from "../types"; import { createOrReuseInvite } from "./createOrReuseInvite"; diff --git a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts index 9d62c2c7..9ea040bf 100644 --- a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts +++ b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts @@ -1,10 +1,10 @@ import { PluginOptions, guildPlugin } from "knub"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { SaveMessagesToDBCmd } from "./commands/SaveMessagesToDB"; import { SavePinsToDBCmd } from "./commands/SavePinsToDB"; import { MessageCreateEvt, MessageDeleteBulkEvt, MessageDeleteEvt, MessageUpdateEvt } from "./events/SaveMessagesEvts"; import { MessageSaverPluginType, zMessageSaverConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts index a34b103e..6097bf14 100644 --- a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { saveMessagesToDB } from "../saveMessagesToDB"; import { messageSaverCmd } from "../types"; @@ -19,9 +18,9 @@ export const SaveMessagesToDBCmd = messageSaverCmd({ if (failed.length) { void pluginData.state.common.sendSuccessMessage( - msg, - `Saved ${savedCount} messages. The following messages could not be saved: ${failed.join(", ")}`, - ); + msg, + `Saved ${savedCount} messages. The following messages could not be saved: ${failed.join(", ")}`, + ); } else { void pluginData.state.common.sendSuccessMessage(msg, `Saved ${savedCount} messages!`); } diff --git a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts index d2910525..29bc2cbb 100644 --- a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { saveMessagesToDB } from "../saveMessagesToDB"; import { messageSaverCmd } from "../types"; @@ -20,9 +19,9 @@ export const SavePinsToDBCmd = messageSaverCmd({ if (failed.length) { void pluginData.state.common.sendSuccessMessage( - msg, - `Saved ${savedCount} messages. The following messages could not be saved: ${failed.join(", ")}`, - ); + msg, + `Saved ${savedCount} messages. The following messages could not be saved: ${failed.join(", ")}`, + ); } else { void pluginData.state.common.sendSuccessMessage(msg, `Saved ${savedCount} messages!`); } diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index bd6aa0c7..a501fbc9 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -10,6 +10,7 @@ import { GuildTempbans } from "../../data/GuildTempbans"; import { makePublicFn, mapToPublicFn } from "../../pluginUtils"; import { MINUTES } from "../../utils"; import { CasesPlugin } from "../Cases/CasesPlugin"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { MutesPlugin } from "../Mutes/MutesPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; @@ -72,7 +73,6 @@ import { onModActionsEvent } from "./functions/onModActionsEvent"; import { updateCase } from "./functions/updateCase"; import { warnMember } from "./functions/warnMember"; import { AttachmentLinkReactionType, ModActionsPluginType, modActionsSlashGroup, zModActionsConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions = { config: { diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts index 9f1b819b..bd9d85bf 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts @@ -2,8 +2,8 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { CaseTypes } from "../../../../data/CaseTypes"; import { hasPermission } from "../../../../pluginUtils"; import { resolveUser } from "../../../../utils"; -import { actualAddCaseCmd } from "./actualAddCaseCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualAddCaseCmd } from "./actualAddCaseCmd"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts index 828ec742..23bb34a9 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts @@ -4,9 +4,9 @@ import { CaseTypes } from "../../../../data/CaseTypes"; import { hasPermission } from "../../../../pluginUtils"; import { resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { actualAddCaseCmd } from "./actualAddCaseCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualAddCaseCmd } from "./actualAddCaseCmd"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), @@ -48,10 +48,7 @@ export const AddCaseSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData.state.common.sendErrorMessage( - interaction, - "You don't have permission to act as another moderator" - ); + pluginData.state.common.sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts b/backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts index 2c67dc2f..ef676083 100644 --- a/backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts @@ -6,9 +6,9 @@ import { canActOn } from "../../../../pluginUtils"; import { UnknownUser, renderUsername, resolveMember } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { ModActionsPluginType } from "../../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ModActionsPluginType } from "../../types"; export async function actualAddCaseCmd( pluginData: GuildPluginData, @@ -27,10 +27,7 @@ export async function actualAddCaseCmd( // If the user exists as a guild member, make sure we can act on them first const member = await resolveMember(pluginData.client, pluginData.guild, user.id); if (member && !canActOn(pluginData, author, member)) { - pluginData.state.common.sendErrorMessage( - context, - "Cannot add case on this user: insufficient permissions" - ); + pluginData.state.common.sendErrorMessage(context, "Cannot add case on this user: insufficient permissions"); return; } @@ -49,7 +46,7 @@ export async function actualAddCaseCmd( if (user) { pluginData.state.common.sendSuccessMessage( context, - `Case #${theCase.case_number} created for **${renderUsername(user)}**` + `Case #${theCase.case_number} created for **${renderUsername(user)}**`, ); } else { pluginData.state.common.sendSuccessMessage(context, `Case #${theCase.case_number} created`); diff --git a/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts index 35b9f737..b218c2e0 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts @@ -1,9 +1,9 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, resolveUser } from "../../../../utils"; -import { actualBanCmd } from "./actualBanCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; +import { actualBanCmd } from "./actualBanCmd"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts index 16bda55b..12ea3f11 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts @@ -3,10 +3,10 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { actualBanCmd } from "./actualBanCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualBanCmd } from "./actualBanCmd"; const opts = [ slashOptions.string({ name: "time", description: "The duration of the ban", required: false }), @@ -51,13 +51,7 @@ export const BanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData.state.common.sendErrorMessage( - interaction, - "Text or attachment required", - undefined, - undefined, - true - ); + pluginData.state.common.sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -70,10 +64,7 @@ export const BanSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData.state.common.sendErrorMessage( - interaction, - "You don't have permission to act as another moderator" - ); + pluginData.state.common.sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts b/backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts index 0b442239..95706e6f 100644 --- a/backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts @@ -10,11 +10,14 @@ import { banLock } from "../../../../utils/lockNameHelpers"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { ModActionsPluginType } from "../../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; import { banUserId } from "../../functions/banUserId"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { + formatReasonWithAttachments, + formatReasonWithMessageLinkForAttachments, +} from "../../functions/formatReasonForAttachments"; import { isBanned } from "../../functions/isBanned"; +import { ModActionsPluginType } from "../../types"; export async function actualBanCmd( pluginData: GuildPluginData, @@ -74,10 +77,7 @@ export async function actualBanCmd( ); if (!reply) { - pluginData.state.common.sendErrorMessage( - context, - "User already banned, update cancelled by moderator" - ); + pluginData.state.common.sendErrorMessage(context, "User already banned, update cancelled by moderator"); lock.unlock(); return; } @@ -123,9 +123,9 @@ export async function actualBanCmd( } pluginData.state.common.sendSuccessMessage( - context, - `Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`, - ); + context, + `Ban updated to ${time ? "expire in " + humanizeDuration(time) + " from now" : "indefinite"}`, + ); lock.unlock(); return; } @@ -138,7 +138,7 @@ export async function actualBanCmd( pluginData.state.common.sendErrorMessage( context, `Cannot ban: target permission level is equal or higher to yours, ${targetLevel} >= ${ourLevel}`, - ); + ); lock.unlock(); return; } diff --git a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts index 6c727e45..c2e8d8b5 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualCaseCmd } from "./actualCaseCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualCaseCmd } from "./actualCaseCmd"; const opts = { show: ct.switchOption({ def: false, shortcut: "sh" }), diff --git a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts index b86bfb01..220a9697 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts @@ -1,6 +1,6 @@ import { slashOptions } from "knub"; -import { actualCaseCmd } from "./actualCaseCmd"; import { modActionsSlashCmd } from "../../types"; +import { actualCaseCmd } from "./actualCaseCmd"; const opts = [ slashOptions.boolean({ name: "show", description: "To make the result visible to everyone", required: false }), diff --git a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts index d5f5f7fe..e55f1661 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualCasesCmd } from "./actualCasesCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualCasesCmd } from "./actualCasesCmd"; const opts = { mod: ct.userId({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts index fe932311..accb2050 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts @@ -1,7 +1,7 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { actualCasesCmd } from "./actualCasesCmd"; import { modActionsSlashCmd } from "../../types"; +import { actualCasesCmd } from "./actualCasesCmd"; const opts = [ slashOptions.user({ name: "user", description: "The user to show cases for", required: false }), diff --git a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts index b36b39c7..7d425f2c 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts @@ -1,7 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { resolveMember, resolveUser, UnknownUser } from "../../../../utils"; -import { actualCasesCmd } from "./actualCasesCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualCasesCmd } from "./actualCasesCmd"; const opts = { mod: ct.userId({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts b/backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts index 5973bcdb..3e72303d 100644 --- a/backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts @@ -159,13 +159,7 @@ async function casesModCmd( const totalCases = await casesPlugin.getTotalCasesByMod(modId ?? author.id, casesFilters); if (totalCases === 0) { - pluginData.state.common.sendErrorMessage( - context, - `No cases by **${modName}**`, - undefined, - undefined, - !show - ); + pluginData.state.common.sendErrorMessage(context, `No cases by **${modName}**`, undefined, undefined, !show); return; } diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts index dad54847..396bd73f 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts @@ -1,7 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { trimLines } from "../../../../utils"; -import { actualDeleteCaseCmd } from "./actualDeleteCaseCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualDeleteCaseCmd } from "./actualDeleteCaseCmd"; export const DeleteCaseMsgCmd = modActionsMsgCmd({ trigger: ["delete_case", "deletecase"], diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts index c9038c74..932f4cad 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts @@ -1,7 +1,7 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { actualDeleteCaseCmd } from "./actualDeleteCaseCmd"; import { modActionsSlashCmd } from "../../types"; +import { actualDeleteCaseCmd } from "./actualDeleteCaseCmd"; const opts = [slashOptions.boolean({ name: "force", description: "Whether or not to force delete", required: false })]; diff --git a/backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts index 707332e4..64c146ee 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts @@ -82,15 +82,12 @@ export async function actualDeleteCaseCmd( : ""; const amt = validCases.length - cancelled; if (amt === 0) { - pluginData.state.common.sendErrorMessage( - context, - "All deletions were cancelled, no cases were deleted." - ); + pluginData.state.common.sendErrorMessage(context, "All deletions were cancelled, no cases were deleted."); return; } pluginData.state.common.sendSuccessMessage( context, - `${amt} case${amt === 1 ? " was" : "s were"} deleted!${failedAddendum}` + `${amt} case${amt === 1 ? " was" : "s were"} deleted!${failedAddendum}`, ); } diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts index 5224e905..3546ee14 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts @@ -1,9 +1,9 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; -import { actualForceBanCmd } from "./actualForceBanCmd"; import { isBanned } from "../../functions/isBanned"; import { modActionsMsgCmd } from "../../types"; +import { actualForceBanCmd } from "./actualForceBanCmd"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts index 8389233b..14e27561 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts @@ -3,9 +3,9 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { actualForceBanCmd } from "./actualForceBanCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualForceBanCmd } from "./actualForceBanCmd"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), @@ -29,13 +29,7 @@ export const ForceBanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData.state.common.sendErrorMessage( - interaction, - "Text or attachment required", - undefined, - undefined, - true - ); + pluginData.state.common.sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -48,10 +42,7 @@ export const ForceBanSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData.state.common.sendErrorMessage( - interaction, - "You don't have permission to act as another moderator" - ); + pluginData.state.common.sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts b/backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts index 448f4134..6b84901c 100644 --- a/backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts @@ -5,10 +5,13 @@ import { LogType } from "../../../../data/LogType"; import { DAYS, MINUTES, UnknownUser } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { IgnoredEventType, ModActionsPluginType } from "../../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { + formatReasonWithAttachments, + formatReasonWithMessageLinkForAttachments, +} from "../../functions/formatReasonForAttachments"; import { ignoreEvent } from "../../functions/ignoreEvent"; +import { IgnoredEventType, ModActionsPluginType } from "../../types"; export async function actualForceBanCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts index 833fb181..384b34e8 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts @@ -1,9 +1,9 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; -import { actualMuteCmd } from "../mute/actualMuteCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; +import { actualMuteCmd } from "../mute/actualMuteCmd"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts index ba262835..05505bab 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts @@ -3,10 +3,10 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { actualMuteCmd } from "../mute/actualMuteCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualMuteCmd } from "../mute/actualMuteCmd"; const opts = [ slashOptions.string({ name: "time", description: "The duration of the mute", required: false }), @@ -46,13 +46,7 @@ export const ForceMuteSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData.state.common.sendErrorMessage( - interaction, - "Text or attachment required", - undefined, - undefined, - true - ); + pluginData.state.common.sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -66,10 +60,7 @@ export const ForceMuteSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData.state.common.sendErrorMessage( - interaction, - "You don't have permission to act as another moderator" - ); + pluginData.state.common.sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts index 396052fd..439bc877 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts @@ -1,8 +1,8 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; -import { actualUnmuteCmd } from "../unmute/actualUnmuteCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualUnmuteCmd } from "../unmute/actualUnmuteCmd"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts index bb03ee89..1ddd4962 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts @@ -3,9 +3,9 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { actualUnmuteCmd } from "../unmute/actualUnmuteCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualUnmuteCmd } from "../unmute/actualUnmuteCmd"; const opts = [ slashOptions.string({ name: "time", description: "The duration of the unmute", required: false }), @@ -30,13 +30,7 @@ export const ForceUnmuteSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData.state.common.sendErrorMessage( - interaction, - "Text or attachment required", - undefined, - undefined, - true - ); + pluginData.state.common.sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -50,10 +44,7 @@ export const ForceUnmuteSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData.state.common.sendErrorMessage( - interaction, - "You don't have permission to act as another moderator" - ); + pluginData.state.common.sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts index c04bf9a1..8b427275 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualHideCaseCmd } from "./actualHideCaseCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualHideCaseCmd } from "./actualHideCaseCmd"; export const HideCaseMsgCmd = modActionsMsgCmd({ trigger: ["hide", "hidecase", "hide_case"], diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts index b6261d73..0485c5de 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts @@ -1,6 +1,6 @@ import { slashOptions } from "knub"; -import { actualHideCaseCmd } from "./actualHideCaseCmd"; import { modActionsSlashCmd } from "../../types"; +import { actualHideCaseCmd } from "./actualHideCaseCmd"; export const HideCaseSlashCmd = modActionsSlashCmd({ name: "hidecase", diff --git a/backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts index 49bee81b..d38e099c 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts @@ -30,7 +30,7 @@ export async function actualHideCaseCmd( const amt = caseNumbers.length - failed.length; pluginData.state.common.sendSuccessMessage( - context, - `${amt} case${amt === 1 ? " is" : "s are"} now hidden! Use \`unhidecase\` to unhide them.${failedAddendum}`, - ); + context, + `${amt} case${amt === 1 ? " is" : "s are"} now hidden! Use \`unhidecase\` to unhide them.${failedAddendum}`, + ); } diff --git a/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts index c494a7c7..d895bba4 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts @@ -1,9 +1,9 @@ import { hasPermission } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { resolveUser } from "../../../../utils"; -import { actualKickCmd } from "./actualKickCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; +import { actualKickCmd } from "./actualKickCmd"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts index 5bd94f30..4f9bf392 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts @@ -3,10 +3,10 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { actualKickCmd } from "./actualKickCmd"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualKickCmd } from "./actualKickCmd"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), @@ -50,13 +50,7 @@ export const KickSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData.state.common.sendErrorMessage( - interaction, - "Text or attachment required", - undefined, - undefined, - true - ); + pluginData.state.common.sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -69,10 +63,7 @@ export const KickSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData.state.common.sendErrorMessage( - interaction, - "You don't have permission to act as another moderator" - ); + pluginData.state.common.sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts b/backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts index 4a6b22a4..3ee204cc 100644 --- a/backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts @@ -3,12 +3,15 @@ import { GuildPluginData } from "knub"; import { LogType } from "../../../../data/LogType"; import { canActOn } from "../../../../pluginUtils"; import { DAYS, SECONDS, UnknownUser, UserNotificationMethod, renderUsername, resolveMember } from "../../../../utils"; -import { IgnoredEventType, ModActionsPluginType } from "../../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { + formatReasonWithAttachments, + formatReasonWithMessageLinkForAttachments, +} from "../../functions/formatReasonForAttachments"; import { ignoreEvent } from "../../functions/ignoreEvent"; import { isBanned } from "../../functions/isBanned"; import { kickMember } from "../../functions/kickMember"; +import { IgnoredEventType, ModActionsPluginType } from "../../types"; export async function actualKickCmd( pluginData: GuildPluginData, @@ -71,9 +74,7 @@ export async function actualKickCmd( try { await pluginData.guild.bans.remove(memberToKick.id, "kick -clean"); } catch { - pluginData.state.common.sendErrorMessage( - context, - "Failed to unban the user after banning them (-clean)"); + pluginData.state.common.sendErrorMessage(context, "Failed to unban the user after banning them (-clean)"); } } diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts index d47c61d5..3267bf28 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts @@ -1,8 +1,8 @@ import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { actualMassBanCmd } from "./actualMassBanCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualMassBanCmd } from "./actualMassBanCmd"; export const MassBanMsgCmd = modActionsMsgCmd({ trigger: "massban", diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts index a358893e..805a3d63 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts @@ -1,9 +1,9 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { actualMassBanCmd } from "./actualMassBanCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualMassBanCmd } from "./actualMassBanCmd"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), @@ -30,13 +30,7 @@ export const MassBanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData.state.common.sendErrorMessage( - interaction, - "Text or attachment required", - undefined, - undefined, - true - ); + pluginData.state.common.sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } diff --git a/backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts b/backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts index 207194df..27706105 100644 --- a/backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts @@ -7,10 +7,13 @@ import { canActOn, getContextChannel, isContextInteraction, sendContextResponse import { DAYS, MINUTES, SECONDS, noop } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { IgnoredEventType, ModActionsPluginType } from "../../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { + formatReasonWithAttachments, + formatReasonWithMessageLinkForAttachments, +} from "../../functions/formatReasonForAttachments"; import { ignoreEvent } from "../../functions/ignoreEvent"; +import { IgnoredEventType, ModActionsPluginType } from "../../types"; export async function actualMassBanCmd( pluginData: GuildPluginData, @@ -37,9 +40,7 @@ export async function actualMassBanCmd( for (const userId of userIds) { const member = pluginData.guild.members.cache.get(userId as Snowflake); // TODO: Get members on demand? if (member && !canActOn(pluginData, author, member)) { - pluginData.state.common.sendErrorMessage( - context, - "Cannot massban one or more users: insufficient permissions"); + pluginData.state.common.sendErrorMessage(context, "Cannot massban one or more users: insufficient permissions"); return; } } @@ -157,14 +158,14 @@ export async function actualMassBanCmd( if (failedBans.length) { pluginData.state.common.sendSuccessMessage( context, - `Banned ${successfulBanCount} users in ${formattedTimeTaken}, ${ - failedBans.length - } failed: ${failedBans.join(" ")}`, + `Banned ${successfulBanCount} users in ${formattedTimeTaken}, ${failedBans.length} failed: ${failedBans.join( + " ", + )}`, ); } else { pluginData.state.common.sendSuccessMessage( context, - `Banned ${successfulBanCount} users successfully in ${formattedTimeTaken}` + `Banned ${successfulBanCount} users successfully in ${formattedTimeTaken}`, ); } } diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts index bbcfd715..0ff53ab1 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts @@ -1,8 +1,8 @@ import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { actualMassMuteCmd } from "./actualMassMuteCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualMassMuteCmd } from "./actualMassMuteCmd"; export const MassMuteMsgCmd = modActionsMsgCmd({ trigger: "massmute", diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts index d7ad927a..cb02ceee 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts @@ -1,9 +1,9 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { actualMassMuteCmd } from "./actualMassMuteCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualMassMuteCmd } from "./actualMassMuteCmd"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), @@ -30,13 +30,7 @@ export const MassMuteSlashSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData.state.common.sendErrorMessage( - interaction, - "Text or attachment required", - undefined, - undefined, - true - ); + pluginData.state.common.sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } diff --git a/backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts b/backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts index e8ed7111..e7615044 100644 --- a/backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts @@ -5,9 +5,12 @@ import { logger } from "../../../../logger"; import { canActOn, isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { ModActionsPluginType } from "../../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { + formatReasonWithAttachments, + formatReasonWithMessageLinkForAttachments, +} from "../../functions/formatReasonForAttachments"; +import { ModActionsPluginType } from "../../types"; export async function actualMassMuteCmd( pluginData: GuildPluginData, @@ -34,10 +37,7 @@ export async function actualMassMuteCmd( for (const userId of userIds) { const member = pluginData.guild.members.cache.get(userId as Snowflake); if (member && !canActOn(pluginData, author, member)) { - pluginData.state.common.sendErrorMessage( - context, - "Cannot massmute one or more users: insufficient permissions" - ); + pluginData.state.common.sendErrorMessage(context, "Cannot massmute one or more users: insufficient permissions"); return; } } @@ -87,9 +87,9 @@ export async function actualMassMuteCmd( if (failedMutes.length) { pluginData.state.common.sendSuccessMessage( - context, - `Muted ${successfulMuteCount} users, ${failedMutes.length} failed: ${failedMutes.join(" ")}`, - ); + context, + `Muted ${successfulMuteCount} users, ${failedMutes.length} failed: ${failedMutes.join(" ")}`, + ); } else { pluginData.state.common.sendSuccessMessage(context, `Muted ${successfulMuteCount} users successfully`); } diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts index c10df41f..2d2dd306 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts @@ -1,8 +1,8 @@ import { waitForReply } from "knub/helpers"; import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { actualMassUnbanCmd } from "./actualMassUnbanCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualMassUnbanCmd } from "./actualMassUnbanCmd"; export const MassUnbanMsgCmd = modActionsMsgCmd({ trigger: "massunban", diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts index 4a733552..acf6a975 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts @@ -1,9 +1,9 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { actualMassUnbanCmd } from "./actualMassUnbanCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualMassUnbanCmd } from "./actualMassUnbanCmd"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), @@ -30,13 +30,7 @@ export const MassUnbanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData.state.common.sendErrorMessage( - interaction, - "Text or attachment required", - undefined, - undefined, - true - ); + pluginData.state.common.sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } diff --git a/backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts index 6f4a0ebf..e67e7066 100644 --- a/backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts @@ -6,11 +6,11 @@ import { isContextInteraction, sendContextResponse } from "../../../../pluginUti import { MINUTES, noop } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { IgnoredEventType, ModActionsPluginType } from "../../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; import { ignoreEvent } from "../../functions/ignoreEvent"; import { isBanned } from "../../functions/isBanned"; +import { IgnoredEventType, ModActionsPluginType } from "../../types"; export async function actualMassUnbanCmd( pluginData: GuildPluginData, @@ -75,10 +75,7 @@ export async function actualMassUnbanCmd( const successfulUnbanCount = userIds.length - failedUnbans.length; if (successfulUnbanCount === 0) { // All unbans failed - don't create a log entry and notify the user - pluginData.state.common.sendErrorMessage( - context, - "All unbans failed. Make sure the IDs are valid and banned." - ); + pluginData.state.common.sendErrorMessage(context, "All unbans failed. Make sure the IDs are valid and banned."); } else { // Some or all unbans were successful. Create a log entry for the mass unban and notify the user. pluginData.getPlugin(LogsPlugin).logMassUnban({ @@ -106,9 +103,9 @@ export async function actualMassUnbanCmd( } pluginData.state.common.sendSuccessMessage( - context, - `Unbanned ${successfulUnbanCount} users, ${failedUnbans.length} failed:\n${failedMsg}`, - ); + context, + `Unbanned ${successfulUnbanCount} users, ${failedUnbans.length} failed:\n${failedMsg}`, + ); } else { pluginData.state.common.sendSuccessMessage(context, `Unbanned ${successfulUnbanCount} users successfully`); } diff --git a/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts index d6aeb284..0135b3e3 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts @@ -2,10 +2,10 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { actualMuteCmd } from "./actualMuteCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; +import { actualMuteCmd } from "./actualMuteCmd"; const opts = { mod: ct.member({ option: true }), @@ -49,7 +49,7 @@ export const MuteMsgCmd = modActionsMsgCmd({ if (_isBanned) { pluginData.state.common.sendErrorMessage( msg, - `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.` + `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.`, ); return; } else { diff --git a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts index b662b33d..d791b9d8 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts @@ -4,11 +4,11 @@ import { canActOn, hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { actualMuteCmd } from "./actualMuteCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualMuteCmd } from "./actualMuteCmd"; const opts = [ slashOptions.string({ name: "time", description: "The duration of the mute", required: false }), @@ -54,7 +54,7 @@ export const MuteSlashCmd = modActionsSlashCmd({ if (_isBanned) { pluginData.state.common.sendErrorMessage( interaction, - `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.` + `User is banned. Use \`${prefix}forcemute\` if you want to mute them anyway.`, ); return; } else { @@ -66,10 +66,7 @@ export const MuteSlashCmd = modActionsSlashCmd({ ); if (!reply) { - pluginData.state.common.sendErrorMessage( - interaction, - "User not on server, mute cancelled by moderator" - ); + pluginData.state.common.sendErrorMessage(interaction, "User not on server, mute cancelled by moderator"); return; } } @@ -90,10 +87,7 @@ export const MuteSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData.state.common.sendErrorMessage( - interaction, - "You don't have permission to act as another moderator" - ); + pluginData.state.common.sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts b/backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts index 6500d072..0a938d06 100644 --- a/backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts @@ -12,9 +12,12 @@ import { } from "../../../../utils"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; import { MuteResult } from "../../../Mutes/types"; -import { ModActionsPluginType } from "../../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { + formatReasonWithAttachments, + formatReasonWithMessageLinkForAttachments, +} from "../../functions/formatReasonForAttachments"; +import { ModActionsPluginType } from "../../types"; /** * The actual function run by both !mute and !forcemute. @@ -56,10 +59,7 @@ export async function actualMuteCmd( }); } catch (e) { if (e instanceof RecoverablePluginError && e.code === ERRORS.NO_MUTE_ROLE_IN_CONFIG) { - pluginData.state.common.sendErrorMessage( - context, - "Could not mute the user: no mute role set in config" - ); + pluginData.state.common.sendErrorMessage(context, "Could not mute the user: no mute role set in config"); } else if (isDiscordAPIError(e) && e.code === 10007) { pluginData.state.common.sendErrorMessage(context, "Could not mute the user: unknown member"); } else { diff --git a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts index 2cccbd6d..4ef15c2e 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts @@ -1,7 +1,7 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { resolveUser } from "../../../../utils"; -import { actualNoteCmd } from "./actualNoteCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualNoteCmd } from "./actualNoteCmd"; export const NoteMsgCmd = modActionsMsgCmd({ trigger: "note", diff --git a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts index c13bbb60..e9069cc8 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts @@ -1,8 +1,8 @@ import { slashOptions } from "knub"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { actualNoteCmd } from "./actualNoteCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualNoteCmd } from "./actualNoteCmd"; const opts = [ slashOptions.string({ name: "note", description: "The note to add to the user", required: false }), @@ -25,13 +25,7 @@ export const NoteSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.note || options.note.trim() === "") && attachments.length < 1) { - pluginData.state.common.sendErrorMessage( - interaction, - "Text or attachment required", - undefined, - undefined, - true - ); + pluginData.state.common.sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } diff --git a/backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts b/backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts index 5c70cb04..b34f8821 100644 --- a/backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts @@ -4,9 +4,9 @@ import { CaseTypes } from "../../../../data/CaseTypes"; import { UnknownUser, renderUsername } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { ModActionsPluginType } from "../../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ModActionsPluginType } from "../../types"; export async function actualNoteCmd( pluginData: GuildPluginData, @@ -39,12 +39,12 @@ export async function actualNoteCmd( }); pluginData.state.common.sendSuccessMessage( - context, - `Note added on **${userName}** (Case #${createdCase.case_number})`, - undefined, - undefined, - true, - ); + context, + `Note added on **${userName}** (Case #${createdCase.case_number})`, + undefined, + undefined, + true, + ); pluginData.state.events.emit("note", user.id, reason); } diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts index ec346acc..8720fadc 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts @@ -1,8 +1,8 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { hasPermission } from "../../../../pluginUtils"; import { resolveUser } from "../../../../utils"; -import { actualUnbanCmd } from "./actualUnbanCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualUnbanCmd } from "./actualUnbanCmd"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts index a5b0124b..8c4ef63a 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts @@ -3,9 +3,9 @@ import { slashOptions } from "knub"; import { hasPermission } from "../../../../pluginUtils"; import { resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { actualUnbanCmd } from "./actualUnbanCmd"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualUnbanCmd } from "./actualUnbanCmd"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), @@ -29,13 +29,7 @@ export const UnbanSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData.state.common.sendErrorMessage( - interaction, - "Text or attachment required", - undefined, - undefined, - true - ); + pluginData.state.common.sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -48,10 +42,7 @@ export const UnbanSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData.state.common.sendErrorMessage( - interaction, - "You don't have permission to act as another moderator" - ); + pluginData.state.common.sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts b/backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts index e49b5b21..5baa31ea 100644 --- a/backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts @@ -6,10 +6,10 @@ import { clearExpiringTempban } from "../../../../data/loops/expiringTempbansLoo import { UnknownUser } from "../../../../utils"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { IgnoredEventType, ModActionsPluginType } from "../../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; import { ignoreEvent } from "../../functions/ignoreEvent"; +import { IgnoredEventType, ModActionsPluginType } from "../../types"; export async function actualUnbanCmd( pluginData: GuildPluginData, @@ -31,10 +31,7 @@ export async function actualUnbanCmd( ignoreEvent(pluginData, IgnoredEventType.Unban, user.id); await pluginData.guild.bans.remove(user.id as Snowflake, formattedReason ?? undefined); } catch { - pluginData.state.common.sendErrorMessage( - context, - "Failed to unban member; are you sure they're banned?" - ); + pluginData.state.common.sendErrorMessage(context, "Failed to unban member; are you sure they're banned?"); return; } diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts index 308c34f2..fe573ba1 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts @@ -1,6 +1,6 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { actualHideCaseCmd } from "../hidecase/actualHideCaseCmd"; import { modActionsMsgCmd } from "../../types"; +import { actualHideCaseCmd } from "../hidecase/actualHideCaseCmd"; export const UnhideCaseMsgCmd = modActionsMsgCmd({ trigger: ["unhide", "unhidecase", "unhide_case"], diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts index f4b4b80f..3bf4b61c 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts @@ -1,6 +1,6 @@ import { slashOptions } from "knub"; -import { actualUnhideCaseCmd } from "./actualUnhideCaseCmd"; import { modActionsSlashCmd } from "../../types"; +import { actualUnhideCaseCmd } from "./actualUnhideCaseCmd"; export const UnhideCaseSlashCmd = modActionsSlashCmd({ name: "unhidecase", diff --git a/backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts index f1e8405e..b1af7433 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts @@ -32,6 +32,6 @@ export async function actualUnhideCaseCmd( const amt = caseNumbers.length - failed.length; pluginData.state.common.sendSuccessMessage( context, - `${amt} case${amt === 1 ? " is" : "s are"} no longer hidden!${failedAddendum}` + `${amt} case${amt === 1 ? " is" : "s are"} no longer hidden!${failedAddendum}`, ); } diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts index a0654d13..925a90a6 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts @@ -3,9 +3,9 @@ import { canActOn, hasPermission } from "../../../../pluginUtils"; import { resolveMember, resolveUser } from "../../../../utils"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { actualUnmuteCmd } from "./actualUnmuteCmd"; import { isBanned } from "../../functions/isBanned"; import { modActionsMsgCmd } from "../../types"; +import { actualUnmuteCmd } from "./actualUnmuteCmd"; const opts = { mod: ct.member({ option: true }), @@ -59,7 +59,7 @@ export const UnmuteMsgCmd = modActionsMsgCmd({ if (banned) { pluginData.state.common.sendErrorMessage( msg, - `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.` + `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.`, ); return; } else { diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts index 609c7451..5420892c 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts @@ -5,10 +5,10 @@ import { convertDelayStringToMS, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { actualUnmuteCmd } from "./actualUnmuteCmd"; import { isBanned } from "../../functions/isBanned"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualUnmuteCmd } from "./actualUnmuteCmd"; const opts = [ slashOptions.string({ name: "time", description: "The duration of the unmute", required: false }), @@ -33,13 +33,7 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ const attachments = retrieveMultipleOptions(NUMBER_ATTACHMENTS_CASE_CREATION, options, "attachment"); if ((!options.reason || options.reason.trim() === "") && attachments.length < 1) { - pluginData.state.common.sendErrorMessage( - interaction, - "Text or attachment required", - undefined, - undefined, - true - ); + pluginData.state.common.sendErrorMessage(interaction, "Text or attachment required", undefined, undefined, true); return; } @@ -64,7 +58,7 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ if (banned) { pluginData.state.common.sendErrorMessage( interaction, - `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.` + `User is banned. Use \`${prefix}forceunmute\` to unmute them anyway.`, ); return; } else { @@ -76,10 +70,7 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ ); if (!reply) { - pluginData.state.common.sendErrorMessage( - interaction, - "User not on server, unmute cancelled by moderator" - ); + pluginData.state.common.sendErrorMessage(interaction, "User not on server, unmute cancelled by moderator"); return; } } @@ -100,10 +91,7 @@ export const UnmuteSlashCmd = modActionsSlashCmd({ if (options.mod) { if (!canActAsOther) { - pluginData.state.common.sendErrorMessage( - interaction, - "You don't have permission to act as another moderator" - ); + pluginData.state.common.sendErrorMessage(interaction, "You don't have permission to act as another moderator"); return; } diff --git a/backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts b/backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts index 3e3be312..da34ed43 100644 --- a/backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts @@ -3,9 +3,9 @@ import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { UnknownUser, asSingleLine, renderUsername } from "../../../../utils"; import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { ModActionsPluginType } from "../../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { ModActionsPluginType } from "../../types"; export async function actualUnmuteCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts index 1d9e331f..99309c22 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts @@ -1,10 +1,10 @@ import { commandTypeHelpers as ct } from "../../../../commandTypes"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { errorMessage, resolveMember, resolveUser } from "../../../../utils"; -import { actualWarnCmd } from "./actualWarnCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsMsgCmd } from "../../types"; +import { actualWarnCmd } from "./actualWarnCmd"; export const WarnMsgCmd = modActionsMsgCmd({ trigger: "warn", diff --git a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts index 82f80ba0..af7449f1 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts @@ -3,11 +3,11 @@ import { slashOptions } from "knub"; import { canActOn, hasPermission } from "../../../../pluginUtils"; import { UserNotificationMethod, resolveMember } from "../../../../utils"; import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { actualWarnCmd } from "./actualWarnCmd"; import { isBanned } from "../../functions/isBanned"; import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; import { modActionsSlashCmd } from "../../types"; import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; +import { actualWarnCmd } from "./actualWarnCmd"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), @@ -51,7 +51,7 @@ export const WarnSlashCmd = modActionsSlashCmd({ "Text or attachment required", undefined, undefined, - true + true, ); return; @@ -86,7 +86,7 @@ export const WarnSlashCmd = modActionsSlashCmd({ if (!canActAsOther) { await pluginData.state.common.sendErrorMessage( interaction, - "You don't have permission to act as another moderator" + "You don't have permission to act as another moderator", ); return; } diff --git a/backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts b/backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts index c764d29d..b505434a 100644 --- a/backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts @@ -4,10 +4,13 @@ import { CaseTypes } from "../../../../data/CaseTypes"; import { UserNotificationMethod, renderUsername } from "../../../../utils"; import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { ModActionsPluginType } from "../../types"; import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; -import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; +import { + formatReasonWithAttachments, + formatReasonWithMessageLinkForAttachments, +} from "../../functions/formatReasonForAttachments"; import { warnMember } from "../../functions/warnMember"; +import { ModActionsPluginType } from "../../types"; export async function actualWarnCmd( pluginData: GuildPluginData, @@ -62,7 +65,7 @@ export async function actualWarnCmd( const messageResultText = warnResult.notifyResult.text ? ` (${warnResult.notifyResult.text})` : ""; await pluginData.state.common.sendSuccessMessage( - context, - `Warned **${renderUsername(memberToWarn.user)}** (Case #${warnResult.case.case_number})${messageResultText}`, - ); + context, + `Warned **${renderUsername(memberToWarn.user)}** (Case #${warnResult.case.case_number})${messageResultText}`, + ); } diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index a3f36c11..14388ea9 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -1,11 +1,12 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { EventEmitter } from "events"; import { - BasePluginType, pluginUtils, + BasePluginType, guildPluginEventListener, guildPluginMessageCommand, guildPluginSlashCommand, - guildPluginSlashGroup + guildPluginSlashGroup, + pluginUtils, } from "knub"; import z from "zod"; import { Queue } from "../../Queue"; diff --git a/backend/src/plugins/Mutes/MutesPlugin.ts b/backend/src/plugins/Mutes/MutesPlugin.ts index c1a8c84b..eeae16df 100644 --- a/backend/src/plugins/Mutes/MutesPlugin.ts +++ b/backend/src/plugins/Mutes/MutesPlugin.ts @@ -8,6 +8,7 @@ import { GuildLogs } from "../../data/GuildLogs"; import { GuildMutes } from "../../data/GuildMutes"; import { makePublicFn } from "../../pluginUtils"; import { CasesPlugin } from "../Cases/CasesPlugin"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin.js"; import { ClearBannedMutesCmd } from "./commands/ClearBannedMutesCmd"; @@ -24,7 +25,6 @@ import { onMutesEvent } from "./functions/onMutesEvent"; import { renewTimeoutMute } from "./functions/renewTimeoutMute"; import { unmuteUser } from "./functions/unmuteUser"; import { MutesPluginType, zMutesConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions = { config: { diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts index 64b77233..43d2c58a 100644 --- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts @@ -1,5 +1,4 @@ import { Snowflake } from "discord.js"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { mutesCmd } from "../types"; export const ClearBannedMutesCmd = mutesCmd({ diff --git a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts index b8f75022..43062754 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { mutesCmd } from "../types"; export const ClearMutesCmd = mutesCmd({ @@ -23,14 +22,17 @@ export const ClearMutesCmd = mutesCmd({ } if (failed.length !== args.userIds.length) { - void pluginData.state.common.sendSuccessMessage(msg, `**${args.userIds.length - failed.length} active mute(s) cleared**`); + void pluginData.state.common.sendSuccessMessage( + msg, + `**${args.userIds.length - failed.length} active mute(s) cleared**`, + ); } if (failed.length) { void pluginData.state.common.sendErrorMessage( - msg, - `**${failed.length}/${args.userIds.length} IDs failed**, they are not muted: ${failed.join(" ")}`, - ); + msg, + `**${failed.length}/${args.userIds.length} IDs failed**, they are not muted: ${failed.join(" ")}`, + ); } }, }); diff --git a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts index c5f7be13..b73d3b41 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts @@ -1,6 +1,5 @@ import { Snowflake } from "discord.js"; import { resolveMember } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { mutesCmd } from "../types"; export const ClearMutesWithoutRoleCmd = mutesCmd({ @@ -26,6 +25,9 @@ export const ClearMutesWithoutRoleCmd = mutesCmd({ } } - void pluginData.state.common.sendSuccessMessage(msg, `Cleared ${cleared} mutes from members that don't have the mute role`); + void pluginData.state.common.sendSuccessMessage( + msg, + `Cleared ${cleared} mutes from members that don't have the mute role`, + ); }, }); diff --git a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts index f8d5f990..617ce019 100644 --- a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts +++ b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts @@ -2,9 +2,9 @@ import { PluginOptions, guildPlugin } from "knub"; import { Queue } from "../../Queue"; import { GuildNicknameHistory } from "../../data/GuildNicknameHistory"; import { UsernameHistory } from "../../data/UsernameHistory"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { NamesCmd } from "./commands/NamesCmd"; import { NameHistoryPluginType, zNameHistoryConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts index 9f3bb418..3fadaadd 100644 --- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts +++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts @@ -5,7 +5,6 @@ import { MAX_NICKNAME_ENTRIES_PER_USER } from "../../../data/GuildNicknameHistor import { MAX_USERNAME_ENTRIES_PER_USER } from "../../../data/UsernameHistory"; import { NICKNAME_RETENTION_PERIOD } from "../../../data/cleanup/nicknames"; import { DAYS, renderUsername } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { nameHistoryCmd } from "../types"; export const NamesCmd = nameHistoryCmd({ diff --git a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts index 118cf044..380a2a25 100644 --- a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts +++ b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts @@ -1,9 +1,9 @@ import { PluginOptions, guildPlugin } from "knub"; import { GuildPingableRoles } from "../../data/GuildPingableRoles"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { PingableRoleDisableCmd } from "./commands/PingableRoleDisableCmd"; import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd"; import { PingableRolesPluginType, zPingableRolesConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts index 3bc1ad58..a66d41a7 100644 --- a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts +++ b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { pingableRolesCmd } from "../types"; export const PingableRoleDisableCmd = pingableRolesCmd({ @@ -14,13 +13,19 @@ export const PingableRoleDisableCmd = pingableRolesCmd({ async run({ message: msg, args, pluginData }) { const pingableRole = await pluginData.state.pingableRoles.getByChannelAndRoleId(args.channelId, args.role.id); if (!pingableRole) { - void pluginData.state.common.sendErrorMessage(msg, `**${args.role.name}** is not set as pingable in <#${args.channelId}>`); + void pluginData.state.common.sendErrorMessage( + msg, + `**${args.role.name}** is not set as pingable in <#${args.channelId}>`, + ); return; } await pluginData.state.pingableRoles.delete(args.channelId, args.role.id); pluginData.state.cache.delete(args.channelId); - void pluginData.state.common.sendSuccessMessage(msg, `**${args.role.name}** is no longer set as pingable in <#${args.channelId}>`); + void pluginData.state.common.sendSuccessMessage( + msg, + `**${args.role.name}** is no longer set as pingable in <#${args.channelId}>`, + ); }, }); diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts index 004c0741..31218b5d 100644 --- a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts +++ b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { pingableRolesCmd } from "../types"; export const PingableRoleEnableCmd = pingableRolesCmd({ @@ -17,13 +16,19 @@ export const PingableRoleEnableCmd = pingableRolesCmd({ args.role.id, ); if (existingPingableRole) { - void pluginData.state.common.sendErrorMessage(msg, `**${args.role.name}** is already set as pingable in <#${args.channelId}>`); + void pluginData.state.common.sendErrorMessage( + msg, + `**${args.role.name}** is already set as pingable in <#${args.channelId}>`, + ); return; } await pluginData.state.pingableRoles.add(args.channelId, args.role.id); pluginData.state.cache.delete(args.channelId); - void pluginData.state.common.sendSuccessMessage(msg, `**${args.role.name}** has been set as pingable in <#${args.channelId}>`); + void pluginData.state.common.sendSuccessMessage( + msg, + `**${args.role.name}** has been set as pingable in <#${args.channelId}>`, + ); }, }); diff --git a/backend/src/plugins/Post/PostPlugin.ts b/backend/src/plugins/Post/PostPlugin.ts index 93376dcf..a96d21b4 100644 --- a/backend/src/plugins/Post/PostPlugin.ts +++ b/backend/src/plugins/Post/PostPlugin.ts @@ -3,6 +3,7 @@ import { onGuildEvent } from "../../data/GuildEvents"; import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildScheduledPosts } from "../../data/GuildScheduledPosts"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { EditCmd } from "./commands/EditCmd"; @@ -14,7 +15,6 @@ import { ScheduledPostsListCmd } from "./commands/ScheduledPostsListCmd"; import { ScheduledPostsShowCmd } from "./commands/ScheduledPostsShowCmd"; import { PostPluginType, zPostConfig } from "./types"; import { postScheduledPost } from "./util/postScheduledPost"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Post/commands/EditCmd.ts b/backend/src/plugins/Post/commands/EditCmd.ts index fb785929..9dc7d2d0 100644 --- a/backend/src/plugins/Post/commands/EditCmd.ts +++ b/backend/src/plugins/Post/commands/EditCmd.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { postCmd } from "../types"; import { formatContent } from "../util/formatContent"; diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts index 4cdfdd8b..3ceff537 100644 --- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts @@ -3,7 +3,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isValidEmbed, trimLines } from "../../../utils"; import { parseColor } from "../../../utils/parseColor"; import { rgbToInt } from "../../../utils/rgbToInt"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { postCmd } from "../types"; import { formatContent } from "../util/formatContent"; diff --git a/backend/src/plugins/Post/commands/PostEmbedCmd.ts b/backend/src/plugins/Post/commands/PostEmbedCmd.ts index e54649e6..4a71d8af 100644 --- a/backend/src/plugins/Post/commands/PostEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/PostEmbedCmd.ts @@ -3,7 +3,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isValidEmbed, trimLines } from "../../../utils"; import { parseColor } from "../../../utils/parseColor"; import { rgbToInt } from "../../../utils/rgbToInt"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { postCmd } from "../types"; import { actualPostCmd } from "../util/actualPostCmd"; import { formatContent } from "../util/formatContent"; diff --git a/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts index d3c6063a..75602f54 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts @@ -1,7 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { clearUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop"; import { sorter } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { postCmd } from "../types"; export const ScheduledPostsDeleteCmd = postCmd({ diff --git a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts index a990e6d9..38e450fc 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts @@ -1,6 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { sorter } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { postCmd } from "../types"; import { postMessage } from "../util/postMessage"; diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index b75bcc53..987be772 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -4,7 +4,6 @@ import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { registerUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop"; import { DBDateFormat, MINUTES, StrictMessageContent, errorMessage, renderUsername } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { PostPluginType } from "../types"; @@ -40,11 +39,17 @@ export async function actualPostCmd( if (opts.repeat) { if (opts.repeat < MIN_REPEAT_TIME) { - void pluginData.state.common.sendErrorMessage(msg, `Minimum time for -repeat is ${humanizeDuration(MIN_REPEAT_TIME)}`); + void pluginData.state.common.sendErrorMessage( + msg, + `Minimum time for -repeat is ${humanizeDuration(MIN_REPEAT_TIME)}`, + ); return; } if (opts.repeat > MAX_REPEAT_TIME) { - void pluginData.state.common.sendErrorMessage(msg, `Max time for -repeat is ${humanizeDuration(MAX_REPEAT_TIME)}`); + void pluginData.state.common.sendErrorMessage( + msg, + `Max time for -repeat is ${humanizeDuration(MAX_REPEAT_TIME)}`, + ); return; } } @@ -95,12 +100,18 @@ export async function actualPostCmd( } if (repeatUntil && repeatTimes) { - void pluginData.state.common.sendErrorMessage(msg, "You can only use one of -repeat-until or -repeat-times at once"); + void pluginData.state.common.sendErrorMessage( + msg, + "You can only use one of -repeat-until or -repeat-times at once", + ); return; } if (opts.repeat && !repeatUntil && !repeatTimes) { - void pluginData.state.common.sendErrorMessage(msg, "You must specify -repeat-until or -repeat-times for repeated messages"); + void pluginData.state.common.sendErrorMessage( + msg, + "You must specify -repeat-until or -repeat-times for repeated messages", + ); return; } diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts index 1848e663..79bcbef0 100644 --- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts +++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts @@ -2,6 +2,7 @@ import { PluginOptions, guildPlugin } from "knub"; import { Queue } from "../../Queue"; import { GuildReactionRoles } from "../../data/GuildReactionRoles"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { ClearReactionRolesCmd } from "./commands/ClearReactionRolesCmd"; import { InitReactionRolesCmd } from "./commands/InitReactionRolesCmd"; @@ -9,7 +10,6 @@ import { RefreshReactionRolesCmd } from "./commands/RefreshReactionRolesCmd"; import { AddReactionRoleEvt } from "./events/AddReactionRoleEvt"; import { MessageDeletedEvt } from "./events/MessageDeletedEvt"; import { ReactionRolesPluginType, zReactionRolesConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const MIN_AUTO_REFRESH = 1000 * 60 * 15; // 15min minimum, let's not abuse the API diff --git a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts index 18baef48..44f22c99 100644 --- a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts @@ -1,7 +1,6 @@ import { Message } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isDiscordAPIError } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { reactionRolesCmd } from "../types"; export const ClearReactionRolesCmd = reactionRolesCmd({ diff --git a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts index 1c166039..35d23865 100644 --- a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts @@ -2,7 +2,6 @@ import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canUseEmoji, isDiscordAPIError, isValidEmoji, noop, trimPluginDescription } from "../../../utils"; import { canReadChannel } from "../../../utils/canReadChannel"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { TReactionRolePair, reactionRolesCmd } from "../types"; import { applyReactionRoleReactionsToMessage } from "../util/applyReactionRoleReactionsToMessage"; @@ -34,7 +33,10 @@ export const InitReactionRolesCmd = reactionRolesCmd({ async run({ message: msg, args, pluginData }) { if (!canReadChannel(args.message.channel, msg.member)) { - void pluginData.state.common.sendErrorMessage(msg, "You can't add reaction roles to channels you can't see yourself"); + void pluginData.state.common.sendErrorMessage( + msg, + "You can't add reaction roles to channels you can't see yourself", + ); return; } @@ -71,7 +73,10 @@ export const InitReactionRolesCmd = reactionRolesCmd({ // Verify the specified emojis and roles are valid and usable for (const pair of emojiRolePairs) { if (pair[0] === CLEAR_ROLES_EMOJI) { - void pluginData.state.common.sendErrorMessage(msg, `The emoji for clearing roles (${CLEAR_ROLES_EMOJI}) is reserved and cannot be used`); + void pluginData.state.common.sendErrorMessage( + msg, + `The emoji for clearing roles (${CLEAR_ROLES_EMOJI}) is reserved and cannot be used`, + ); return; } @@ -81,7 +86,10 @@ export const InitReactionRolesCmd = reactionRolesCmd({ } if (!canUseEmoji(pluginData.client, pair[0])) { - void pluginData.state.common.sendErrorMessage(msg, "I can only use regular emojis and custom emojis from servers I'm on"); + void pluginData.state.common.sendErrorMessage( + msg, + "I can only use regular emojis and custom emojis from servers I'm on", + ); return; } diff --git a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts index fa0e8ac1..ad2e0c47 100644 --- a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { reactionRolesCmd } from "../types"; import { refreshReactionRoles } from "../util/refreshReactionRoles"; diff --git a/backend/src/plugins/Reminders/RemindersPlugin.ts b/backend/src/plugins/Reminders/RemindersPlugin.ts index a6070112..0a4d723f 100644 --- a/backend/src/plugins/Reminders/RemindersPlugin.ts +++ b/backend/src/plugins/Reminders/RemindersPlugin.ts @@ -1,13 +1,13 @@ import { PluginOptions, guildPlugin } from "knub"; import { onGuildEvent } from "../../data/GuildEvents"; import { GuildReminders } from "../../data/GuildReminders"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { RemindCmd } from "./commands/RemindCmd"; import { RemindersCmd } from "./commands/RemindersCmd"; import { RemindersDeleteCmd } from "./commands/RemindersDeleteCmd"; import { postReminder } from "./functions/postReminder"; import { RemindersPluginType, zRemindersConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Reminders/commands/RemindCmd.ts b/backend/src/plugins/Reminders/commands/RemindCmd.ts index d0fb4eb0..7999ad5a 100644 --- a/backend/src/plugins/Reminders/commands/RemindCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindCmd.ts @@ -3,7 +3,6 @@ import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { registerUpcomingReminder } from "../../../data/loops/upcomingRemindersLoop"; import { convertDelayStringToMS, messageLink } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { remindersCmd } from "../types"; @@ -67,6 +66,9 @@ export const RemindCmd = remindersCmd({ pluginData.getPlugin(TimeAndDatePlugin).getDateFormat("pretty_datetime"), ); - void pluginData.state.common.sendSuccessMessage(msg, `I will remind you in **${timeUntilReminder}** at **${prettyReminderTime}**`); + void pluginData.state.common.sendSuccessMessage( + msg, + `I will remind you in **${timeUntilReminder}** at **${prettyReminderTime}**`, + ); }, }); diff --git a/backend/src/plugins/Reminders/commands/RemindersCmd.ts b/backend/src/plugins/Reminders/commands/RemindersCmd.ts index 9f6dacc7..393c5b24 100644 --- a/backend/src/plugins/Reminders/commands/RemindersCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersCmd.ts @@ -1,7 +1,6 @@ import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; import { createChunkedMessage, DBDateFormat, sorter } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; import { remindersCmd } from "../types"; diff --git a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts index 7a57f79b..5e40f692 100644 --- a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts @@ -1,7 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { clearUpcomingReminder } from "../../../data/loops/upcomingRemindersLoop"; import { sorter } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { remindersCmd } from "../types"; export const RemindersDeleteCmd = remindersCmd({ diff --git a/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts b/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts index ecd25e8d..e71c7ed0 100644 --- a/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts +++ b/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts @@ -1,12 +1,12 @@ import { guildPlugin } from "knub"; import { GuildRoleButtons } from "../../data/GuildRoleButtons"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin"; import { resetButtonsCmd } from "./commands/resetButtons"; import { onButtonInteraction } from "./events/buttonInteraction"; import { applyAllRoleButtons } from "./functions/applyAllRoleButtons"; import { RoleButtonsPluginType, zRoleButtonsConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; export const RoleButtonsPlugin = guildPlugin()({ name: "role_buttons", diff --git a/backend/src/plugins/RoleButtons/commands/resetButtons.ts b/backend/src/plugins/RoleButtons/commands/resetButtons.ts index 78b3e6a2..49add73f 100644 --- a/backend/src/plugins/RoleButtons/commands/resetButtons.ts +++ b/backend/src/plugins/RoleButtons/commands/resetButtons.ts @@ -1,6 +1,5 @@ import { guildPluginMessageCommand } from "knub"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { applyAllRoleButtons } from "../functions/applyAllRoleButtons"; import { RoleButtonsPluginType } from "../types"; diff --git a/backend/src/plugins/RoleButtons/types.ts b/backend/src/plugins/RoleButtons/types.ts index 42fa6bf9..b863e7bc 100644 --- a/backend/src/plugins/RoleButtons/types.ts +++ b/backend/src/plugins/RoleButtons/types.ts @@ -3,9 +3,9 @@ import { BasePluginType, pluginUtils } from "knub"; import z from "zod"; import { GuildRoleButtons } from "../../data/GuildRoleButtons"; import { zBoundedCharacters, zBoundedRecord, zMessageContent, zSnowflake } from "../../utils"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { TooManyComponentsError } from "./functions/TooManyComponentsError"; import { createButtonComponents } from "./functions/createButtonComponents"; -import { CommonPlugin } from "../Common/CommonPlugin"; const zRoleButtonOption = z.strictObject({ role_id: zSnowflake, diff --git a/backend/src/plugins/Roles/RolesPlugin.ts b/backend/src/plugins/Roles/RolesPlugin.ts index 4d4bdbb9..117339b8 100644 --- a/backend/src/plugins/Roles/RolesPlugin.ts +++ b/backend/src/plugins/Roles/RolesPlugin.ts @@ -1,5 +1,6 @@ import { PluginOptions, guildPlugin } from "knub"; import { GuildLogs } from "../../data/GuildLogs"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin"; import { AddRoleCmd } from "./commands/AddRoleCmd"; @@ -7,7 +8,6 @@ import { MassAddRoleCmd } from "./commands/MassAddRoleCmd"; import { MassRemoveRoleCmd } from "./commands/MassRemoveRoleCmd"; import { RemoveRoleCmd } from "./commands/RemoveRoleCmd"; import { RolesPluginType, zRolesConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Roles/commands/AddRoleCmd.ts b/backend/src/plugins/Roles/commands/AddRoleCmd.ts index 66506c9e..9ce16346 100644 --- a/backend/src/plugins/Roles/commands/AddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/AddRoleCmd.ts @@ -2,7 +2,6 @@ import { GuildChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn } from "../../../pluginUtils"; import { resolveRoleId, verboseUserMention } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; import { rolesCmd } from "../types"; @@ -58,6 +57,9 @@ export const AddRoleCmd = rolesCmd({ roles: [role], }); - void pluginData.state.common.sendSuccessMessage(msg, `Added role **${role.name}** to ${verboseUserMention(args.member.user)}!`); + void pluginData.state.common.sendSuccessMessage( + msg, + `Added role **${role.name}** to ${verboseUserMention(args.member.user)}!`, + ); }, }); diff --git a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts index 991cdcdb..4a73eaa9 100644 --- a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts @@ -3,7 +3,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { logger } from "../../../logger"; import { canActOn } from "../../../pluginUtils"; import { resolveMember, resolveRoleId, successMessage } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; import { rolesCmd } from "../types"; @@ -30,7 +29,10 @@ export const MassAddRoleCmd = rolesCmd({ for (const member of members) { if (!canActOn(pluginData, msg.member, member, true)) { - void pluginData.state.common.sendErrorMessage(msg, "Cannot add roles to 1 or more specified members: insufficient permissions"); + void pluginData.state.common.sendErrorMessage( + msg, + "Cannot add roles to 1 or more specified members: insufficient permissions", + ); return; } } diff --git a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts index 6ba75d53..bc0d3233 100644 --- a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts @@ -2,7 +2,6 @@ import { GuildMember } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn } from "../../../pluginUtils"; import { resolveMember, resolveRoleId, successMessage } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; import { rolesCmd } from "../types"; @@ -29,7 +28,10 @@ export const MassRemoveRoleCmd = rolesCmd({ for (const member of members) { if (!canActOn(pluginData, msg.member, member, true)) { - void pluginData.state.common.sendErrorMessage(msg, "Cannot add roles to 1 or more specified members: insufficient permissions"); + void pluginData.state.common.sendErrorMessage( + msg, + "Cannot add roles to 1 or more specified members: insufficient permissions", + ); return; } } diff --git a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts index d1b8a7fa..a8b12479 100644 --- a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts @@ -2,7 +2,6 @@ import { GuildChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn } from "../../../pluginUtils"; import { resolveRoleId, verboseUserMention } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; import { rolesCmd } from "../types"; @@ -19,7 +18,10 @@ export const RemoveRoleCmd = rolesCmd({ async run({ message: msg, args, pluginData }) { if (!canActOn(pluginData, msg.member, args.member, true)) { - void pluginData.state.common.sendErrorMessage(msg, "Cannot remove roles from this user: insufficient permissions"); + void pluginData.state.common.sendErrorMessage( + msg, + "Cannot remove roles from this user: insufficient permissions", + ); return; } @@ -57,6 +59,9 @@ export const RemoveRoleCmd = rolesCmd({ roles: [role], }); - void pluginData.state.common.sendSuccessMessage(msg, `Removed role **${role.name}** from ${verboseUserMention(args.member.user)}!`); + void pluginData.state.common.sendSuccessMessage( + msg, + `Removed role **${role.name}** from ${verboseUserMention(args.member.user)}!`, + ); }, }); diff --git a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts index a6a823d8..e7fbe875 100644 --- a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts +++ b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts @@ -1,9 +1,9 @@ import { CooldownManager, PluginOptions, guildPlugin } from "knub"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { RoleAddCmd } from "./commands/RoleAddCmd"; import { RoleHelpCmd } from "./commands/RoleHelpCmd"; import { RoleRemoveCmd } from "./commands/RoleRemoveCmd"; import { SelfGrantableRolesPluginType, zSelfGrantableRolesConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts index 4dfcacba..f4e718aa 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts @@ -1,7 +1,6 @@ import { Role, Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { selfGrantableRolesCmd } from "../types"; import { findMatchingRoles } from "../util/findMatchingRoles"; import { getApplyingEntries } from "../util/getApplyingEntries"; @@ -39,9 +38,13 @@ export const RoleAddCmd = selfGrantableRolesCmd({ }, new Map()); if (!rolesToAdd.size) { - void pluginData.state.common.sendErrorMessage(msg, `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, { - users: [msg.author.id], - }); + void pluginData.state.common.sendErrorMessage( + msg, + `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, + { + users: [msg.author.id], + }, + ); lock.unlock(); return; } @@ -81,9 +84,13 @@ export const RoleAddCmd = selfGrantableRolesCmd({ roles: Array.from(newRoleIds) as Snowflake[], }); } catch { - void pluginData.state.common.sendErrorMessage(msg, `<@!${msg.author.id}> Got an error while trying to grant you the roles`, { - users: [msg.author.id], - }); + void pluginData.state.common.sendErrorMessage( + msg, + `<@!${msg.author.id}> Got an error while trying to grant you the roles`, + { + users: [msg.author.id], + }, + ); return; } diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts index 11e4a4cd..1ca76b4d 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts @@ -1,7 +1,6 @@ import { Snowflake } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { memberRolesLock } from "../../../utils/lockNameHelpers"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { selfGrantableRolesCmd } from "../types"; import { findMatchingRoles } from "../util/findMatchingRoles"; import { getApplyingEntries } from "../util/getApplyingEntries"; @@ -53,19 +52,31 @@ export const RoleRemoveCmd = selfGrantableRolesCmd({ { users: [msg.author.id] }, ); } else { - void pluginData.state.common.sendSuccessMessage(msg, `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord}`, { - users: [msg.author.id], - }); + void pluginData.state.common.sendSuccessMessage( + msg, + `<@!${msg.author.id}> Removed ${removedRolesStr.join(", ")} ${removedRolesWord}`, + { + users: [msg.author.id], + }, + ); } } catch { - void pluginData.state.common.sendSuccessMessage(msg, `<@!${msg.author.id}> Got an error while trying to remove the roles`, { - users: [msg.author.id], - }); + void pluginData.state.common.sendSuccessMessage( + msg, + `<@!${msg.author.id}> Got an error while trying to remove the roles`, + { + users: [msg.author.id], + }, + ); } } else { - void pluginData.state.common.sendErrorMessage(msg, `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, { - users: [msg.author.id], - }); + void pluginData.state.common.sendErrorMessage( + msg, + `<@!${msg.author.id}> Unknown ${args.roleNames.length === 1 ? "role" : "roles"}`, + { + users: [msg.author.id], + }, + ); } lock.unlock(); diff --git a/backend/src/plugins/Slowmode/SlowmodePlugin.ts b/backend/src/plugins/Slowmode/SlowmodePlugin.ts index 8a0b7de9..e82d6d62 100644 --- a/backend/src/plugins/Slowmode/SlowmodePlugin.ts +++ b/backend/src/plugins/Slowmode/SlowmodePlugin.ts @@ -3,6 +3,7 @@ import { GuildLogs } from "../../data/GuildLogs"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildSlowmodes } from "../../data/GuildSlowmodes"; import { SECONDS } from "../../utils"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { SlowmodeClearCmd } from "./commands/SlowmodeClearCmd"; import { SlowmodeDisableCmd } from "./commands/SlowmodeDisableCmd"; @@ -12,7 +13,6 @@ import { SlowmodeSetCmd } from "./commands/SlowmodeSetCmd"; import { SlowmodePluginType, zSlowmodeConfig } from "./types"; import { clearExpiredSlowmodes } from "./util/clearExpiredSlowmodes"; import { onMessageCreate } from "./util/onMessageCreate"; -import { CommonPlugin } from "../Common/CommonPlugin"; const BOT_SLOWMODE_CLEAR_INTERVAL = 60 * SECONDS; diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts index 29465e79..c00f1ad9 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts @@ -3,7 +3,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { asSingleLine, renderUsername } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { BOT_SLOWMODE_CLEAR_PERMISSIONS } from "../requiredPermissions"; import { slowmodeCmd } from "../types"; import { clearBotSlowmodeFromUserId } from "../util/clearBotSlowmodeFromUserId"; @@ -29,7 +28,10 @@ export const SlowmodeClearCmd = slowmodeCmd({ const me = pluginData.guild.members.cache.get(pluginData.client.user!.id)!; const missingPermissions = getMissingChannelPermissions(me, args.channel, BOT_SLOWMODE_CLEAR_PERMISSIONS); if (missingPermissions) { - void pluginData.state.common.sendErrorMessage(msg, `Unable to clear slowmode. ${missingPermissionError(missingPermissions)}`); + void pluginData.state.common.sendErrorMessage( + msg, + `Unable to clear slowmode. ${missingPermissionError(missingPermissions)}`, + ); return; } @@ -57,6 +59,9 @@ export const SlowmodeClearCmd = slowmodeCmd({ return; } - void pluginData.state.common.sendSuccessMessage(msg, `Slowmode cleared from **${renderUsername(args.user)}** in <#${args.channel.id}>`); + void pluginData.state.common.sendSuccessMessage( + msg, + `Slowmode cleared from **${renderUsername(args.user)}** in <#${args.channel.id}>`, + ); }, }); diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index 6f951084..84cf6baa 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -4,7 +4,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { asSingleLine, DAYS, HOURS, MINUTES } from "../../../utils"; import { getMissingPermissions } from "../../../utils/getMissingPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { BOT_SLOWMODE_PERMISSIONS, NATIVE_SLOWMODE_PERMISSIONS } from "../requiredPermissions"; import { slowmodeCmd } from "../types"; import { actualDisableSlowmodeCmd } from "../util/actualDisableSlowmodeCmd"; @@ -67,7 +66,10 @@ export const SlowmodeSetCmd = slowmodeCmd({ } if (mode === "bot" && args.time > MAX_BOT_SLOWMODE) { - void pluginData.state.common.sendErrorMessage(msg, `Sorry, bot managed slowmodes can be at most 100 years long. Maybe 99 would be enough?`); + void pluginData.state.common.sendErrorMessage( + msg, + `Sorry, bot managed slowmodes can be at most 100 years long. Maybe 99 would be enough?`, + ); return; } @@ -91,7 +93,10 @@ export const SlowmodeSetCmd = slowmodeCmd({ NATIVE_SLOWMODE_PERMISSIONS, ); if (missingPermissions) { - void pluginData.state.common.sendErrorMessage(msg, `Unable to set native slowmode. ${missingPermissionError(missingPermissions)}`); + void pluginData.state.common.sendErrorMessage( + msg, + `Unable to set native slowmode. ${missingPermissionError(missingPermissions)}`, + ); return; } } @@ -102,7 +107,10 @@ export const SlowmodeSetCmd = slowmodeCmd({ BOT_SLOWMODE_PERMISSIONS, ); if (missingPermissions) { - void pluginData.state.common.sendErrorMessage(msg, `Unable to set bot managed slowmode. ${missingPermissionError(missingPermissions)}`); + void pluginData.state.common.sendErrorMessage( + msg, + `Unable to set bot managed slowmode. ${missingPermissionError(missingPermissions)}`, + ); return; } } @@ -121,7 +129,10 @@ export const SlowmodeSetCmd = slowmodeCmd({ try { await channel.setRateLimitPerUser(rateLimitSeconds); } catch (e) { - void pluginData.state.common.sendErrorMessage(msg, `Failed to set native slowmode: ${escapeInlineCode(e.message)}`); + void pluginData.state.common.sendErrorMessage( + msg, + `Failed to set native slowmode: ${escapeInlineCode(e.message)}`, + ); return; } } else { @@ -140,6 +151,9 @@ export const SlowmodeSetCmd = slowmodeCmd({ const humanizedSlowmodeTime = humanizeDuration(args.time); const slowmodeType = mode === "native" ? "native slowmode" : "bot-maintained slowmode"; - void pluginData.state.common.sendSuccessMessage(msg, `Set ${humanizedSlowmodeTime} slowmode for <#${channel.id}> (${slowmodeType})`); + void pluginData.state.common.sendSuccessMessage( + msg, + `Set ${humanizedSlowmodeTime} slowmode for <#${channel.id}> (${slowmodeType})`, + ); }, }); diff --git a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts index da245eb4..64298763 100644 --- a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts +++ b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts @@ -2,7 +2,6 @@ import { Message } from "discord.js"; import { noop } from "../../../utils"; import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { BOT_SLOWMODE_DISABLE_PERMISSIONS } from "../requiredPermissions"; import { disableBotSlowmodeForChannel } from "./disableBotSlowmodeForChannel"; @@ -18,7 +17,10 @@ export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { const me = pluginData.guild.members.cache.get(pluginData.client.user!.id); const missingPermissions = getMissingChannelPermissions(me, args.channel, BOT_SLOWMODE_DISABLE_PERMISSIONS); if (missingPermissions) { - void pluginData.state.common.sendErrorMessage(msg, `Unable to disable slowmode. ${missingPermissionError(missingPermissions)}`); + void pluginData.state.common.sendErrorMessage( + msg, + `Unable to disable slowmode. ${missingPermissionError(missingPermissions)}`, + ); return; } diff --git a/backend/src/plugins/Starboard/StarboardPlugin.ts b/backend/src/plugins/Starboard/StarboardPlugin.ts index 9888b013..37ac2397 100644 --- a/backend/src/plugins/Starboard/StarboardPlugin.ts +++ b/backend/src/plugins/Starboard/StarboardPlugin.ts @@ -2,12 +2,12 @@ import { PluginOptions, guildPlugin } from "knub"; import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildStarboardMessages } from "../../data/GuildStarboardMessages"; import { GuildStarboardReactions } from "../../data/GuildStarboardReactions"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { MigratePinsCmd } from "./commands/MigratePinsCmd"; import { StarboardReactionAddEvt } from "./events/StarboardReactionAddEvt"; import { StarboardReactionRemoveAllEvt, StarboardReactionRemoveEvt } from "./events/StarboardReactionRemoveEvts"; import { StarboardPluginType, zStarboardConfig } from "./types"; import { onMessageDelete } from "./util/onMessageDelete"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts index 114b293f..448ba465 100644 --- a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts +++ b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts @@ -1,6 +1,5 @@ import { Snowflake, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { starboardCmd } from "../types"; import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; @@ -43,6 +42,9 @@ export const MigratePinsCmd = starboardCmd({ await saveMessageToStarboard(pluginData, pin, starboard); } - void pluginData.state.common.sendSuccessMessage(msg, `Pins migrated from <#${args.pinChannel.id}> to <#${starboardChannel.id}>!`); + void pluginData.state.common.sendSuccessMessage( + msg, + `Pins migrated from <#${args.pinChannel.id}> to <#${starboardChannel.id}>!`, + ); }, }); diff --git a/backend/src/plugins/Tags/TagsPlugin.ts b/backend/src/plugins/Tags/TagsPlugin.ts index 97d667c4..cf82440e 100644 --- a/backend/src/plugins/Tags/TagsPlugin.ts +++ b/backend/src/plugins/Tags/TagsPlugin.ts @@ -8,6 +8,7 @@ import { GuildSavedMessages } from "../../data/GuildSavedMessages"; import { GuildTags } from "../../data/GuildTags"; import { makePublicFn } from "../../pluginUtils"; import { convertDelayStringToMS } from "../../utils"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { LogsPlugin } from "../Logs/LogsPlugin"; import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { TagCreateCmd } from "./commands/TagCreateCmd"; @@ -20,7 +21,6 @@ import { findTagByName } from "./util/findTagByName"; import { onMessageCreate } from "./util/onMessageCreate"; import { onMessageDelete } from "./util/onMessageDelete"; import { renderTagBody } from "./util/renderTagBody"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Tags/commands/TagCreateCmd.ts b/backend/src/plugins/Tags/commands/TagCreateCmd.ts index 8aab9647..872c63bd 100644 --- a/backend/src/plugins/Tags/commands/TagCreateCmd.ts +++ b/backend/src/plugins/Tags/commands/TagCreateCmd.ts @@ -1,6 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { TemplateParseError, parseTemplate } from "../../../templateFormatter"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { tagsCmd } from "../types"; export const TagCreateCmd = tagsCmd({ diff --git a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts index 618b6796..66913a5e 100644 --- a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts +++ b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { tagsCmd } from "../types"; export const TagDeleteCmd = tagsCmd({ diff --git a/backend/src/plugins/Tags/commands/TagEvalCmd.ts b/backend/src/plugins/Tags/commands/TagEvalCmd.ts index 9cdab774..3cc045e6 100644 --- a/backend/src/plugins/Tags/commands/TagEvalCmd.ts +++ b/backend/src/plugins/Tags/commands/TagEvalCmd.ts @@ -3,7 +3,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { logger } from "../../../logger"; import { TemplateParseError } from "../../../templateFormatter"; import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { tagsCmd } from "../types"; import { renderTagBody } from "../util/renderTagBody"; diff --git a/backend/src/plugins/Tags/commands/TagSourceCmd.ts b/backend/src/plugins/Tags/commands/TagSourceCmd.ts index 0a16c41b..35be3515 100644 --- a/backend/src/plugins/Tags/commands/TagSourceCmd.ts +++ b/backend/src/plugins/Tags/commands/TagSourceCmd.ts @@ -1,7 +1,6 @@ import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { getBaseUrl } from "../../../pluginUtils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { tagsCmd } from "../types"; export const TagSourceCmd = tagsCmd({ diff --git a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts index 4c84c4ff..daeaa2ad 100644 --- a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts +++ b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts @@ -1,6 +1,7 @@ import { PluginOptions, guildPlugin } from "knub"; import { GuildMemberTimezones } from "../../data/GuildMemberTimezones"; import { makePublicFn } from "../../pluginUtils"; +import { CommonPlugin } from "../Common/CommonPlugin"; import { ResetTimezoneCmd } from "./commands/ResetTimezoneCmd"; import { SetTimezoneCmd } from "./commands/SetTimezoneCmd"; import { ViewTimezoneCmd } from "./commands/ViewTimezoneCmd"; @@ -11,7 +12,6 @@ import { getMemberTz } from "./functions/getMemberTz"; import { inGuildTz } from "./functions/inGuildTz"; import { inMemberTz } from "./functions/inMemberTz"; import { TimeAndDatePluginType, zTimeAndDateConfig } from "./types"; -import { CommonPlugin } from "../Common/CommonPlugin"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts index 88eddd18..1a9c1daf 100644 --- a/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts @@ -1,4 +1,3 @@ -import { CommonPlugin } from "../../Common/CommonPlugin"; import { getGuildTz } from "../functions/getGuildTz"; import { timeAndDateCmd } from "../types"; @@ -11,6 +10,9 @@ export const ResetTimezoneCmd = timeAndDateCmd({ async run({ pluginData, message }) { await pluginData.state.memberTimezones.reset(message.author.id); const serverTimezone = getGuildTz(pluginData); - void pluginData.state.common.sendSuccessMessage(message, `Your timezone has been reset to server default, **${serverTimezone}**`); + void pluginData.state.common.sendSuccessMessage( + message, + `Your timezone has been reset to server default, **${serverTimezone}**`, + ); }, }); diff --git a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts index 684f60f7..092edadc 100644 --- a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts @@ -2,7 +2,6 @@ import { escapeInlineCode } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { trimLines } from "../../../utils"; import { parseFuzzyTimezone } from "../../../utils/parseFuzzyTimezone"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { timeAndDateCmd } from "../types"; export const SetTimezoneCmd = timeAndDateCmd({ diff --git a/backend/src/plugins/TimeAndDate/types.ts b/backend/src/plugins/TimeAndDate/types.ts index 5bb5253d..1890e3d4 100644 --- a/backend/src/plugins/TimeAndDate/types.ts +++ b/backend/src/plugins/TimeAndDate/types.ts @@ -4,8 +4,8 @@ import z from "zod"; import { GuildMemberTimezones } from "../../data/GuildMemberTimezones"; import { keys } from "../../utils"; import { zValidTimezone } from "../../utils/zValidTimezone"; -import { defaultDateFormats } from "./defaultDateFormats"; import { CommonPlugin } from "../Common/CommonPlugin"; +import { defaultDateFormats } from "./defaultDateFormats"; const zDateFormatKeys = z.enum(keys(defaultDateFormats) as U.ListOf); diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index b0b7ce7e..4fb146e7 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -1,7 +1,6 @@ import { APIEmbed, ImageFormat } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { UnknownUser, renderUsername } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { utilityCmd } from "../types"; export const AvatarCmd = utilityCmd({ diff --git a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts index dc0901bc..d39d5364 100644 --- a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed"; import { utilityCmd } from "../types"; diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index 6eac645e..fb06f689 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -8,7 +8,6 @@ import { humanizeDurationShort } from "../../../humanizeDurationShort"; import { getBaseUrl } from "../../../pluginUtils"; import { ModActionsPlugin } from "../../../plugins/ModActions/ModActionsPlugin"; import { DAYS, SECONDS, chunkArray, getInviteCodesInString, noop } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { UtilityPluginType, utilityCmd } from "../types"; @@ -94,7 +93,12 @@ export async function cleanCmd(pluginData: GuildPluginData, a const targetChannel = args.channel ? pluginData.guild.channels.cache.get(args.channel as Snowflake) : msg.channel; if (!targetChannel?.isTextBased()) { - void pluginData.state.common.sendErrorMessage(msg, `Invalid channel specified`, undefined, args["response-interaction"]); + void pluginData.state.common.sendErrorMessage( + msg, + `Invalid channel specified`, + undefined, + args["response-interaction"], + ); return; } @@ -217,10 +221,20 @@ export async function cleanCmd(pluginData: GuildPluginData, a } } - responseMsg = await pluginData.state.common.sendSuccessMessage(msg, responseText, undefined, args["response-interaction"]); + responseMsg = await pluginData.state.common.sendSuccessMessage( + msg, + responseText, + undefined, + args["response-interaction"], + ); } else { const responseText = `Found no messages to clean${note ? ` (${note})` : ""}!`; - responseMsg = await pluginData.state.common.sendErrorMessage(msg, responseText, undefined, args["response-interaction"]); + responseMsg = await pluginData.state.common.sendErrorMessage( + msg, + responseText, + undefined, + args["response-interaction"], + ); } cleaningMessage?.delete(); diff --git a/backend/src/plugins/Utility/commands/ContextCmd.ts b/backend/src/plugins/Utility/commands/ContextCmd.ts index 9db76606..0bbb8d68 100644 --- a/backend/src/plugins/Utility/commands/ContextCmd.ts +++ b/backend/src/plugins/Utility/commands/ContextCmd.ts @@ -2,7 +2,6 @@ import { Snowflake, TextChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { messageLink } from "../../../utils"; import { canReadChannel } from "../../../utils/canReadChannel"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { utilityCmd } from "../types"; export const ContextCmd = utilityCmd({ diff --git a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts index e5806aec..ff1a8fa7 100644 --- a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { getCustomEmojiId } from "../functions/getCustomEmojiId"; import { getEmojiInfoEmbed } from "../functions/getEmojiInfoEmbed"; import { utilityCmd } from "../types"; diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index 9314dbce..75f12197 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -4,7 +4,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { isValidSnowflake, noop, parseInviteCodeInput, resolveInvite, resolveUser } from "../../../utils"; import { canReadChannel } from "../../../utils/canReadChannel"; import { resolveMessageTarget } from "../../../utils/resolveMessageTarget"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed"; import { getCustomEmojiId } from "../functions/getCustomEmojiId"; import { getEmojiInfoEmbed } from "../functions/getEmojiInfoEmbed"; diff --git a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts index bbecd794..37d8493b 100644 --- a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts @@ -1,6 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { parseInviteCodeInput } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { getInviteInfoEmbed } from "../functions/getInviteInfoEmbed"; import { utilityCmd } from "../types"; diff --git a/backend/src/plugins/Utility/commands/JumboCmd.ts b/backend/src/plugins/Utility/commands/JumboCmd.ts index d29dc608..11d42a04 100644 --- a/backend/src/plugins/Utility/commands/JumboCmd.ts +++ b/backend/src/plugins/Utility/commands/JumboCmd.ts @@ -4,7 +4,6 @@ import fs from "fs"; import twemoji from "twemoji"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { downloadFile, isEmoji, SECONDS } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { utilityCmd } from "../types"; const fsp = fs.promises; diff --git a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts index 4ea7da69..1b4496b8 100644 --- a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts @@ -1,6 +1,5 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canReadChannel } from "../../../utils/canReadChannel"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { getMessageInfoEmbed } from "../functions/getMessageInfoEmbed"; import { utilityCmd } from "../types"; diff --git a/backend/src/plugins/Utility/commands/NicknameCmd.ts b/backend/src/plugins/Utility/commands/NicknameCmd.ts index fd33a755..ec274703 100644 --- a/backend/src/plugins/Utility/commands/NicknameCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameCmd.ts @@ -2,7 +2,6 @@ import { escapeBold } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn } from "../../../pluginUtils"; import { errorMessage } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { utilityCmd } from "../types"; export const NicknameCmd = utilityCmd({ diff --git a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts index 8fd23c84..34ae2cbb 100644 --- a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts @@ -1,7 +1,6 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn } from "../../../pluginUtils"; import { errorMessage } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { utilityCmd } from "../types"; export const NicknameResetCmd = utilityCmd({ diff --git a/backend/src/plugins/Utility/commands/RolesCmd.ts b/backend/src/plugins/Utility/commands/RolesCmd.ts index 08ec5dc1..a9d9dc1d 100644 --- a/backend/src/plugins/Utility/commands/RolesCmd.ts +++ b/backend/src/plugins/Utility/commands/RolesCmd.ts @@ -1,7 +1,6 @@ import { Role } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { chunkArray, sorter, trimLines } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { refreshMembersIfNeeded } from "../refreshMembers"; import { utilityCmd } from "../types"; diff --git a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts index 0388d8cd..94a9c91d 100644 --- a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { getServerInfoEmbed } from "../functions/getServerInfoEmbed"; import { utilityCmd } from "../types"; diff --git a/backend/src/plugins/Utility/commands/SourceCmd.ts b/backend/src/plugins/Utility/commands/SourceCmd.ts index 5fccc109..e51f94d3 100644 --- a/backend/src/plugins/Utility/commands/SourceCmd.ts +++ b/backend/src/plugins/Utility/commands/SourceCmd.ts @@ -2,7 +2,6 @@ import moment from "moment-timezone"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { getBaseUrl } from "../../../pluginUtils"; import { canReadChannel } from "../../../utils/canReadChannel"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { utilityCmd } from "../types"; export const SourceCmd = utilityCmd({ diff --git a/backend/src/plugins/Utility/commands/UserInfoCmd.ts b/backend/src/plugins/Utility/commands/UserInfoCmd.ts index 9f2698a9..274fbbbc 100644 --- a/backend/src/plugins/Utility/commands/UserInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/UserInfoCmd.ts @@ -1,5 +1,4 @@ import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { getUserInfoEmbed } from "../functions/getUserInfoEmbed"; import { utilityCmd } from "../types"; diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index 797f5dda..299b27a6 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -2,7 +2,6 @@ import { VoiceChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn } from "../../../pluginUtils"; import { renderUsername } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { utilityCmd } from "../types"; @@ -43,7 +42,7 @@ export const VcdisconnectCmd = utilityCmd({ pluginData.state.common.sendSuccessMessage( msg, - `**${renderUsername(args.member)}** disconnected from **${channel.name}**` + `**${renderUsername(args.member)}** disconnected from **${channel.name}**`, ); }, }); diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index eee432c7..a037d379 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -2,7 +2,6 @@ import { ChannelType, Snowflake, VoiceChannel } from "discord.js"; import { commandTypeHelpers as ct } from "../../../commandTypes"; import { canActOn } from "../../../pluginUtils"; import { channelMentionRegex, isSnowflake, renderUsername, simpleClosestStringMatch } from "../../../utils"; -import { CommonPlugin } from "../../Common/CommonPlugin"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { utilityCmd } from "../types"; @@ -81,7 +80,10 @@ export const VcmoveCmd = utilityCmd({ newChannel: channel, }); - void pluginData.state.common.sendSuccessMessage(msg, `**${renderUsername(args.member)}** moved to **${channel.name}**`); + void pluginData.state.common.sendSuccessMessage( + msg, + `**${renderUsername(args.member)}** moved to **${channel.name}**`, + ); }, }); @@ -168,7 +170,10 @@ export const VcmoveAllCmd = utilityCmd({ void pluginData.state.common.sendErrorMessage(msg, "Unknown error when trying to move members"); return; } - void pluginData.state.common.sendErrorMessage(msg, `Failed to move ${renderUsername(currMember)} (${currMember.id})`); + void pluginData.state.common.sendErrorMessage( + msg, + `Failed to move ${renderUsername(currMember)} (${currMember.id})`, + ); errAmt++; continue; } From 45e3fe2ef0b390301eacc211dc2674cf1338517b Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 11 Aug 2024 21:58:52 +0300 Subject: [PATCH 30/30] chore: esm imports This will make merging this into 'next' much easier. --- backend/src/Queue.ts | 2 +- backend/src/QueuedEventEmitter.ts | 2 +- backend/src/RegExpRunner.ts | 2 +- backend/src/api/archives.ts | 4 +- backend/src/api/auth.ts | 12 +- backend/src/api/docs.ts | 8 +- backend/src/api/guilds.ts | 28 +-- backend/src/api/guilds/importExport.ts | 14 +- backend/src/api/guilds/index.ts | 6 +- backend/src/api/guilds/misc.ts | 26 +-- backend/src/api/index.ts | 8 +- backend/src/api/permissions.ts | 8 +- backend/src/api/rateLimits.ts | 2 +- backend/src/api/staff.ts | 4 +- backend/src/api/start.ts | 14 +- backend/src/api/tasks.ts | 4 +- backend/src/commandTypes.ts | 6 +- backend/src/configValidator.ts | 6 +- backend/src/data/AllowedGuilds.ts | 10 +- backend/src/data/ApiAuditLog.ts | 8 +- backend/src/data/ApiLogins.ts | 8 +- backend/src/data/ApiPermissionAssignments.ts | 12 +- backend/src/data/ApiUserInfo.ts | 8 +- backend/src/data/Archives.ts | 6 +- backend/src/data/BaseGuildRepository.ts | 2 +- backend/src/data/BaseRepository.ts | 2 +- backend/src/data/Configs.ts | 12 +- backend/src/data/GuildAntiraidLevels.ts | 6 +- backend/src/data/GuildArchives.ts | 18 +- backend/src/data/GuildAutoReactions.ts | 6 +- backend/src/data/GuildButtonRoles.ts | 4 +- backend/src/data/GuildCases.ts | 14 +- backend/src/data/GuildContextMenuLinks.ts | 6 +- backend/src/data/GuildCounters.ts | 16 +- backend/src/data/GuildEvents.ts | 10 +- backend/src/data/GuildLogs.ts | 2 +- backend/src/data/GuildMemberCache.ts | 10 +- backend/src/data/GuildMemberTimezones.ts | 6 +- backend/src/data/GuildMutes.ts | 10 +- backend/src/data/GuildNicknameHistory.ts | 12 +- backend/src/data/GuildPersistedData.ts | 6 +- backend/src/data/GuildPingableRoles.ts | 6 +- backend/src/data/GuildReactionRoles.ts | 6 +- backend/src/data/GuildReminders.ts | 6 +- backend/src/data/GuildRoleButtons.ts | 6 +- backend/src/data/GuildRoleQueue.ts | 6 +- backend/src/data/GuildSavedMessages.ts | 16 +- backend/src/data/GuildScheduledPosts.ts | 6 +- backend/src/data/GuildSlowmodes.ts | 8 +- backend/src/data/GuildStarboardMessages.ts | 6 +- backend/src/data/GuildStarboardReactions.ts | 6 +- backend/src/data/GuildStats.ts | 6 +- backend/src/data/GuildTags.ts | 8 +- backend/src/data/GuildTempbans.ts | 6 +- backend/src/data/GuildVCAlerts.ts | 6 +- backend/src/data/MemberCache.ts | 8 +- backend/src/data/Mutes.ts | 10 +- backend/src/data/Phisherman.ts | 12 +- backend/src/data/Reminders.ts | 8 +- backend/src/data/ScheduledPosts.ts | 8 +- backend/src/data/Supporters.ts | 6 +- backend/src/data/Tempbans.ts | 8 +- backend/src/data/UsernameHistory.ts | 12 +- backend/src/data/VCAlerts.ts | 8 +- backend/src/data/Webhooks.ts | 8 +- backend/src/data/apiAuditLogTypes.ts | 2 +- backend/src/data/cleanup/configs.ts | 6 +- backend/src/data/cleanup/messages.ts | 6 +- backend/src/data/cleanup/nicknames.ts | 6 +- backend/src/data/cleanup/usernames.ts | 6 +- backend/src/data/dataSource.ts | 4 +- backend/src/data/db.ts | 4 +- backend/src/data/entities/ApiAuditLogEntry.ts | 2 +- backend/src/data/entities/ApiLogin.ts | 2 +- .../data/entities/ApiPermissionAssignment.ts | 4 +- backend/src/data/entities/ApiUserInfo.ts | 4 +- backend/src/data/entities/Case.ts | 2 +- backend/src/data/entities/CaseNote.ts | 2 +- backend/src/data/entities/Config.ts | 2 +- .../src/data/entities/PhishermanCacheEntry.ts | 2 +- backend/src/data/entities/ScheduledPost.ts | 2 +- backend/src/data/entities/StarboardMessage.ts | 2 +- .../src/data/entities/StarboardReaction.ts | 2 +- backend/src/data/getChannelIdFromMessageId.ts | 4 +- .../data/loops/expiredArchiveDeletionLoop.ts | 4 +- .../loops/expiredMemberCacheDeletionLoop.ts | 4 +- backend/src/data/loops/expiringMutesLoop.ts | 8 +- .../src/data/loops/expiringTempbansLoop.ts | 8 +- .../src/data/loops/expiringVCAlertsLoop.ts | 8 +- .../src/data/loops/memberCacheDeletionLoop.ts | 4 +- backend/src/data/loops/phishermanLoops.ts | 4 +- .../src/data/loops/savedMessageCleanupLoop.ts | 4 +- .../src/data/loops/upcomingRemindersLoop.ts | 8 +- .../data/loops/upcomingScheduledPostsLoop.ts | 8 +- backend/src/env.ts | 2 +- backend/src/exportSchemas.ts | 4 +- backend/src/index.ts | 64 +++--- backend/src/migrateConfigsToDB.ts | 4 +- .../1600283341726-EncryptExistingMessages.ts | 2 +- .../1600285077890-EncryptArchives.ts | 2 +- backend/src/pluginUtils.ts | 6 +- .../plugins/AutoDelete/AutoDeletePlugin.ts | 16 +- backend/src/plugins/AutoDelete/info.ts | 2 +- backend/src/plugins/AutoDelete/types.ts | 8 +- .../util/addMessageToDeletionQueue.ts | 8 +- .../plugins/AutoDelete/util/deleteNextItem.ts | 16 +- .../AutoDelete/util/onMessageCreate.ts | 10 +- .../AutoDelete/util/onMessageDelete.ts | 6 +- .../AutoDelete/util/onMessageDeleteBulk.ts | 6 +- .../AutoDelete/util/scheduleNextDeletion.ts | 4 +- .../AutoReactions/AutoReactionsPlugin.ts | 16 +- .../commands/DisableAutoReactionsCmd.ts | 4 +- .../commands/NewAutoReactionsCmd.ts | 12 +- .../AutoReactions/events/AddReactionsEvt.ts | 14 +- backend/src/plugins/AutoReactions/info.ts | 4 +- backend/src/plugins/AutoReactions/types.ts | 10 +- backend/src/plugins/Automod/AutomodPlugin.ts | 60 +++--- .../src/plugins/Automod/actions/addRoles.ts | 16 +- .../plugins/Automod/actions/addToCounter.ts | 8 +- backend/src/plugins/Automod/actions/alert.ts | 18 +- .../plugins/Automod/actions/archiveThread.ts | 4 +- .../Automod/actions/availableActions.ts | 40 ++-- backend/src/plugins/Automod/actions/ban.ts | 12 +- .../plugins/Automod/actions/changeNickname.ts | 6 +- .../plugins/Automod/actions/changePerms.ts | 10 +- backend/src/plugins/Automod/actions/clean.ts | 6 +- .../plugins/Automod/actions/exampleAction.ts | 4 +- backend/src/plugins/Automod/actions/kick.ts | 12 +- backend/src/plugins/Automod/actions/log.ts | 6 +- backend/src/plugins/Automod/actions/mute.ts | 16 +- .../plugins/Automod/actions/pauseInvites.ts | 2 +- .../plugins/Automod/actions/removeRoles.ts | 16 +- backend/src/plugins/Automod/actions/reply.ts | 16 +- .../Automod/actions/setAntiraidLevel.ts | 6 +- .../src/plugins/Automod/actions/setCounter.ts | 10 +- .../plugins/Automod/actions/setSlowmode.ts | 6 +- .../plugins/Automod/actions/startThread.ts | 10 +- backend/src/plugins/Automod/actions/warn.ts | 12 +- .../Automod/commands/AntiraidClearCmd.ts | 4 +- .../Automod/commands/SetAntiraidCmd.ts | 6 +- .../Automod/commands/ViewAntiraidCmd.ts | 2 +- backend/src/plugins/Automod/constants.ts | 2 +- .../events/RunAutomodOnJoinLeaveEvt.ts | 6 +- .../events/RunAutomodOnMemberUpdate.ts | 4 +- .../events/runAutomodOnAntiraidLevel.ts | 4 +- .../events/runAutomodOnCounterTrigger.ts | 8 +- .../Automod/events/runAutomodOnMessage.ts | 12 +- .../Automod/events/runAutomodOnModAction.ts | 8 +- .../events/runAutomodOnThreadEvents.ts | 6 +- .../functions/addRecentActionsFromMessage.ts | 6 +- .../Automod/functions/applyCooldown.ts | 4 +- .../Automod/functions/checkCooldown.ts | 2 +- .../functions/clearOldNicknameChanges.ts | 4 +- .../functions/clearOldRecentActions.ts | 6 +- .../Automod/functions/clearOldRecentSpam.ts | 6 +- .../functions/clearRecentActionsForMessage.ts | 4 +- .../functions/createMessageSpamTrigger.ts | 18 +- .../Automod/functions/findRecentSpam.ts | 6 +- .../getMatchingMessageRecentActions.ts | 10 +- .../functions/getMatchingRecentActions.ts | 6 +- .../Automod/functions/getSpamIdentifier.ts | 2 +- .../functions/getTextMatchPartialSummary.ts | 6 +- .../Automod/functions/ignoredRoleChanges.ts | 4 +- .../matchMultipleTextTypesOnMessage.ts | 6 +- .../functions/resolveActionContactMethods.ts | 6 +- .../plugins/Automod/functions/runAutomod.ts | 16 +- .../Automod/functions/setAntiraidLevel.ts | 6 +- .../functions/sumRecentActionCounts.ts | 2 +- backend/src/plugins/Automod/helpers.ts | 4 +- backend/src/plugins/Automod/info.ts | 4 +- .../plugins/Automod/triggers/antiraidLevel.ts | 2 +- .../plugins/Automod/triggers/anyMessage.ts | 4 +- .../Automod/triggers/attachmentSpam.ts | 4 +- .../Automod/triggers/availableTriggers.ts | 70 +++---- backend/src/plugins/Automod/triggers/ban.ts | 2 +- .../plugins/Automod/triggers/characterSpam.ts | 4 +- .../Automod/triggers/counterTrigger.ts | 2 +- .../src/plugins/Automod/triggers/emojiSpam.ts | 4 +- .../Automod/triggers/exampleTrigger.ts | 2 +- backend/src/plugins/Automod/triggers/kick.ts | 2 +- .../src/plugins/Automod/triggers/lineSpam.ts | 4 +- .../src/plugins/Automod/triggers/linkSpam.ts | 4 +- .../Automod/triggers/matchAttachmentType.ts | 4 +- .../plugins/Automod/triggers/matchInvites.ts | 8 +- .../plugins/Automod/triggers/matchLinks.ts | 18 +- .../plugins/Automod/triggers/matchMimeType.ts | 4 +- .../plugins/Automod/triggers/matchRegex.ts | 16 +- .../plugins/Automod/triggers/matchWords.ts | 10 +- .../plugins/Automod/triggers/memberJoin.ts | 4 +- .../Automod/triggers/memberJoinSpam.ts | 12 +- .../plugins/Automod/triggers/memberLeave.ts | 2 +- .../plugins/Automod/triggers/mentionSpam.ts | 4 +- .../plugins/Automod/triggers/messageSpam.ts | 4 +- backend/src/plugins/Automod/triggers/mute.ts | 2 +- backend/src/plugins/Automod/triggers/note.ts | 2 +- .../src/plugins/Automod/triggers/roleAdded.ts | 6 +- .../plugins/Automod/triggers/roleRemoved.ts | 6 +- .../plugins/Automod/triggers/stickerSpam.ts | 4 +- .../plugins/Automod/triggers/threadArchive.ts | 4 +- .../plugins/Automod/triggers/threadCreate.ts | 2 +- .../Automod/triggers/threadCreateSpam.ts | 12 +- .../plugins/Automod/triggers/threadDelete.ts | 2 +- .../Automod/triggers/threadUnarchive.ts | 4 +- backend/src/plugins/Automod/triggers/unban.ts | 2 +- .../src/plugins/Automod/triggers/unmute.ts | 2 +- backend/src/plugins/Automod/triggers/warn.ts | 2 +- backend/src/plugins/Automod/types.ts | 30 +-- .../plugins/BotControl/BotControlPlugin.ts | 44 ++-- .../commands/AddDashboardUserCmd.ts | 10 +- .../commands/AddServerFromInviteCmd.ts | 10 +- .../BotControl/commands/AllowServerCmd.ts | 10 +- .../BotControl/commands/ChannelToServerCmd.ts | 6 +- .../BotControl/commands/DisallowServerCmd.ts | 8 +- .../BotControl/commands/EligibleCmd.ts | 8 +- .../BotControl/commands/LeaveServerCmd.ts | 6 +- .../commands/ListDashboardPermsCmd.ts | 10 +- .../commands/ListDashboardUsersCmd.ts | 6 +- .../BotControl/commands/ProfilerDataCmd.ts | 10 +- .../commands/RateLimitPerformanceCmd.ts | 8 +- .../commands/ReloadGlobalPluginsCmd.ts | 6 +- .../BotControl/commands/ReloadServerCmd.ts | 6 +- .../commands/RemoveDashboardUserCmd.ts | 8 +- .../BotControl/commands/RestPerformanceCmd.ts | 8 +- .../plugins/BotControl/commands/ServersCmd.ts | 8 +- .../BotControl/functions/isEligible.ts | 4 +- backend/src/plugins/BotControl/types.ts | 10 +- backend/src/plugins/Cases/CasesPlugin.ts | 30 +-- .../src/plugins/Cases/caseAbbreviations.ts | 2 +- backend/src/plugins/Cases/caseColors.ts | 2 +- backend/src/plugins/Cases/caseIcons.ts | 2 +- .../src/plugins/Cases/functions/createCase.ts | 10 +- .../plugins/Cases/functions/createCaseNote.ts | 10 +- .../plugins/Cases/functions/getCaseColor.ts | 6 +- .../plugins/Cases/functions/getCaseEmbed.ts | 14 +- .../plugins/Cases/functions/getCaseIcon.ts | 6 +- .../plugins/Cases/functions/getCaseSummary.ts | 12 +- .../functions/getCaseTypeAmountForUserId.ts | 4 +- .../Cases/functions/getRecentCasesByMod.ts | 4 +- .../Cases/functions/getTotalCasesByMod.ts | 4 +- .../Cases/functions/postToCaseLogChannel.ts | 16 +- .../plugins/Cases/functions/resolveCaseId.ts | 2 +- backend/src/plugins/Cases/info.ts | 4 +- backend/src/plugins/Cases/types.ts | 12 +- backend/src/plugins/Censor/CensorPlugin.ts | 14 +- backend/src/plugins/Censor/info.ts | 4 +- backend/src/plugins/Censor/types.ts | 8 +- .../plugins/Censor/util/applyFiltersToMsg.ts | 12 +- .../src/plugins/Censor/util/censorMessage.ts | 10 +- .../plugins/Censor/util/onMessageCreate.ts | 8 +- .../plugins/Censor/util/onMessageUpdate.ts | 8 +- .../ChannelArchiver/ChannelArchiverPlugin.ts | 8 +- .../commands/ArchiveChannelCmd.ts | 12 +- .../ChannelArchiver/rehostAttachment.ts | 2 +- backend/src/plugins/ChannelArchiver/types.ts | 2 +- backend/src/plugins/Common/CommonPlugin.ts | 10 +- .../src/plugins/Common/functions/getEmoji.ts | 2 +- backend/src/plugins/Common/info.ts | 4 +- .../CompanionChannelsPlugin.ts | 8 +- .../events/VoiceStateUpdateEvt.ts | 4 +- ...etCompanionChannelOptsForVoiceChannelId.ts | 2 +- .../functions/handleCompanionPermissions.ts | 12 +- backend/src/plugins/CompanionChannels/info.ts | 4 +- .../src/plugins/CompanionChannels/types.ts | 4 +- .../plugins/ContextMenus/ContextMenuPlugin.ts | 26 +-- .../src/plugins/ContextMenus/actions/ban.ts | 16 +- .../src/plugins/ContextMenus/actions/clean.ts | 8 +- .../src/plugins/ContextMenus/actions/mute.ts | 22 +- .../src/plugins/ContextMenus/actions/note.ts | 18 +- .../plugins/ContextMenus/actions/update.ts | 10 +- .../src/plugins/ContextMenus/actions/warn.ts | 16 +- .../ContextMenus/commands/BanUserCtxCmd.ts | 2 +- .../commands/CleanMessageCtxCmd.ts | 2 +- .../commands/ModMenuUserCtxCmd.ts | 28 +-- .../ContextMenus/commands/MuteUserCtxCmd.ts | 2 +- .../ContextMenus/commands/NoteUserCtxCmd.ts | 2 +- .../ContextMenus/commands/WarnUserCtxCmd.ts | 2 +- backend/src/plugins/ContextMenus/info.ts | 6 +- backend/src/plugins/ContextMenus/types.ts | 2 +- .../src/plugins/Counters/CountersPlugin.ts | 40 ++-- .../Counters/commands/AddCounterCmd.ts | 8 +- .../Counters/commands/CountersListCmd.ts | 6 +- .../commands/ResetAllCounterValuesCmd.ts | 8 +- .../Counters/commands/ResetCounterCmd.ts | 8 +- .../Counters/commands/SetCounterCmd.ts | 8 +- .../Counters/commands/ViewCounterCmd.ts | 6 +- .../Counters/functions/changeCounterValue.ts | 8 +- .../checkAllValuesForReverseTrigger.ts | 6 +- .../functions/checkAllValuesForTrigger.ts | 6 +- .../Counters/functions/checkCounterTrigger.ts | 6 +- .../functions/checkReverseCounterTrigger.ts | 6 +- .../Counters/functions/counterExists.ts | 2 +- .../Counters/functions/decayCounter.ts | 8 +- .../Counters/functions/emitCounterEvent.ts | 2 +- .../functions/getPrettyNameForCounter.ts | 2 +- .../getPrettyNameForCounterTrigger.ts | 2 +- .../Counters/functions/offCounterEvent.ts | 2 +- .../Counters/functions/onCounterEvent.ts | 2 +- .../functions/resetAllCounterValues.ts | 4 +- .../Counters/functions/setCounterValue.ts | 8 +- backend/src/plugins/Counters/info.ts | 4 +- backend/src/plugins/Counters/types.ts | 8 +- .../CustomEvents/CustomEventsPlugin.ts | 18 +- .../CustomEvents/actions/addRoleAction.ts | 12 +- .../CustomEvents/actions/createCaseAction.ts | 14 +- .../actions/makeRoleMentionableAction.ts | 8 +- .../actions/makeRoleUnmentionableAction.ts | 8 +- .../CustomEvents/actions/messageAction.ts | 10 +- .../actions/moveToVoiceChannelAction.ts | 12 +- .../actions/setChannelPermissionOverrides.ts | 8 +- .../CustomEvents/catchTemplateError.ts | 4 +- .../CustomEvents/functions/runEvent.ts | 20 +- backend/src/plugins/CustomEvents/info.ts | 2 +- backend/src/plugins/CustomEvents/types.ts | 18 +- .../GuildAccessMonitorPlugin.ts | 6 +- .../GuildConfigReloaderPlugin.ts | 6 +- .../functions/reloadChangedGuilds.ts | 4 +- .../src/plugins/GuildConfigReloader/info.ts | 2 +- .../src/plugins/GuildConfigReloader/types.ts | 2 +- .../GuildInfoSaver/GuildInfoSaverPlugin.ts | 8 +- backend/src/plugins/GuildInfoSaver/info.ts | 2 +- .../GuildMemberCachePlugin.ts | 22 +- .../events/cancelDeletionOnMemberJoin.ts | 2 +- .../events/removeMemberCacheOnMemberLeave.ts | 2 +- .../events/updateMemberCacheOnMemberUpdate.ts | 4 +- .../events/updateMemberCacheOnMessage.ts | 4 +- .../events/updateMemberCacheOnRoleChange.ts | 4 +- .../updateMemberCacheOnVoiceStateUpdate.ts | 4 +- .../functions/getCachedMemberData.ts | 4 +- .../functions/updateMemberCacheForMember.ts | 2 +- backend/src/plugins/GuildMemberCache/info.ts | 2 +- backend/src/plugins/GuildMemberCache/types.ts | 2 +- .../InternalPoster/InternalPosterPlugin.ts | 12 +- .../InternalPoster/functions/editMessage.ts | 4 +- .../getOrCreateWebhookClientForChannel.ts | 4 +- .../functions/getOrCreateWebhookForChannel.ts | 4 +- .../InternalPoster/functions/sendMessage.ts | 8 +- backend/src/plugins/InternalPoster/info.ts | 2 +- backend/src/plugins/InternalPoster/types.ts | 4 +- .../plugins/LocateUser/LocateUserPlugin.ts | 22 +- .../plugins/LocateUser/commands/FollowCmd.ts | 8 +- .../LocateUser/commands/ListFollowCmd.ts | 8 +- .../plugins/LocateUser/commands/WhereCmd.ts | 6 +- .../LocateUser/events/BanRemoveAlertsEvt.ts | 4 +- .../LocateUser/events/SendAlertsEvts.ts | 4 +- backend/src/plugins/LocateUser/info.ts | 6 +- backend/src/plugins/LocateUser/types.ts | 4 +- .../LocateUser/utils/clearExpiredAlert.ts | 6 +- .../LocateUser/utils/fillAlertsList.ts | 2 +- .../plugins/LocateUser/utils/moveMember.ts | 2 +- .../utils/removeUserIdFromActiveAlerts.ts | 2 +- .../plugins/LocateUser/utils/sendAlerts.ts | 8 +- .../src/plugins/LocateUser/utils/sendWhere.ts | 4 +- backend/src/plugins/Logs/LogsPlugin.ts | 194 +++++++++--------- .../Logs/events/LogsChannelModifyEvts.ts | 12 +- .../events/LogsEmojiAndStickerModifyEvts.ts | 18 +- .../plugins/Logs/events/LogsGuildBanEvts.ts | 12 +- .../Logs/events/LogsGuildMemberAddEvt.ts | 4 +- .../Logs/events/LogsGuildMemberRemoveEvt.ts | 4 +- .../events/LogsGuildMemberRoleChangeEvt.ts | 8 +- .../plugins/Logs/events/LogsRoleModifyEvts.ts | 12 +- .../events/LogsStageInstanceModifyEvts.ts | 12 +- .../Logs/events/LogsThreadModifyEvts.ts | 12 +- .../plugins/Logs/events/LogsUserUpdateEvts.ts | 4 +- .../Logs/events/LogsVoiceChannelEvts.ts | 8 +- backend/src/plugins/Logs/info.ts | 4 +- .../Logs/logFunctions/logAutomodAction.ts | 10 +- .../plugins/Logs/logFunctions/logBotAlert.ts | 8 +- .../Logs/logFunctions/logCaseCreate.ts | 10 +- .../Logs/logFunctions/logCaseDelete.ts | 12 +- .../Logs/logFunctions/logCaseUpdate.ts | 10 +- .../plugins/Logs/logFunctions/logCensor.ts | 16 +- .../Logs/logFunctions/logChannelCreate.ts | 12 +- .../Logs/logFunctions/logChannelDelete.ts | 12 +- .../Logs/logFunctions/logChannelUpdate.ts | 12 +- .../src/plugins/Logs/logFunctions/logClean.ts | 12 +- .../plugins/Logs/logFunctions/logDmFailed.ts | 12 +- .../Logs/logFunctions/logEmojiCreate.ts | 10 +- .../Logs/logFunctions/logEmojiDelete.ts | 10 +- .../Logs/logFunctions/logEmojiUpdate.ts | 10 +- .../plugins/Logs/logFunctions/logMassBan.ts | 10 +- .../plugins/Logs/logFunctions/logMassMute.ts | 10 +- .../plugins/Logs/logFunctions/logMassUnban.ts | 10 +- .../plugins/Logs/logFunctions/logMemberBan.ts | 12 +- .../Logs/logFunctions/logMemberForceban.ts | 10 +- .../Logs/logFunctions/logMemberJoin.ts | 10 +- .../logMemberJoinWithPriorRecords.ts | 10 +- .../Logs/logFunctions/logMemberKick.ts | 12 +- .../Logs/logFunctions/logMemberLeave.ts | 10 +- .../Logs/logFunctions/logMemberMute.ts | 12 +- .../Logs/logFunctions/logMemberMuteExpired.ts | 12 +- .../Logs/logFunctions/logMemberMuteRejoin.ts | 10 +- .../Logs/logFunctions/logMemberNickChange.ts | 10 +- .../Logs/logFunctions/logMemberNote.ts | 12 +- .../Logs/logFunctions/logMemberRestore.ts | 10 +- .../Logs/logFunctions/logMemberRoleAdd.ts | 12 +- .../Logs/logFunctions/logMemberRoleChanges.ts | 12 +- .../Logs/logFunctions/logMemberRoleRemove.ts | 12 +- .../Logs/logFunctions/logMemberTimedBan.ts | 12 +- .../Logs/logFunctions/logMemberTimedMute.ts | 12 +- .../Logs/logFunctions/logMemberTimedUnban.ts | 12 +- .../Logs/logFunctions/logMemberTimedUnmute.ts | 12 +- .../Logs/logFunctions/logMemberUnban.ts | 12 +- .../Logs/logFunctions/logMemberUnmute.ts | 12 +- .../Logs/logFunctions/logMemberWarn.ts | 10 +- .../Logs/logFunctions/logMessageDelete.ts | 18 +- .../Logs/logFunctions/logMessageDeleteAuto.ts | 16 +- .../Logs/logFunctions/logMessageDeleteBare.ts | 12 +- .../Logs/logFunctions/logMessageDeleteBulk.ts | 12 +- .../Logs/logFunctions/logMessageEdit.ts | 16 +- .../logFunctions/logMessageSpamDetected.ts | 12 +- .../Logs/logFunctions/logOtherSpamDetected.ts | 10 +- .../logFunctions/logPostedScheduledMessage.ts | 12 +- .../Logs/logFunctions/logRepeatedMessage.ts | 12 +- .../Logs/logFunctions/logRoleCreate.ts | 10 +- .../Logs/logFunctions/logRoleDelete.ts | 10 +- .../Logs/logFunctions/logRoleUpdate.ts | 10 +- .../Logs/logFunctions/logScheduledMessage.ts | 12 +- .../logScheduledRepeatedMessage.ts | 12 +- .../Logs/logFunctions/logSetAntiraidAuto.ts | 8 +- .../Logs/logFunctions/logSetAntiraidUser.ts | 10 +- .../logFunctions/logStageInstanceCreate.ts | 12 +- .../logFunctions/logStageInstanceDelete.ts | 12 +- .../logFunctions/logStageInstanceUpdate.ts | 12 +- .../Logs/logFunctions/logStickerCreate.ts | 10 +- .../Logs/logFunctions/logStickerDelete.ts | 10 +- .../Logs/logFunctions/logStickerUpdate.ts | 10 +- .../Logs/logFunctions/logThreadCreate.ts | 12 +- .../Logs/logFunctions/logThreadDelete.ts | 12 +- .../Logs/logFunctions/logThreadUpdate.ts | 12 +- .../logVoiceChannelForceDisconnect.ts | 12 +- .../logFunctions/logVoiceChannelForceMove.ts | 12 +- .../Logs/logFunctions/logVoiceChannelJoin.ts | 12 +- .../Logs/logFunctions/logVoiceChannelLeave.ts | 12 +- .../Logs/logFunctions/logVoiceChannelMove.ts | 12 +- backend/src/plugins/Logs/types.ts | 18 +- .../src/plugins/Logs/util/getLogMessage.ts | 16 +- backend/src/plugins/Logs/util/isLogIgnored.ts | 4 +- backend/src/plugins/Logs/util/log.ts | 16 +- .../src/plugins/Logs/util/onMessageDelete.ts | 14 +- .../plugins/Logs/util/onMessageDeleteBulk.ts | 12 +- .../src/plugins/Logs/util/onMessageUpdate.ts | 8 +- .../MessageSaver/MessageSaverPlugin.ts | 12 +- .../MessageSaver/commands/SaveMessagesToDB.ts | 6 +- .../MessageSaver/commands/SavePinsToDB.ts | 6 +- .../MessageSaver/events/SaveMessagesEvts.ts | 2 +- backend/src/plugins/MessageSaver/info.ts | 2 +- .../plugins/MessageSaver/saveMessagesToDB.ts | 2 +- backend/src/plugins/MessageSaver/types.ts | 4 +- .../plugins/ModActions/ModActionsPlugin.ts | 134 ++++++------ .../commands/addcase/AddCaseMsgCmd.ts | 12 +- .../commands/addcase/AddCaseSlashCmd.ts | 14 +- .../commands/addcase/actualAddCaseCmd.ts | 18 +- .../ModActions/commands/ban/BanMsgCmd.ts | 12 +- .../ModActions/commands/ban/BanSlashCmd.ts | 14 +- .../ModActions/commands/ban/actualBanCmd.ts | 26 +-- .../ModActions/commands/case/CaseMsgCmd.ts | 6 +- .../ModActions/commands/case/CaseSlashCmd.ts | 4 +- .../ModActions/commands/case/actualCaseCmd.ts | 6 +- .../commands/cases/CasesModMsgCmd.ts | 6 +- .../commands/cases/CasesSlashCmd.ts | 4 +- .../commands/cases/CasesUserMsgCmd.ts | 8 +- .../commands/cases/actualCasesCmd.ts | 18 +- .../commands/deletecase/DeleteCaseMsgCmd.ts | 8 +- .../commands/deletecase/DeleteCaseSlashCmd.ts | 4 +- .../deletecase/actualDeleteCaseCmd.ts | 14 +- .../commands/forceban/ForceBanMsgCmd.ts | 12 +- .../commands/forceban/ForceBanSlashCmd.ts | 12 +- .../commands/forceban/actualForceBanCmd.ts | 18 +- .../commands/forcemute/ForceMuteMsgCmd.ts | 12 +- .../commands/forcemute/ForceMuteSlashCmd.ts | 14 +- .../commands/forceunmute/ForceUnmuteMsgCmd.ts | 10 +- .../forceunmute/ForceUnmuteSlashCmd.ts | 12 +- .../commands/hidecase/HideCaseMsgCmd.ts | 6 +- .../commands/hidecase/HideCaseSlashCmd.ts | 4 +- .../commands/hidecase/actualHideCaseCmd.ts | 2 +- .../ModActions/commands/kick/KickMsgCmd.ts | 10 +- .../ModActions/commands/kick/KickSlashCmd.ts | 14 +- .../ModActions/commands/kick/actualKickCmd.ts | 18 +- .../commands/massban/MassBanMsgCmd.ts | 8 +- .../commands/massban/MassBanSlashCmd.ts | 8 +- .../commands/massban/actualMassBanCmd.ts | 22 +- .../commands/massmute/MassMuteMsgCmd.ts | 8 +- .../commands/massmute/MassMuteSlashCmd.ts | 8 +- .../commands/massmute/actualMassMuteCmd.ts | 16 +- .../commands/massunban/MassUnbanMsgCmd.ts | 8 +- .../commands/massunban/MassUnbanSlashCmd.ts | 8 +- .../commands/massunban/actualMassUnbanCmd.ts | 22 +- .../ModActions/commands/mute/MuteMsgCmd.ts | 16 +- .../ModActions/commands/mute/MuteSlashCmd.ts | 18 +- .../ModActions/commands/mute/actualMuteCmd.ts | 16 +- .../ModActions/commands/note/NoteMsgCmd.ts | 8 +- .../ModActions/commands/note/NoteSlashCmd.ts | 8 +- .../ModActions/commands/note/actualNoteCmd.ts | 14 +- .../ModActions/commands/unban/UnbanMsgCmd.ts | 10 +- .../commands/unban/UnbanSlashCmd.ts | 12 +- .../commands/unban/actualUnbanCmd.ts | 20 +- .../commands/unhidecase/UnhideCaseMsgCmd.ts | 6 +- .../commands/unhidecase/UnhideCaseSlashCmd.ts | 4 +- .../unhidecase/actualUnhideCaseCmd.ts | 2 +- .../commands/unmute/UnmuteMsgCmd.ts | 16 +- .../commands/unmute/UnmuteSlashCmd.ts | 18 +- .../commands/unmute/actualUnmuteCmd.ts | 10 +- .../commands/update/UpdateMsgCmd.ts | 6 +- .../commands/update/UpdateSlashCmd.ts | 8 +- .../ModActions/commands/warn/WarnMsgCmd.ts | 14 +- .../ModActions/commands/warn/WarnSlashCmd.ts | 16 +- .../ModActions/commands/warn/actualWarnCmd.ts | 16 +- .../ModActions/events/AuditLogEvents.ts | 8 +- .../events/CreateBanCaseOnManualBanEvt.ts | 20 +- .../events/CreateKickCaseOnManualKickEvt.ts | 20 +- .../events/CreateUnbanCaseOnManualUnbanEvt.ts | 18 +- .../events/PostAlertOnMemberJoinEvt.ts | 8 +- .../functions/attachmentLinkReaction.ts | 2 +- .../plugins/ModActions/functions/banUserId.ts | 24 +-- .../functions/clearIgnoredEvents.ts | 2 +- .../ModActions/functions/clearTempban.ts | 20 +- .../functions/formatReasonForAttachments.ts | 4 +- .../functions/getDefaultContactMethods.ts | 4 +- .../ModActions/functions/hasModActionPerm.ts | 2 +- .../ModActions/functions/ignoreEvent.ts | 6 +- .../plugins/ModActions/functions/isBanned.ts | 8 +- .../ModActions/functions/isEventIgnored.ts | 2 +- .../ModActions/functions/kickMember.ts | 20 +- .../functions/offModActionsEvent.ts | 2 +- .../ModActions/functions/onModActionsEvent.ts | 2 +- .../functions/readContactMethodsFromArgs.ts | 2 +- .../ModActions/functions/updateCase.ts | 14 +- .../ModActions/functions/warnMember.ts | 18 +- backend/src/plugins/ModActions/info.ts | 6 +- backend/src/plugins/ModActions/types.ts | 18 +- backend/src/plugins/Mutes/MutesPlugin.ts | 46 ++--- .../Mutes/commands/ClearBannedMutesCmd.ts | 2 +- .../plugins/Mutes/commands/ClearMutesCmd.ts | 4 +- .../commands/ClearMutesWithoutRoleCmd.ts | 4 +- .../src/plugins/Mutes/commands/MutesCmd.ts | 10 +- .../events/ClearActiveMuteOnMemberBanEvt.ts | 2 +- .../events/ClearActiveMuteOnRoleRemovalEvt.ts | 4 +- .../events/ReapplyActiveMuteOnJoinEvt.ts | 10 +- .../Mutes/events/RegisterManualTimeoutsEvt.ts | 6 +- .../src/plugins/Mutes/functions/clearMute.ts | 16 +- .../Mutes/functions/getDefaultMuteType.ts | 4 +- .../Mutes/functions/getTimeoutExpiryTime.ts | 2 +- .../Mutes/functions/memberHasMutedRole.ts | 2 +- .../src/plugins/Mutes/functions/muteUser.ts | 34 +-- .../plugins/Mutes/functions/offMutesEvent.ts | 2 +- .../plugins/Mutes/functions/onMutesEvent.ts | 2 +- .../Mutes/functions/renewTimeoutMute.ts | 8 +- .../src/plugins/Mutes/functions/unmuteUser.ts | 26 +-- backend/src/plugins/Mutes/info.ts | 4 +- backend/src/plugins/Mutes/types.ts | 18 +- .../plugins/NameHistory/NameHistoryPlugin.ts | 12 +- .../plugins/NameHistory/commands/NamesCmd.ts | 12 +- .../NameHistory/events/UpdateNameEvts.ts | 4 +- backend/src/plugins/NameHistory/info.ts | 4 +- backend/src/plugins/NameHistory/types.ts | 8 +- .../src/plugins/NameHistory/updateNickname.ts | 2 +- backend/src/plugins/Persist/PersistPlugin.ts | 14 +- .../src/plugins/Persist/events/LoadDataEvt.ts | 16 +- .../plugins/Persist/events/StoreDataEvt.ts | 4 +- backend/src/plugins/Persist/info.ts | 6 +- backend/src/plugins/Persist/types.ts | 6 +- .../plugins/Phisherman/PhishermanPlugin.ts | 8 +- .../Phisherman/functions/getDomainInfo.ts | 6 +- backend/src/plugins/Phisherman/info.ts | 6 +- .../PingableRoles/PingableRolesPlugin.ts | 10 +- .../commands/PingableRoleDisableCmd.ts | 4 +- .../commands/PingableRoleEnableCmd.ts | 4 +- .../events/ChangePingableEvts.ts | 8 +- backend/src/plugins/PingableRoles/info.ts | 4 +- backend/src/plugins/PingableRoles/types.ts | 6 +- .../utils/disablePingableRoles.ts | 4 +- .../utils/enablePingableRoles.ts | 4 +- .../utils/getPingableRolesForChannel.ts | 4 +- backend/src/plugins/Post/PostPlugin.ts | 32 +-- backend/src/plugins/Post/commands/EditCmd.ts | 6 +- .../src/plugins/Post/commands/EditEmbedCmd.ts | 12 +- backend/src/plugins/Post/commands/PostCmd.ts | 6 +- .../src/plugins/Post/commands/PostEmbedCmd.ts | 14 +- .../Post/commands/ScheduledPostsDeleteCmd.ts | 8 +- .../Post/commands/ScheduledPostsListCmd.ts | 6 +- .../Post/commands/ScheduledPostsShowCmd.ts | 8 +- backend/src/plugins/Post/info.ts | 4 +- backend/src/plugins/Post/types.ts | 8 +- .../src/plugins/Post/util/actualPostCmd.ts | 14 +- .../plugins/Post/util/parseScheduleTime.ts | 4 +- backend/src/plugins/Post/util/postMessage.ts | 6 +- .../plugins/Post/util/postScheduledPost.ts | 14 +- .../ReactionRoles/ReactionRolesPlugin.ts | 22 +- .../commands/ClearReactionRolesCmd.ts | 6 +- .../commands/InitReactionRolesCmd.ts | 10 +- .../commands/RefreshReactionRolesCmd.ts | 6 +- .../events/AddReactionRoleEvt.ts | 6 +- .../ReactionRoles/events/MessageDeletedEvt.ts | 2 +- backend/src/plugins/ReactionRoles/info.ts | 4 +- backend/src/plugins/ReactionRoles/types.ts | 8 +- .../util/addMemberPendingRoleChange.ts | 8 +- .../applyReactionRoleReactionsToMessage.ts | 8 +- .../ReactionRoles/util/autoRefreshLoop.ts | 4 +- .../util/refreshReactionRoles.ts | 4 +- .../ReactionRoles/util/runAutoRefresh.ts | 4 +- .../src/plugins/Reminders/RemindersPlugin.ts | 18 +- .../plugins/Reminders/commands/RemindCmd.ts | 10 +- .../Reminders/commands/RemindersCmd.ts | 6 +- .../Reminders/commands/RemindersDeleteCmd.ts | 8 +- .../Reminders/functions/postReminder.ts | 6 +- backend/src/plugins/Reminders/info.ts | 4 +- backend/src/plugins/Reminders/types.ts | 4 +- .../plugins/RoleButtons/RoleButtonsPlugin.ts | 16 +- .../RoleButtons/commands/resetButtons.ts | 6 +- .../RoleButtons/events/buttonInteraction.ts | 10 +- .../functions/applyAllRoleButtons.ts | 4 +- .../RoleButtons/functions/applyRoleButtons.ts | 8 +- .../functions/createButtonComponents.ts | 6 +- .../functions/getAllRolesInButtons.ts | 2 +- backend/src/plugins/RoleButtons/info.ts | 6 +- backend/src/plugins/RoleButtons/types.ts | 10 +- .../plugins/RoleManager/RoleManagerPlugin.ts | 18 +- .../RoleManager/functions/addPriorityRole.ts | 6 +- .../plugins/RoleManager/functions/addRole.ts | 4 +- .../functions/removePriorityRole.ts | 6 +- .../RoleManager/functions/removeRole.ts | 4 +- .../functions/runRoleAssignmentLoop.ts | 6 +- backend/src/plugins/RoleManager/info.ts | 2 +- backend/src/plugins/RoleManager/types.ts | 2 +- backend/src/plugins/Roles/RolesPlugin.ts | 18 +- .../src/plugins/Roles/commands/AddRoleCmd.ts | 12 +- .../plugins/Roles/commands/MassAddRoleCmd.ts | 14 +- .../Roles/commands/MassRemoveRoleCmd.ts | 12 +- .../plugins/Roles/commands/RemoveRoleCmd.ts | 12 +- backend/src/plugins/Roles/info.ts | 6 +- backend/src/plugins/Roles/types.ts | 4 +- .../SelfGrantableRolesPlugin.ts | 10 +- .../SelfGrantableRoles/commands/RoleAddCmd.ts | 14 +- .../commands/RoleHelpCmd.ts | 6 +- .../commands/RoleRemoveCmd.ts | 14 +- .../src/plugins/SelfGrantableRoles/info.ts | 6 +- .../src/plugins/SelfGrantableRoles/types.ts | 4 +- .../util/findMatchingRoles.ts | 2 +- .../util/getApplyingEntries.ts | 2 +- .../src/plugins/Slowmode/SlowmodePlugin.ts | 28 +-- .../Slowmode/commands/SlowmodeClearCmd.ts | 14 +- .../Slowmode/commands/SlowmodeDisableCmd.ts | 6 +- .../Slowmode/commands/SlowmodeGetCmd.ts | 4 +- .../Slowmode/commands/SlowmodeListCmd.ts | 4 +- .../Slowmode/commands/SlowmodeSetCmd.ts | 16 +- backend/src/plugins/Slowmode/info.ts | 4 +- backend/src/plugins/Slowmode/types.ts | 10 +- .../Slowmode/util/actualDisableSlowmodeCmd.ts | 10 +- .../Slowmode/util/applyBotSlowmodeToUserId.ts | 10 +- .../util/clearBotSlowmodeFromUserId.ts | 4 +- .../Slowmode/util/clearExpiredSlowmodes.ts | 10 +- .../util/disableBotSlowmodeForChannel.ts | 4 +- .../plugins/Slowmode/util/onMessageCreate.ts | 22 +- backend/src/plugins/Spam/SpamPlugin.ts | 18 +- .../src/plugins/Spam/events/SpamVoiceEvt.ts | 4 +- backend/src/plugins/Spam/info.ts | 6 +- backend/src/plugins/Spam/types.ts | 10 +- .../src/plugins/Spam/util/addRecentAction.ts | 2 +- .../Spam/util/clearOldRecentActions.ts | 2 +- .../Spam/util/clearRecentUserActions.ts | 2 +- .../plugins/Spam/util/getRecentActionCount.ts | 2 +- .../src/plugins/Spam/util/getRecentActions.ts | 2 +- .../Spam/util/logAndDetectMessageSpam.ts | 32 +-- .../Spam/util/logAndDetectOtherSpam.ts | 20 +- backend/src/plugins/Spam/util/logCensor.ts | 6 +- .../src/plugins/Spam/util/onMessageCreate.ts | 8 +- .../src/plugins/Spam/util/saveSpamArchives.ts | 6 +- .../src/plugins/Starboard/StarboardPlugin.ts | 18 +- .../Starboard/commands/MigratePinsCmd.ts | 6 +- .../events/StarboardReactionAddEvt.ts | 10 +- .../events/StarboardReactionRemoveEvts.ts | 4 +- backend/src/plugins/Starboard/info.ts | 6 +- backend/src/plugins/Starboard/types.ts | 10 +- .../util/createStarboardEmbedFromMessage.ts | 2 +- .../createStarboardPseudoFooterForMessage.ts | 4 +- .../plugins/Starboard/util/onMessageDelete.ts | 8 +- .../util/removeMessageFromStarboard.ts | 6 +- .../removeMessageFromStarboardMessages.ts | 2 +- .../Starboard/util/saveMessageToStarboard.ts | 6 +- .../util/updateStarboardMessageStarCount.ts | 4 +- backend/src/plugins/Tags/TagsPlugin.ts | 38 ++-- .../src/plugins/Tags/commands/TagCreateCmd.ts | 6 +- .../src/plugins/Tags/commands/TagDeleteCmd.ts | 4 +- .../src/plugins/Tags/commands/TagEvalCmd.ts | 12 +- .../src/plugins/Tags/commands/TagListCmd.ts | 6 +- .../src/plugins/Tags/commands/TagSourceCmd.ts | 6 +- backend/src/plugins/Tags/info.ts | 8 +- backend/src/plugins/Tags/templateFunctions.ts | 2 +- backend/src/plugins/Tags/types.ts | 12 +- .../src/plugins/Tags/util/findTagByName.ts | 2 +- .../Tags/util/matchAndRenderTagFromString.ts | 6 +- .../src/plugins/Tags/util/onMessageCreate.ts | 14 +- .../src/plugins/Tags/util/onMessageDelete.ts | 2 +- .../src/plugins/Tags/util/renderTagBody.ts | 8 +- .../plugins/Tags/util/renderTagFromString.ts | 14 +- .../plugins/TimeAndDate/TimeAndDatePlugin.ts | 26 +-- .../TimeAndDate/commands/ResetTimezoneCmd.ts | 4 +- .../TimeAndDate/commands/SetTimezoneCmd.ts | 8 +- .../TimeAndDate/commands/ViewTimezoneCmd.ts | 4 +- .../TimeAndDate/functions/getDateFormat.ts | 4 +- .../TimeAndDate/functions/getGuildTz.ts | 2 +- .../TimeAndDate/functions/getMemberTz.ts | 4 +- .../TimeAndDate/functions/inGuildTz.ts | 4 +- .../TimeAndDate/functions/inMemberTz.ts | 4 +- backend/src/plugins/TimeAndDate/info.ts | 6 +- backend/src/plugins/TimeAndDate/types.ts | 10 +- .../UsernameSaver/UsernameSaverPlugin.ts | 8 +- .../events/UpdateUsernameEvts.ts | 4 +- backend/src/plugins/UsernameSaver/info.ts | 2 +- backend/src/plugins/UsernameSaver/types.ts | 4 +- .../plugins/UsernameSaver/updateUsername.ts | 4 +- backend/src/plugins/Utility/UtilityPlugin.ts | 86 ++++---- .../src/plugins/Utility/commands/AboutCmd.ts | 10 +- .../src/plugins/Utility/commands/AvatarCmd.ts | 6 +- .../plugins/Utility/commands/BanSearchCmd.ts | 6 +- .../Utility/commands/ChannelInfoCmd.ts | 6 +- .../src/plugins/Utility/commands/CleanCmd.ts | 20 +- .../plugins/Utility/commands/ContextCmd.ts | 8 +- .../plugins/Utility/commands/EmojiInfoCmd.ts | 8 +- .../src/plugins/Utility/commands/HelpCmd.ts | 6 +- .../src/plugins/Utility/commands/InfoCmd.ts | 30 +-- .../plugins/Utility/commands/InviteInfoCmd.ts | 8 +- .../src/plugins/Utility/commands/JumboCmd.ts | 6 +- .../src/plugins/Utility/commands/LevelCmd.ts | 6 +- .../Utility/commands/MessageInfoCmd.ts | 8 +- .../plugins/Utility/commands/NicknameCmd.ts | 8 +- .../Utility/commands/NicknameResetCmd.ts | 8 +- .../src/plugins/Utility/commands/PingCmd.ts | 4 +- .../Utility/commands/ReloadGuildCmd.ts | 4 +- .../plugins/Utility/commands/RoleInfoCmd.ts | 6 +- .../src/plugins/Utility/commands/RolesCmd.ts | 8 +- .../src/plugins/Utility/commands/SearchCmd.ts | 6 +- .../plugins/Utility/commands/ServerInfoCmd.ts | 6 +- .../Utility/commands/SnowflakeInfoCmd.ts | 6 +- .../src/plugins/Utility/commands/SourceCmd.ts | 8 +- .../plugins/Utility/commands/UserInfoCmd.ts | 6 +- .../Utility/commands/VcdisconnectCmd.ts | 10 +- .../src/plugins/Utility/commands/VcmoveCmd.ts | 10 +- .../Utility/events/AutoJoinThreadEvt.ts | 2 +- .../Utility/functions/getChannelInfoEmbed.ts | 4 +- .../Utility/functions/getEmojiInfoEmbed.ts | 4 +- .../Utility/functions/getGuildPreview.ts | 2 +- .../Utility/functions/getInviteInfoEmbed.ts | 6 +- .../Utility/functions/getMessageInfoEmbed.ts | 4 +- .../Utility/functions/getRoleInfoEmbed.ts | 4 +- .../Utility/functions/getServerInfoEmbed.ts | 8 +- .../functions/getSnowflakeInfoEmbed.ts | 4 +- .../Utility/functions/getUserInfoEmbed.ts | 6 +- .../Utility/functions/hasPermission.ts | 2 +- backend/src/plugins/Utility/info.ts | 4 +- backend/src/plugins/Utility/refreshMembers.ts | 2 +- backend/src/plugins/Utility/search.ts | 20 +- backend/src/plugins/Utility/types.ts | 14 +- .../WelcomeMessage/WelcomeMessagePlugin.ts | 8 +- .../events/SendWelcomeMessageEvt.ts | 12 +- backend/src/plugins/WelcomeMessage/info.ts | 4 +- backend/src/plugins/WelcomeMessage/types.ts | 2 +- backend/src/plugins/availablePlugins.ts | 80 ++++---- backend/src/plugins/pluginInfo.ts | 142 ++++++------- backend/src/regExpRunners.ts | 2 +- backend/src/restCallStats.ts | 2 +- backend/src/staff.ts | 2 +- backend/src/templateFormatter.test.ts | 2 +- backend/src/templateFormatter.ts | 2 +- backend/src/threadsSignalFix.ts | 2 +- backend/src/types.ts | 2 +- backend/src/utils.test.ts | 4 +- backend/src/utils.ts | 12 +- backend/src/utils/MessageBuffer.ts | 4 +- backend/src/utils/async.ts | 2 +- backend/src/utils/canAssignRole.ts | 4 +- backend/src/utils/canReadChannel.ts | 4 +- backend/src/utils/createPaginatedMessage.ts | 6 +- backend/src/utils/crypt.test.ts | 2 +- backend/src/utils/crypt.ts | 6 +- backend/src/utils/cryptHelpers.ts | 2 +- backend/src/utils/easyProfiler.ts | 2 +- .../src/utils/findMatchingAuditLogEntry.ts | 2 +- backend/src/utils/getChunkedEmbedFields.ts | 2 +- .../src/utils/getMissingChannelPermissions.ts | 2 +- backend/src/utils/loadYamlSafely.ts | 2 +- backend/src/utils/lockNameHelpers.ts | 2 +- backend/src/utils/mergeRegexes.ts | 2 +- backend/src/utils/messageIsEmpty.ts | 2 +- backend/src/utils/missingPermissionError.ts | 2 +- backend/src/utils/normalizeText.test.ts | 2 +- backend/src/utils/parseCustomId.ts | 2 +- backend/src/utils/permissionNames.ts | 2 +- backend/src/utils/resolveChannelIds.ts | 6 +- backend/src/utils/resolveMessageTarget.ts | 4 +- backend/src/utils/sendDM.ts | 4 +- backend/src/utils/snowflakeToTimestamp.ts | 2 +- backend/src/utils/templateSafeObjects.ts | 8 +- .../src/utils/validateNoObjectAliases.test.ts | 2 +- backend/src/utils/waitForInteraction.ts | 4 +- backend/src/utils/zColor.ts | 4 +- backend/src/utils/zValidTimezone.ts | 2 +- backend/src/validateActiveConfigs.ts | 10 +- 798 files changed, 3633 insertions(+), 3633 deletions(-) diff --git a/backend/src/Queue.ts b/backend/src/Queue.ts index a8505411..8d67ad7f 100644 --- a/backend/src/Queue.ts +++ b/backend/src/Queue.ts @@ -1,4 +1,4 @@ -import { SECONDS } from "./utils"; +import { SECONDS } from "./utils.js"; type InternalQueueFn = () => Promise; type AnyFn = (...args: any[]) => any; diff --git a/backend/src/QueuedEventEmitter.ts b/backend/src/QueuedEventEmitter.ts index 2402c491..42935f30 100644 --- a/backend/src/QueuedEventEmitter.ts +++ b/backend/src/QueuedEventEmitter.ts @@ -1,4 +1,4 @@ -import { Queue } from "./Queue"; +import { Queue } from "./Queue.js"; type Listener = (...args: any[]) => void; diff --git a/backend/src/RegExpRunner.ts b/backend/src/RegExpRunner.ts index 1ac5f47c..6d835a84 100644 --- a/backend/src/RegExpRunner.ts +++ b/backend/src/RegExpRunner.ts @@ -1,7 +1,7 @@ import { EventEmitter } from "events"; import { CooldownManager } from "knub"; import { RegExpWorker, TimeoutError } from "regexp-worker"; -import { MINUTES, SECONDS } from "./utils"; +import { MINUTES, SECONDS } from "./utils.js"; import Timeout = NodeJS.Timeout; const isTimeoutError = (a): a is TimeoutError => { diff --git a/backend/src/api/archives.ts b/backend/src/api/archives.ts index 9494d194..77da999d 100644 --- a/backend/src/api/archives.ts +++ b/backend/src/api/archives.ts @@ -1,7 +1,7 @@ import express, { Request, Response } from "express"; import moment from "moment-timezone"; -import { GuildArchives } from "../data/GuildArchives"; -import { notFound } from "./responses"; +import { GuildArchives } from "../data/GuildArchives.js"; +import { notFound } from "./responses.js"; export function initArchives(router: express.Router) { const archives = new GuildArchives(null); diff --git a/backend/src/api/auth.ts b/backend/src/api/auth.ts index 543dab0f..b034215b 100644 --- a/backend/src/api/auth.ts +++ b/backend/src/api/auth.ts @@ -4,12 +4,12 @@ import pick from "lodash.pick"; import passport from "passport"; import { Strategy as CustomStrategy } from "passport-custom"; import OAuth2Strategy from "passport-oauth2"; -import { ApiLogins } from "../data/ApiLogins"; -import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments"; -import { ApiUserInfo } from "../data/ApiUserInfo"; -import { ApiUserInfoData } from "../data/entities/ApiUserInfo"; -import { env } from "../env"; -import { ok } from "./responses"; +import { ApiLogins } from "../data/ApiLogins.js"; +import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments.js"; +import { ApiUserInfo } from "../data/ApiUserInfo.js"; +import { ApiUserInfoData } from "../data/entities/ApiUserInfo.js"; +import { env } from "../env.js"; +import { ok } from "./responses.js"; interface IPassportApiUser { apiKey: string; diff --git a/backend/src/api/docs.ts b/backend/src/api/docs.ts index 8b742b5c..ff0723a2 100644 --- a/backend/src/api/docs.ts +++ b/backend/src/api/docs.ts @@ -1,9 +1,9 @@ import express from "express"; import z from "zod"; -import { guildPlugins } from "../plugins/availablePlugins"; -import { guildPluginInfo } from "../plugins/pluginInfo"; -import { indentLines } from "../utils"; -import { notFound } from "./responses"; +import { guildPlugins } from "../plugins/availablePlugins.js"; +import { guildPluginInfo } from "../plugins/pluginInfo.js"; +import { indentLines } from "../utils.js"; +import { notFound } from "./responses.js"; function isZodObject(schema: z.ZodTypeAny): schema is z.ZodObject { return schema._def.typeName === "ZodObject"; diff --git a/backend/src/api/guilds.ts b/backend/src/api/guilds.ts index 29192c40..acc1f222 100644 --- a/backend/src/api/guilds.ts +++ b/backend/src/api/guilds.ts @@ -1,20 +1,20 @@ -import { ApiPermissions } from "@zeppelinbot/shared"; +import { ApiPermissions } from "@zeppelinbot/shared.js"; import express, { Request, Response } from "express"; import { YAMLException } from "js-yaml"; import moment from "moment-timezone"; -import { Queue } from "../Queue"; -import { validateGuildConfig } from "../configValidator"; -import { AllowedGuilds } from "../data/AllowedGuilds"; -import { ApiAuditLog } from "../data/ApiAuditLog"; -import { ApiPermissionAssignments, ApiPermissionTypes } from "../data/ApiPermissionAssignments"; -import { Configs } from "../data/Configs"; -import { AuditLogEventTypes } from "../data/apiAuditLogTypes"; -import { isSnowflake } from "../utils"; -import { loadYamlSafely } from "../utils/loadYamlSafely"; -import { ObjectAliasError } from "../utils/validateNoObjectAliases"; -import { apiTokenAuthHandlers } from "./auth"; -import { hasGuildPermission, requireGuildPermission } from "./permissions"; -import { clientError, ok, serverError, unauthorized } from "./responses"; +import { Queue } from "../Queue.js"; +import { validateGuildConfig } from "../configValidator.js"; +import { AllowedGuilds } from "../data/AllowedGuilds.js"; +import { ApiAuditLog } from "../data/ApiAuditLog.js"; +import { ApiPermissionAssignments, ApiPermissionTypes } from "../data/ApiPermissionAssignments.js"; +import { Configs } from "../data/Configs.js"; +import { AuditLogEventTypes } from "../data/apiAuditLogTypes.js"; +import { isSnowflake } from "../utils.js"; +import { loadYamlSafely } from "../utils/loadYamlSafely.js"; +import { ObjectAliasError } from "../utils/validateNoObjectAliases.js"; +import { apiTokenAuthHandlers } from "./auth.js"; +import { hasGuildPermission, requireGuildPermission } from "./permissions.js"; +import { clientError, ok, serverError, unauthorized } from "./responses.js"; const apiPermissionAssignments = new ApiPermissionAssignments(); const auditLog = new ApiAuditLog(); diff --git a/backend/src/api/guilds/importExport.ts b/backend/src/api/guilds/importExport.ts index 9a4a8710..05cacc2a 100644 --- a/backend/src/api/guilds/importExport.ts +++ b/backend/src/api/guilds/importExport.ts @@ -1,13 +1,13 @@ -import { ApiPermissions } from "@zeppelinbot/shared"; +import { ApiPermissions } from "@zeppelinbot/shared.js"; import express, { Request, Response } from "express"; import moment from "moment-timezone"; import { z } from "zod"; -import { GuildCases } from "../../data/GuildCases"; -import { Case } from "../../data/entities/Case"; -import { MINUTES } from "../../utils"; -import { requireGuildPermission } from "../permissions"; -import { rateLimit } from "../rateLimits"; -import { clientError, ok } from "../responses"; +import { GuildCases } from "../../data/GuildCases.js"; +import { Case } from "../../data/entities/Case.js"; +import { MINUTES } from "../../utils.js"; +import { requireGuildPermission } from "../permissions.js"; +import { rateLimit } from "../rateLimits.js"; +import { clientError, ok } from "../responses.js"; const caseHandlingModeSchema = z.union([ z.literal("replace"), diff --git a/backend/src/api/guilds/index.ts b/backend/src/api/guilds/index.ts index 3da1384a..a6436abc 100644 --- a/backend/src/api/guilds/index.ts +++ b/backend/src/api/guilds/index.ts @@ -1,7 +1,7 @@ import express from "express"; -import { apiTokenAuthHandlers } from "../auth"; -import { initGuildsImportExportAPI } from "./importExport"; -import { initGuildsMiscAPI } from "./misc"; +import { apiTokenAuthHandlers } from "../auth.js"; +import { initGuildsImportExportAPI } from "./importExport.js"; +import { initGuildsMiscAPI } from "./misc.js"; export function initGuildsAPI(router: express.Router) { const guildRouter = express.Router(); diff --git a/backend/src/api/guilds/misc.ts b/backend/src/api/guilds/misc.ts index 38835227..43bfa6e9 100644 --- a/backend/src/api/guilds/misc.ts +++ b/backend/src/api/guilds/misc.ts @@ -1,19 +1,19 @@ -import { ApiPermissions } from "@zeppelinbot/shared"; +import { ApiPermissions } from "@zeppelinbot/shared.js"; import express, { Request, Response } from "express"; import { YAMLException } from "js-yaml"; import moment from "moment-timezone"; -import { Queue } from "../../Queue"; -import { validateGuildConfig } from "../../configValidator"; -import { AllowedGuilds } from "../../data/AllowedGuilds"; -import { ApiAuditLog } from "../../data/ApiAuditLog"; -import { ApiPermissionAssignments, ApiPermissionTypes } from "../../data/ApiPermissionAssignments"; -import { Configs } from "../../data/Configs"; -import { AuditLogEventTypes } from "../../data/apiAuditLogTypes"; -import { isSnowflake } from "../../utils"; -import { loadYamlSafely } from "../../utils/loadYamlSafely"; -import { ObjectAliasError } from "../../utils/validateNoObjectAliases"; -import { hasGuildPermission, requireGuildPermission } from "../permissions"; -import { clientError, ok, serverError, unauthorized } from "../responses"; +import { Queue } from "../../Queue.js"; +import { validateGuildConfig } from "../../configValidator.js"; +import { AllowedGuilds } from "../../data/AllowedGuilds.js"; +import { ApiAuditLog } from "../../data/ApiAuditLog.js"; +import { ApiPermissionAssignments, ApiPermissionTypes } from "../../data/ApiPermissionAssignments.js"; +import { Configs } from "../../data/Configs.js"; +import { AuditLogEventTypes } from "../../data/apiAuditLogTypes.js"; +import { isSnowflake } from "../../utils.js"; +import { loadYamlSafely } from "../../utils/loadYamlSafely.js"; +import { ObjectAliasError } from "../../utils/validateNoObjectAliases.js"; +import { hasGuildPermission, requireGuildPermission } from "../permissions.js"; +import { clientError, ok, serverError, unauthorized } from "../responses.js"; const apiPermissionAssignments = new ApiPermissionAssignments(); const auditLog = new ApiAuditLog(); diff --git a/backend/src/api/index.ts b/backend/src/api/index.ts index 503b717e..b0f921e0 100644 --- a/backend/src/api/index.ts +++ b/backend/src/api/index.ts @@ -1,10 +1,10 @@ // KEEP THIS AS FIRST IMPORT // See comment in module for details -import "../threadsSignalFix"; +import "../threadsSignalFix.js"; -import { connect } from "../data/db"; -import { env } from "../env"; -import { setIsAPI } from "../globals"; +import { connect } from "../data/db.js"; +import { env } from "../env.js"; +import { setIsAPI } from "../globals.js"; if (!env.KEY) { // tslint:disable-next-line:no-console diff --git a/backend/src/api/permissions.ts b/backend/src/api/permissions.ts index 74675398..a5fdb432 100644 --- a/backend/src/api/permissions.ts +++ b/backend/src/api/permissions.ts @@ -1,8 +1,8 @@ -import { ApiPermissions, hasPermission, permissionArrToSet } from "@zeppelinbot/shared"; +import { ApiPermissions, hasPermission, permissionArrToSet } from "@zeppelinbot/shared.js"; import { Request, Response } from "express"; -import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments"; -import { isStaff } from "../staff"; -import { unauthorized } from "./responses"; +import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments.js"; +import { isStaff } from "../staff.js"; +import { unauthorized } from "./responses.js"; const apiPermissionAssignments = new ApiPermissionAssignments(); diff --git a/backend/src/api/rateLimits.ts b/backend/src/api/rateLimits.ts index 90b344d5..50d85738 100644 --- a/backend/src/api/rateLimits.ts +++ b/backend/src/api/rateLimits.ts @@ -1,5 +1,5 @@ import { Request, Response } from "express"; -import { error } from "./responses"; +import { error } from "./responses.js"; const lastRequestsByKey: Map = new Map(); diff --git a/backend/src/api/staff.ts b/backend/src/api/staff.ts index 08f0dc09..fa2d644f 100644 --- a/backend/src/api/staff.ts +++ b/backend/src/api/staff.ts @@ -1,6 +1,6 @@ import express, { Request, Response } from "express"; -import { isStaff } from "../staff"; -import { apiTokenAuthHandlers } from "./auth"; +import { isStaff } from "../staff.js"; +import { apiTokenAuthHandlers } from "./auth.js"; export function initStaff(app: express.Express) { const staffRouter = express.Router(); diff --git a/backend/src/api/start.ts b/backend/src/api/start.ts index e009e393..b259d22a 100644 --- a/backend/src/api/start.ts +++ b/backend/src/api/start.ts @@ -2,13 +2,13 @@ import cors from "cors"; import express from "express"; import multer from "multer"; import { TokenError } from "passport-oauth2"; -import { env } from "../env"; -import { initArchives } from "./archives"; -import { initAuth } from "./auth"; -import { initDocs } from "./docs"; -import { initGuildsAPI } from "./guilds/index"; -import { clientError, error, notFound } from "./responses"; -import { startBackgroundTasks } from "./tasks"; +import { env } from "../env.js"; +import { initArchives } from "./archives.js"; +import { initAuth } from "./auth.js"; +import { initDocs } from "./docs.js"; +import { initGuildsAPI } from "./guilds/index.js"; +import { clientError, error, notFound } from "./responses.js"; +import { startBackgroundTasks } from "./tasks.js"; const apiPathPrefix = env.API_PATH_PREFIX || (env.NODE_ENV === "development" ? "/api" : ""); diff --git a/backend/src/api/tasks.ts b/backend/src/api/tasks.ts index 6edf218d..fc58c8a3 100644 --- a/backend/src/api/tasks.ts +++ b/backend/src/api/tasks.ts @@ -1,5 +1,5 @@ -import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments"; -import { MINUTES } from "../utils"; +import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments.js"; +import { MINUTES } from "../utils.js"; export function startBackgroundTasks() { // Clear expired API permissions every minute diff --git a/backend/src/commandTypes.ts b/backend/src/commandTypes.ts index 9ace5312..ca231a5d 100644 --- a/backend/src/commandTypes.ts +++ b/backend/src/commandTypes.ts @@ -24,9 +24,9 @@ import { resolveUserId, roleMentionRegex, UnknownUser, -} from "./utils"; -import { isValidTimezone } from "./utils/isValidTimezone"; -import { MessageTarget, resolveMessageTarget } from "./utils/resolveMessageTarget"; +} from "./utils.js"; +import { isValidTimezone } from "./utils/isValidTimezone.js"; +import { MessageTarget, resolveMessageTarget } from "./utils/resolveMessageTarget.js"; export const commandTypes = { ...messageCommandBaseTypeConverters, diff --git a/backend/src/configValidator.ts b/backend/src/configValidator.ts index 55d83ccf..1978a154 100644 --- a/backend/src/configValidator.ts +++ b/backend/src/configValidator.ts @@ -1,8 +1,8 @@ import { BaseConfig, ConfigValidationError, GuildPluginBlueprint, PluginConfigManager } from "knub"; import { ZodError } from "zod"; -import { guildPlugins } from "./plugins/availablePlugins"; -import { zZeppelinGuildConfig } from "./types"; -import { formatZodIssue } from "./utils/formatZodIssue"; +import { guildPlugins } from "./plugins/availablePlugins.js"; +import { zZeppelinGuildConfig } from "./types.js"; +import { formatZodIssue } from "./utils/formatZodIssue.js"; const pluginNameToPlugin = new Map>(); for (const plugin of guildPlugins) { diff --git a/backend/src/data/AllowedGuilds.ts b/backend/src/data/AllowedGuilds.ts index f942c59a..2224d66a 100644 --- a/backend/src/data/AllowedGuilds.ts +++ b/backend/src/data/AllowedGuilds.ts @@ -1,10 +1,10 @@ import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { DBDateFormat } from "../utils"; -import { ApiPermissionTypes } from "./ApiPermissionAssignments"; -import { BaseRepository } from "./BaseRepository"; -import { dataSource } from "./dataSource"; -import { AllowedGuild } from "./entities/AllowedGuild"; +import { DBDateFormat } from "../utils.js"; +import { ApiPermissionTypes } from "./ApiPermissionAssignments.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { dataSource } from "./dataSource.js"; +import { AllowedGuild } from "./entities/AllowedGuild.js"; export class AllowedGuilds extends BaseRepository { private allowedGuilds: Repository; diff --git a/backend/src/data/ApiAuditLog.ts b/backend/src/data/ApiAuditLog.ts index 98ecbe5f..d7d13e38 100644 --- a/backend/src/data/ApiAuditLog.ts +++ b/backend/src/data/ApiAuditLog.ts @@ -1,8 +1,8 @@ import { Repository } from "typeorm/index"; -import { BaseRepository } from "./BaseRepository"; -import { AuditLogEventData, AuditLogEventType } from "./apiAuditLogTypes"; -import { dataSource } from "./dataSource"; -import { ApiAuditLogEntry } from "./entities/ApiAuditLogEntry"; +import { BaseRepository } from "./BaseRepository.js"; +import { AuditLogEventData, AuditLogEventType } from "./apiAuditLogTypes.js"; +import { dataSource } from "./dataSource.js"; +import { ApiAuditLogEntry } from "./entities/ApiAuditLogEntry.js"; export class ApiAuditLog extends BaseRepository { private auditLog: Repository>; diff --git a/backend/src/data/ApiLogins.ts b/backend/src/data/ApiLogins.ts index 94ffac7d..f2b0c9c5 100644 --- a/backend/src/data/ApiLogins.ts +++ b/backend/src/data/ApiLogins.ts @@ -3,10 +3,10 @@ import moment from "moment-timezone"; import { Repository } from "typeorm"; // tslint:disable-next-line:no-submodule-imports import { v4 as uuidv4 } from "uuid"; -import { DAYS, DBDateFormat } from "../utils"; -import { BaseRepository } from "./BaseRepository"; -import { dataSource } from "./dataSource"; -import { ApiLogin } from "./entities/ApiLogin"; +import { DAYS, DBDateFormat } from "../utils.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { dataSource } from "./dataSource.js"; +import { ApiLogin } from "./entities/ApiLogin.js"; const LOGIN_EXPIRY_TIME = 1 * DAYS; diff --git a/backend/src/data/ApiPermissionAssignments.ts b/backend/src/data/ApiPermissionAssignments.ts index b52fe01f..4bd8824d 100644 --- a/backend/src/data/ApiPermissionAssignments.ts +++ b/backend/src/data/ApiPermissionAssignments.ts @@ -1,10 +1,10 @@ -import { ApiPermissions } from "@zeppelinbot/shared"; +import { ApiPermissions } from "@zeppelinbot/shared.js"; import { Repository } from "typeorm"; -import { ApiAuditLog } from "./ApiAuditLog"; -import { BaseRepository } from "./BaseRepository"; -import { AuditLogEventTypes } from "./apiAuditLogTypes"; -import { dataSource } from "./dataSource"; -import { ApiPermissionAssignment } from "./entities/ApiPermissionAssignment"; +import { ApiAuditLog } from "./ApiAuditLog.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { AuditLogEventTypes } from "./apiAuditLogTypes.js"; +import { dataSource } from "./dataSource.js"; +import { ApiPermissionAssignment } from "./entities/ApiPermissionAssignment.js"; export enum ApiPermissionTypes { User = "USER", diff --git a/backend/src/data/ApiUserInfo.ts b/backend/src/data/ApiUserInfo.ts index 1dbc9d45..f9c25c6d 100644 --- a/backend/src/data/ApiUserInfo.ts +++ b/backend/src/data/ApiUserInfo.ts @@ -1,9 +1,9 @@ import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { DBDateFormat } from "../utils"; -import { BaseRepository } from "./BaseRepository"; -import { dataSource } from "./dataSource"; -import { ApiUserInfoData, ApiUserInfo as ApiUserInfoEntity } from "./entities/ApiUserInfo"; +import { DBDateFormat } from "../utils.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { dataSource } from "./dataSource.js"; +import { ApiUserInfoData, ApiUserInfo as ApiUserInfoEntity } from "./entities/ApiUserInfo.js"; export class ApiUserInfo extends BaseRepository { private apiUserInfo: Repository; diff --git a/backend/src/data/Archives.ts b/backend/src/data/Archives.ts index 0978d861..753341eb 100644 --- a/backend/src/data/Archives.ts +++ b/backend/src/data/Archives.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseRepository } from "./BaseRepository"; -import { dataSource } from "./dataSource"; -import { ArchiveEntry } from "./entities/ArchiveEntry"; +import { BaseRepository } from "./BaseRepository.js"; +import { dataSource } from "./dataSource.js"; +import { ArchiveEntry } from "./entities/ArchiveEntry.js"; export class Archives extends BaseRepository { protected archives: Repository; diff --git a/backend/src/data/BaseGuildRepository.ts b/backend/src/data/BaseGuildRepository.ts index 4ee2d757..6d424628 100644 --- a/backend/src/data/BaseGuildRepository.ts +++ b/backend/src/data/BaseGuildRepository.ts @@ -1,4 +1,4 @@ -import { BaseRepository } from "./BaseRepository"; +import { BaseRepository } from "./BaseRepository.js"; export class BaseGuildRepository extends BaseRepository { private static guildInstances: Map; diff --git a/backend/src/data/BaseRepository.ts b/backend/src/data/BaseRepository.ts index dcba6184..97226875 100644 --- a/backend/src/data/BaseRepository.ts +++ b/backend/src/data/BaseRepository.ts @@ -1,4 +1,4 @@ -import { asyncMap } from "../utils/async"; +import { asyncMap } from "../utils/async.js"; export class BaseRepository { private nextRelations: string[]; diff --git a/backend/src/data/Configs.ts b/backend/src/data/Configs.ts index bc702b5e..d98d4710 100644 --- a/backend/src/data/Configs.ts +++ b/backend/src/data/Configs.ts @@ -1,10 +1,10 @@ import { Repository } from "typeorm"; -import { isAPI } from "../globals"; -import { HOURS, SECONDS } from "../utils"; -import { BaseRepository } from "./BaseRepository"; -import { cleanupConfigs } from "./cleanup/configs"; -import { dataSource } from "./dataSource"; -import { Config } from "./entities/Config"; +import { isAPI } from "../globals.js"; +import { HOURS, SECONDS } from "../utils.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { cleanupConfigs } from "./cleanup/configs.js"; +import { dataSource } from "./dataSource.js"; +import { Config } from "./entities/Config.js"; const CLEANUP_INTERVAL = 1 * HOURS; diff --git a/backend/src/data/GuildAntiraidLevels.ts b/backend/src/data/GuildAntiraidLevels.ts index 0d4eb30c..bd0c5e66 100644 --- a/backend/src/data/GuildAntiraidLevels.ts +++ b/backend/src/data/GuildAntiraidLevels.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { AntiraidLevel } from "./entities/AntiraidLevel"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { AntiraidLevel } from "./entities/AntiraidLevel.js"; export class GuildAntiraidLevels extends BaseGuildRepository { protected antiraidLevels: Repository; diff --git a/backend/src/data/GuildArchives.ts b/backend/src/data/GuildArchives.ts index 4d74ccef..1e133007 100644 --- a/backend/src/data/GuildArchives.ts +++ b/backend/src/data/GuildArchives.ts @@ -1,15 +1,15 @@ import { Guild, Snowflake } from "discord.js"; import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { TemplateSafeValueContainer, renderTemplate } from "../templateFormatter"; -import { renderUsername, trimLines } from "../utils"; -import { decrypt, encrypt } from "../utils/crypt"; -import { isDefaultSticker } from "../utils/isDefaultSticker"; -import { channelToTemplateSafeChannel, guildToTemplateSafeGuild } from "../utils/templateSafeObjects"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { ArchiveEntry } from "./entities/ArchiveEntry"; -import { SavedMessage } from "./entities/SavedMessage"; +import { TemplateSafeValueContainer, renderTemplate } from "../templateFormatter.js"; +import { renderUsername, trimLines } from "../utils.js"; +import { decrypt, encrypt } from "../utils/crypt.js"; +import { isDefaultSticker } from "../utils/isDefaultSticker.js"; +import { channelToTemplateSafeChannel, guildToTemplateSafeGuild } from "../utils/templateSafeObjects.js"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { ArchiveEntry } from "./entities/ArchiveEntry.js"; +import { SavedMessage } from "./entities/SavedMessage.js"; const DEFAULT_EXPIRY_DAYS = 30; diff --git a/backend/src/data/GuildAutoReactions.ts b/backend/src/data/GuildAutoReactions.ts index fcab1a90..39f45c45 100644 --- a/backend/src/data/GuildAutoReactions.ts +++ b/backend/src/data/GuildAutoReactions.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { AutoReaction } from "./entities/AutoReaction"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { AutoReaction } from "./entities/AutoReaction.js"; export class GuildAutoReactions extends BaseGuildRepository { private autoReactions: Repository; diff --git a/backend/src/data/GuildButtonRoles.ts b/backend/src/data/GuildButtonRoles.ts index d493d424..63ead42c 100644 --- a/backend/src/data/GuildButtonRoles.ts +++ b/backend/src/data/GuildButtonRoles.ts @@ -1,6 +1,6 @@ import { getRepository, Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { ButtonRole } from "./entities/ButtonRole"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { ButtonRole } from "./entities/ButtonRole.js"; export class GuildButtonRoles extends BaseGuildRepository { private buttonRoles: Repository; diff --git a/backend/src/data/GuildCases.ts b/backend/src/data/GuildCases.ts index 4137fbee..5d6c1ba0 100644 --- a/backend/src/data/GuildCases.ts +++ b/backend/src/data/GuildCases.ts @@ -1,12 +1,12 @@ import { In, InsertResult, Repository } from "typeorm"; import { FindOptionsWhere } from "typeorm/find-options/FindOptionsWhere"; -import { Queue } from "../Queue"; -import { chunkArray } from "../utils"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { CaseTypes } from "./CaseTypes"; -import { dataSource } from "./dataSource"; -import { Case } from "./entities/Case"; -import { CaseNote } from "./entities/CaseNote"; +import { Queue } from "../Queue.js"; +import { chunkArray } from "../utils.js"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { CaseTypes } from "./CaseTypes.js"; +import { dataSource } from "./dataSource.js"; +import { Case } from "./entities/Case.js"; +import { CaseNote } from "./entities/CaseNote.js"; export class GuildCases extends BaseGuildRepository { private cases: Repository; diff --git a/backend/src/data/GuildContextMenuLinks.ts b/backend/src/data/GuildContextMenuLinks.ts index d82b2dd0..9bbffd0e 100644 --- a/backend/src/data/GuildContextMenuLinks.ts +++ b/backend/src/data/GuildContextMenuLinks.ts @@ -1,7 +1,7 @@ import { DeleteResult, InsertResult, Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { ContextMenuLink } from "./entities/ContextMenuLink"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { ContextMenuLink } from "./entities/ContextMenuLink.js"; export class GuildContextMenuLinks extends BaseGuildRepository { private contextLinks: Repository; diff --git a/backend/src/data/GuildCounters.ts b/backend/src/data/GuildCounters.ts index 18c9b5e6..3313e3c8 100644 --- a/backend/src/data/GuildCounters.ts +++ b/backend/src/data/GuildCounters.ts @@ -1,13 +1,13 @@ import moment from "moment-timezone"; import { FindOptionsWhere, In, IsNull, Not, Repository } from "typeorm"; -import { Queue } from "../Queue"; -import { DAYS, DBDateFormat, HOURS, MINUTES } from "../utils"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { Counter } from "./entities/Counter"; -import { CounterTrigger, TriggerComparisonOp, isValidCounterComparisonOp } from "./entities/CounterTrigger"; -import { CounterTriggerState } from "./entities/CounterTriggerState"; -import { CounterValue } from "./entities/CounterValue"; +import { Queue } from "../Queue.js"; +import { DAYS, DBDateFormat, HOURS, MINUTES } from "../utils.js"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { Counter } from "./entities/Counter.js"; +import { CounterTrigger, TriggerComparisonOp, isValidCounterComparisonOp } from "./entities/CounterTrigger.js"; +import { CounterTriggerState } from "./entities/CounterTriggerState.js"; +import { CounterValue } from "./entities/CounterValue.js"; const DELETE_UNUSED_COUNTERS_AFTER = 1 * DAYS; const DELETE_UNUSED_COUNTER_TRIGGERS_AFTER = 1 * DAYS; diff --git a/backend/src/data/GuildEvents.ts b/backend/src/data/GuildEvents.ts index 290b459d..efc7834b 100644 --- a/backend/src/data/GuildEvents.ts +++ b/backend/src/data/GuildEvents.ts @@ -1,8 +1,8 @@ -import { Mute } from "./entities/Mute"; -import { Reminder } from "./entities/Reminder"; -import { ScheduledPost } from "./entities/ScheduledPost"; -import { Tempban } from "./entities/Tempban"; -import { VCAlert } from "./entities/VCAlert"; +import { Mute } from "./entities/Mute.js"; +import { Reminder } from "./entities/Reminder.js"; +import { ScheduledPost } from "./entities/ScheduledPost.js"; +import { Tempban } from "./entities/Tempban.js"; +import { VCAlert } from "./entities/VCAlert.js"; interface GuildEventArgs extends Record { expiredMute: [Mute]; diff --git a/backend/src/data/GuildLogs.ts b/backend/src/data/GuildLogs.ts index 5f7dc4ed..dc4837ee 100644 --- a/backend/src/data/GuildLogs.ts +++ b/backend/src/data/GuildLogs.ts @@ -1,5 +1,5 @@ import * as events from "events"; -import { LogType } from "./LogType"; +import { LogType } from "./LogType.js"; // Use the same instance for the same guild, even if a new instance is created const guildInstances: Map = new Map(); diff --git a/backend/src/data/GuildMemberCache.ts b/backend/src/data/GuildMemberCache.ts index d64c532c..4a309ca5 100644 --- a/backend/src/data/GuildMemberCache.ts +++ b/backend/src/data/GuildMemberCache.ts @@ -1,10 +1,10 @@ import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { Blocker } from "../Blocker"; -import { DBDateFormat, MINUTES } from "../utils"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { MemberCacheItem } from "./entities/MemberCacheItem"; +import { Blocker } from "../Blocker.js"; +import { DBDateFormat, MINUTES } from "../utils.js"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { MemberCacheItem } from "./entities/MemberCacheItem.js"; const SAVE_PENDING_BLOCKER_KEY = "save-pending" as const; diff --git a/backend/src/data/GuildMemberTimezones.ts b/backend/src/data/GuildMemberTimezones.ts index 68e1660b..43214b1b 100644 --- a/backend/src/data/GuildMemberTimezones.ts +++ b/backend/src/data/GuildMemberTimezones.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm/index"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { MemberTimezone } from "./entities/MemberTimezone"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { MemberTimezone } from "./entities/MemberTimezone.js"; export class GuildMemberTimezones extends BaseGuildRepository { protected memberTimezones: Repository; diff --git a/backend/src/data/GuildMutes.ts b/backend/src/data/GuildMutes.ts index 54e7e6c0..3b9c54e3 100644 --- a/backend/src/data/GuildMutes.ts +++ b/backend/src/data/GuildMutes.ts @@ -1,10 +1,10 @@ import moment from "moment-timezone"; import { Brackets, Repository } from "typeorm"; -import { DBDateFormat } from "../utils"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { MuteTypes } from "./MuteTypes"; -import { dataSource } from "./dataSource"; -import { Mute } from "./entities/Mute"; +import { DBDateFormat } from "../utils.js"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { MuteTypes } from "./MuteTypes.js"; +import { dataSource } from "./dataSource.js"; +import { Mute } from "./entities/Mute.js"; export type AddMuteParams = { userId: Mute["user_id"]; diff --git a/backend/src/data/GuildNicknameHistory.ts b/backend/src/data/GuildNicknameHistory.ts index 03f9d838..84986cda 100644 --- a/backend/src/data/GuildNicknameHistory.ts +++ b/backend/src/data/GuildNicknameHistory.ts @@ -1,10 +1,10 @@ import { In, Repository } from "typeorm"; -import { isAPI } from "../globals"; -import { MINUTES, SECONDS } from "../utils"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { cleanupNicknames } from "./cleanup/nicknames"; -import { dataSource } from "./dataSource"; -import { NicknameHistoryEntry } from "./entities/NicknameHistoryEntry"; +import { isAPI } from "../globals.js"; +import { MINUTES, SECONDS } from "../utils.js"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { cleanupNicknames } from "./cleanup/nicknames.js"; +import { dataSource } from "./dataSource.js"; +import { NicknameHistoryEntry } from "./entities/NicknameHistoryEntry.js"; const CLEANUP_INTERVAL = 5 * MINUTES; diff --git a/backend/src/data/GuildPersistedData.ts b/backend/src/data/GuildPersistedData.ts index f0947cd1..3a37e4b5 100644 --- a/backend/src/data/GuildPersistedData.ts +++ b/backend/src/data/GuildPersistedData.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { PersistedData } from "./entities/PersistedData"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { PersistedData } from "./entities/PersistedData.js"; export class GuildPersistedData extends BaseGuildRepository { private persistedData: Repository; diff --git a/backend/src/data/GuildPingableRoles.ts b/backend/src/data/GuildPingableRoles.ts index 2f229f54..48f0b89e 100644 --- a/backend/src/data/GuildPingableRoles.ts +++ b/backend/src/data/GuildPingableRoles.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { PingableRole } from "./entities/PingableRole"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { PingableRole } from "./entities/PingableRole.js"; export class GuildPingableRoles extends BaseGuildRepository { private pingableRoles: Repository; diff --git a/backend/src/data/GuildReactionRoles.ts b/backend/src/data/GuildReactionRoles.ts index c1a01ca0..16d61245 100644 --- a/backend/src/data/GuildReactionRoles.ts +++ b/backend/src/data/GuildReactionRoles.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { ReactionRole } from "./entities/ReactionRole"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { ReactionRole } from "./entities/ReactionRole.js"; export class GuildReactionRoles extends BaseGuildRepository { private reactionRoles: Repository; diff --git a/backend/src/data/GuildReminders.ts b/backend/src/data/GuildReminders.ts index 31c7babd..e853908c 100644 --- a/backend/src/data/GuildReminders.ts +++ b/backend/src/data/GuildReminders.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { Reminder } from "./entities/Reminder"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { Reminder } from "./entities/Reminder.js"; export class GuildReminders extends BaseGuildRepository { private reminders: Repository; diff --git a/backend/src/data/GuildRoleButtons.ts b/backend/src/data/GuildRoleButtons.ts index c12dd2e0..190fae9b 100644 --- a/backend/src/data/GuildRoleButtons.ts +++ b/backend/src/data/GuildRoleButtons.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { RoleButtonsItem } from "./entities/RoleButtonsItem"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { RoleButtonsItem } from "./entities/RoleButtonsItem.js"; export class GuildRoleButtons extends BaseGuildRepository { private roleButtons: Repository; diff --git a/backend/src/data/GuildRoleQueue.ts b/backend/src/data/GuildRoleQueue.ts index 61172237..d01bab79 100644 --- a/backend/src/data/GuildRoleQueue.ts +++ b/backend/src/data/GuildRoleQueue.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { RoleQueueItem } from "./entities/RoleQueueItem"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { RoleQueueItem } from "./entities/RoleQueueItem.js"; export class GuildRoleQueue extends BaseGuildRepository { private roleQueue: Repository; diff --git a/backend/src/data/GuildSavedMessages.ts b/backend/src/data/GuildSavedMessages.ts index 39eb4b7c..3edc2810 100644 --- a/backend/src/data/GuildSavedMessages.ts +++ b/backend/src/data/GuildSavedMessages.ts @@ -1,14 +1,14 @@ import { GuildChannel, Message } from "discord.js"; import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { QueuedEventEmitter } from "../QueuedEventEmitter"; -import { noop } from "../utils"; -import { asyncMap } from "../utils/async"; -import { decryptJson, encryptJson } from "../utils/cryptHelpers"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { buildEntity } from "./buildEntity"; -import { dataSource } from "./dataSource"; -import { ISavedMessageData, SavedMessage } from "./entities/SavedMessage"; +import { QueuedEventEmitter } from "../QueuedEventEmitter.js"; +import { noop } from "../utils.js"; +import { asyncMap } from "../utils/async.js"; +import { decryptJson, encryptJson } from "../utils/cryptHelpers.js"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { buildEntity } from "./buildEntity.js"; +import { dataSource } from "./dataSource.js"; +import { ISavedMessageData, SavedMessage } from "./entities/SavedMessage.js"; export class GuildSavedMessages extends BaseGuildRepository { private messages: Repository; diff --git a/backend/src/data/GuildScheduledPosts.ts b/backend/src/data/GuildScheduledPosts.ts index eb122861..3614114b 100644 --- a/backend/src/data/GuildScheduledPosts.ts +++ b/backend/src/data/GuildScheduledPosts.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { ScheduledPost } from "./entities/ScheduledPost"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { ScheduledPost } from "./entities/ScheduledPost.js"; export class GuildScheduledPosts extends BaseGuildRepository { private scheduledPosts: Repository; diff --git a/backend/src/data/GuildSlowmodes.ts b/backend/src/data/GuildSlowmodes.ts index ee92a3f5..4ad4cd82 100644 --- a/backend/src/data/GuildSlowmodes.ts +++ b/backend/src/data/GuildSlowmodes.ts @@ -1,9 +1,9 @@ import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { SlowmodeChannel } from "./entities/SlowmodeChannel"; -import { SlowmodeUser } from "./entities/SlowmodeUser"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { SlowmodeChannel } from "./entities/SlowmodeChannel.js"; +import { SlowmodeUser } from "./entities/SlowmodeUser.js"; export class GuildSlowmodes extends BaseGuildRepository { private slowmodeChannels: Repository; diff --git a/backend/src/data/GuildStarboardMessages.ts b/backend/src/data/GuildStarboardMessages.ts index d5e56870..52dfc2ad 100644 --- a/backend/src/data/GuildStarboardMessages.ts +++ b/backend/src/data/GuildStarboardMessages.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { StarboardMessage } from "./entities/StarboardMessage"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { StarboardMessage } from "./entities/StarboardMessage.js"; export class GuildStarboardMessages extends BaseGuildRepository { private allStarboardMessages: Repository; diff --git a/backend/src/data/GuildStarboardReactions.ts b/backend/src/data/GuildStarboardReactions.ts index 9c74d6dd..090cd6a5 100644 --- a/backend/src/data/GuildStarboardReactions.ts +++ b/backend/src/data/GuildStarboardReactions.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { StarboardReaction } from "./entities/StarboardReaction"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { StarboardReaction } from "./entities/StarboardReaction.js"; export class GuildStarboardReactions extends BaseGuildRepository { private allStarboardReactions: Repository; diff --git a/backend/src/data/GuildStats.ts b/backend/src/data/GuildStats.ts index 9a3c0e9a..061be7b0 100644 --- a/backend/src/data/GuildStats.ts +++ b/backend/src/data/GuildStats.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { StatValue } from "./entities/StatValue"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { StatValue } from "./entities/StatValue.js"; export class GuildStats extends BaseGuildRepository { private stats: Repository; diff --git a/backend/src/data/GuildTags.ts b/backend/src/data/GuildTags.ts index 004c4dbe..b8c28bef 100644 --- a/backend/src/data/GuildTags.ts +++ b/backend/src/data/GuildTags.ts @@ -1,8 +1,8 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { Tag } from "./entities/Tag"; -import { TagResponse } from "./entities/TagResponse"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { Tag } from "./entities/Tag.js"; +import { TagResponse } from "./entities/TagResponse.js"; export class GuildTags extends BaseGuildRepository { private tags: Repository; diff --git a/backend/src/data/GuildTempbans.ts b/backend/src/data/GuildTempbans.ts index e74ba7a0..05ba6ff3 100644 --- a/backend/src/data/GuildTempbans.ts +++ b/backend/src/data/GuildTempbans.ts @@ -1,8 +1,8 @@ import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { Tempban } from "./entities/Tempban"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { Tempban } from "./entities/Tempban.js"; export class GuildTempbans extends BaseGuildRepository { private tempbans: Repository; diff --git a/backend/src/data/GuildVCAlerts.ts b/backend/src/data/GuildVCAlerts.ts index 104196e2..4a566942 100644 --- a/backend/src/data/GuildVCAlerts.ts +++ b/backend/src/data/GuildVCAlerts.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseGuildRepository } from "./BaseGuildRepository"; -import { dataSource } from "./dataSource"; -import { VCAlert } from "./entities/VCAlert"; +import { BaseGuildRepository } from "./BaseGuildRepository.js"; +import { dataSource } from "./dataSource.js"; +import { VCAlert } from "./entities/VCAlert.js"; export class GuildVCAlerts extends BaseGuildRepository { private allAlerts: Repository; diff --git a/backend/src/data/MemberCache.ts b/backend/src/data/MemberCache.ts index b727c66e..34aa54aa 100644 --- a/backend/src/data/MemberCache.ts +++ b/backend/src/data/MemberCache.ts @@ -1,9 +1,9 @@ import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { DAYS } from "../utils"; -import { BaseRepository } from "./BaseRepository"; -import { dataSource } from "./dataSource"; -import { MemberCacheItem } from "./entities/MemberCacheItem"; +import { DAYS } from "../utils.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { dataSource } from "./dataSource.js"; +import { MemberCacheItem } from "./entities/MemberCacheItem.js"; const STALE_PERIOD = 90 * DAYS; diff --git a/backend/src/data/Mutes.ts b/backend/src/data/Mutes.ts index ad50dcee..9be15e95 100644 --- a/backend/src/data/Mutes.ts +++ b/backend/src/data/Mutes.ts @@ -1,10 +1,10 @@ import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { DAYS, DBDateFormat } from "../utils"; -import { BaseRepository } from "./BaseRepository"; -import { MuteTypes } from "./MuteTypes"; -import { dataSource } from "./dataSource"; -import { Mute } from "./entities/Mute"; +import { DAYS, DBDateFormat } from "../utils.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { MuteTypes } from "./MuteTypes.js"; +import { dataSource } from "./dataSource.js"; +import { Mute } from "./entities/Mute.js"; const OLD_EXPIRED_MUTE_THRESHOLD = 7 * DAYS; diff --git a/backend/src/data/Phisherman.ts b/backend/src/data/Phisherman.ts index 42f1fce9..a72f0c30 100644 --- a/backend/src/data/Phisherman.ts +++ b/backend/src/data/Phisherman.ts @@ -1,12 +1,12 @@ import crypto from "crypto"; import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { env } from "../env"; -import { DAYS, DBDateFormat, HOURS, MINUTES } from "../utils"; -import { dataSource } from "./dataSource"; -import { PhishermanCacheEntry } from "./entities/PhishermanCacheEntry"; -import { PhishermanKeyCacheEntry } from "./entities/PhishermanKeyCacheEntry"; -import { PhishermanDomainInfo, PhishermanUnknownDomain } from "./types/phisherman"; +import { env } from "../env.js"; +import { DAYS, DBDateFormat, HOURS, MINUTES } from "../utils.js"; +import { dataSource } from "./dataSource.js"; +import { PhishermanCacheEntry } from "./entities/PhishermanCacheEntry.js"; +import { PhishermanKeyCacheEntry } from "./entities/PhishermanKeyCacheEntry.js"; +import { PhishermanDomainInfo, PhishermanUnknownDomain } from "./types/phisherman.js"; const API_URL = "https://api.phisherman.gg"; const MASTER_API_KEY = env.PHISHERMAN_API_KEY; diff --git a/backend/src/data/Reminders.ts b/backend/src/data/Reminders.ts index 1e6333d2..0e8eef1d 100644 --- a/backend/src/data/Reminders.ts +++ b/backend/src/data/Reminders.ts @@ -1,9 +1,9 @@ import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { DBDateFormat } from "../utils"; -import { BaseRepository } from "./BaseRepository"; -import { dataSource } from "./dataSource"; -import { Reminder } from "./entities/Reminder"; +import { DBDateFormat } from "../utils.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { dataSource } from "./dataSource.js"; +import { Reminder } from "./entities/Reminder.js"; export class Reminders extends BaseRepository { private reminders: Repository; diff --git a/backend/src/data/ScheduledPosts.ts b/backend/src/data/ScheduledPosts.ts index ec5fafe8..0151bbee 100644 --- a/backend/src/data/ScheduledPosts.ts +++ b/backend/src/data/ScheduledPosts.ts @@ -1,9 +1,9 @@ import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { DBDateFormat } from "../utils"; -import { BaseRepository } from "./BaseRepository"; -import { dataSource } from "./dataSource"; -import { ScheduledPost } from "./entities/ScheduledPost"; +import { DBDateFormat } from "../utils.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { dataSource } from "./dataSource.js"; +import { ScheduledPost } from "./entities/ScheduledPost.js"; export class ScheduledPosts extends BaseRepository { private scheduledPosts: Repository; diff --git a/backend/src/data/Supporters.ts b/backend/src/data/Supporters.ts index 679d58d1..6784b745 100644 --- a/backend/src/data/Supporters.ts +++ b/backend/src/data/Supporters.ts @@ -1,7 +1,7 @@ import { Repository } from "typeorm"; -import { BaseRepository } from "./BaseRepository"; -import { dataSource } from "./dataSource"; -import { Supporter } from "./entities/Supporter"; +import { BaseRepository } from "./BaseRepository.js"; +import { dataSource } from "./dataSource.js"; +import { Supporter } from "./entities/Supporter.js"; export class Supporters extends BaseRepository { private supporters: Repository; diff --git a/backend/src/data/Tempbans.ts b/backend/src/data/Tempbans.ts index 8346b1a1..54d8dd4f 100644 --- a/backend/src/data/Tempbans.ts +++ b/backend/src/data/Tempbans.ts @@ -1,9 +1,9 @@ import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { DBDateFormat } from "../utils"; -import { BaseRepository } from "./BaseRepository"; -import { dataSource } from "./dataSource"; -import { Tempban } from "./entities/Tempban"; +import { DBDateFormat } from "../utils.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { dataSource } from "./dataSource.js"; +import { Tempban } from "./entities/Tempban.js"; export class Tempbans extends BaseRepository { private tempbans: Repository; diff --git a/backend/src/data/UsernameHistory.ts b/backend/src/data/UsernameHistory.ts index 59082ca4..e7287070 100644 --- a/backend/src/data/UsernameHistory.ts +++ b/backend/src/data/UsernameHistory.ts @@ -1,10 +1,10 @@ import { In, Repository } from "typeorm"; -import { isAPI } from "../globals"; -import { MINUTES, SECONDS } from "../utils"; -import { BaseRepository } from "./BaseRepository"; -import { cleanupUsernames } from "./cleanup/usernames"; -import { dataSource } from "./dataSource"; -import { UsernameHistoryEntry } from "./entities/UsernameHistoryEntry"; +import { isAPI } from "../globals.js"; +import { MINUTES, SECONDS } from "../utils.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { cleanupUsernames } from "./cleanup/usernames.js"; +import { dataSource } from "./dataSource.js"; +import { UsernameHistoryEntry } from "./entities/UsernameHistoryEntry.js"; const CLEANUP_INTERVAL = 5 * MINUTES; diff --git a/backend/src/data/VCAlerts.ts b/backend/src/data/VCAlerts.ts index d5361f57..71c36403 100644 --- a/backend/src/data/VCAlerts.ts +++ b/backend/src/data/VCAlerts.ts @@ -1,9 +1,9 @@ import moment from "moment-timezone"; import { Repository } from "typeorm"; -import { DBDateFormat } from "../utils"; -import { BaseRepository } from "./BaseRepository"; -import { dataSource } from "./dataSource"; -import { VCAlert } from "./entities/VCAlert"; +import { DBDateFormat } from "../utils.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { dataSource } from "./dataSource.js"; +import { VCAlert } from "./entities/VCAlert.js"; export class VCAlerts extends BaseRepository { private allAlerts: Repository; diff --git a/backend/src/data/Webhooks.ts b/backend/src/data/Webhooks.ts index 71927984..6615abba 100644 --- a/backend/src/data/Webhooks.ts +++ b/backend/src/data/Webhooks.ts @@ -1,8 +1,8 @@ import { Repository } from "typeorm"; -import { decrypt, encrypt } from "../utils/crypt"; -import { BaseRepository } from "./BaseRepository"; -import { dataSource } from "./dataSource"; -import { Webhook } from "./entities/Webhook"; +import { decrypt, encrypt } from "../utils/crypt.js"; +import { BaseRepository } from "./BaseRepository.js"; +import { dataSource } from "./dataSource.js"; +import { Webhook } from "./entities/Webhook.js"; export class Webhooks extends BaseRepository { repository: Repository = dataSource.getRepository(Webhook); diff --git a/backend/src/data/apiAuditLogTypes.ts b/backend/src/data/apiAuditLogTypes.ts index e75a071f..fefce4d0 100644 --- a/backend/src/data/apiAuditLogTypes.ts +++ b/backend/src/data/apiAuditLogTypes.ts @@ -1,4 +1,4 @@ -import { ApiPermissionTypes } from "./ApiPermissionAssignments"; +import { ApiPermissionTypes } from "./ApiPermissionAssignments.js"; export const AuditLogEventTypes = { ADD_API_PERMISSION: "ADD_API_PERMISSION" as const, diff --git a/backend/src/data/cleanup/configs.ts b/backend/src/data/cleanup/configs.ts index 66f1e657..a228cc32 100644 --- a/backend/src/data/cleanup/configs.ts +++ b/backend/src/data/cleanup/configs.ts @@ -1,8 +1,8 @@ import moment from "moment-timezone"; import { In } from "typeorm"; -import { DBDateFormat } from "../../utils"; -import { dataSource } from "../dataSource"; -import { Config } from "../entities/Config"; +import { DBDateFormat } from "../../utils.js"; +import { dataSource } from "../dataSource.js"; +import { Config } from "../entities/Config.js"; const CLEAN_PER_LOOP = 50; diff --git a/backend/src/data/cleanup/messages.ts b/backend/src/data/cleanup/messages.ts index 18d416a0..a30179a0 100644 --- a/backend/src/data/cleanup/messages.ts +++ b/backend/src/data/cleanup/messages.ts @@ -1,8 +1,8 @@ import moment from "moment-timezone"; import { In } from "typeorm"; -import { DAYS, DBDateFormat, MINUTES, SECONDS, sleep } from "../../utils"; -import { dataSource } from "../dataSource"; -import { SavedMessage } from "../entities/SavedMessage"; +import { DAYS, DBDateFormat, MINUTES, SECONDS, sleep } from "../../utils.js"; +import { dataSource } from "../dataSource.js"; +import { SavedMessage } from "../entities/SavedMessage.js"; /** * How long message edits, deletions, etc. will include the original message content. diff --git a/backend/src/data/cleanup/nicknames.ts b/backend/src/data/cleanup/nicknames.ts index da3406fd..26e34f4e 100644 --- a/backend/src/data/cleanup/nicknames.ts +++ b/backend/src/data/cleanup/nicknames.ts @@ -1,8 +1,8 @@ import moment from "moment-timezone"; import { In } from "typeorm"; -import { DAYS, DBDateFormat } from "../../utils"; -import { dataSource } from "../dataSource"; -import { NicknameHistoryEntry } from "../entities/NicknameHistoryEntry"; +import { DAYS, DBDateFormat } from "../../utils.js"; +import { dataSource } from "../dataSource.js"; +import { NicknameHistoryEntry } from "../entities/NicknameHistoryEntry.js"; export const NICKNAME_RETENTION_PERIOD = 30 * DAYS; const CLEAN_PER_LOOP = 500; diff --git a/backend/src/data/cleanup/usernames.ts b/backend/src/data/cleanup/usernames.ts index 982e3bfe..483b03c9 100644 --- a/backend/src/data/cleanup/usernames.ts +++ b/backend/src/data/cleanup/usernames.ts @@ -1,8 +1,8 @@ import moment from "moment-timezone"; import { In } from "typeorm"; -import { DAYS, DBDateFormat } from "../../utils"; -import { dataSource } from "../dataSource"; -import { UsernameHistoryEntry } from "../entities/UsernameHistoryEntry"; +import { DAYS, DBDateFormat } from "../../utils.js"; +import { dataSource } from "../dataSource.js"; +import { UsernameHistoryEntry } from "../entities/UsernameHistoryEntry.js"; export const USERNAME_RETENTION_PERIOD = 30 * DAYS; const CLEAN_PER_LOOP = 500; diff --git a/backend/src/data/dataSource.ts b/backend/src/data/dataSource.ts index 71032921..7d432316 100644 --- a/backend/src/data/dataSource.ts +++ b/backend/src/data/dataSource.ts @@ -1,8 +1,8 @@ import moment from "moment-timezone"; import path from "path"; import { DataSource } from "typeorm"; -import { env } from "../env"; -import { backendDir } from "../paths"; +import { env } from "../env.js"; +import { backendDir } from "../paths.js"; moment.tz.setDefault("UTC"); diff --git a/backend/src/data/db.ts b/backend/src/data/db.ts index f8d8f3bf..fe60b148 100644 --- a/backend/src/data/db.ts +++ b/backend/src/data/db.ts @@ -1,5 +1,5 @@ -import { SimpleError } from "../SimpleError"; -import { dataSource } from "./dataSource"; +import { SimpleError } from "../SimpleError.js"; +import { dataSource } from "./dataSource.js"; let connectionPromise: Promise; diff --git a/backend/src/data/entities/ApiAuditLogEntry.ts b/backend/src/data/entities/ApiAuditLogEntry.ts index 6c142bd8..f8900863 100644 --- a/backend/src/data/entities/ApiAuditLogEntry.ts +++ b/backend/src/data/entities/ApiAuditLogEntry.ts @@ -1,5 +1,5 @@ import { Column, Entity, PrimaryColumn } from "typeorm"; -import { AuditLogEventData, AuditLogEventType } from "../apiAuditLogTypes"; +import { AuditLogEventData, AuditLogEventType } from "../apiAuditLogTypes.js"; @Entity("api_audit_log") export class ApiAuditLogEntry { diff --git a/backend/src/data/entities/ApiLogin.ts b/backend/src/data/entities/ApiLogin.ts index 76460068..b1bbbdc1 100644 --- a/backend/src/data/entities/ApiLogin.ts +++ b/backend/src/data/entities/ApiLogin.ts @@ -1,5 +1,5 @@ import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm"; -import { ApiUserInfo } from "./ApiUserInfo"; +import { ApiUserInfo } from "./ApiUserInfo.js"; @Entity("api_logins") export class ApiLogin { diff --git a/backend/src/data/entities/ApiPermissionAssignment.ts b/backend/src/data/entities/ApiPermissionAssignment.ts index 98ef500f..06254127 100644 --- a/backend/src/data/entities/ApiPermissionAssignment.ts +++ b/backend/src/data/entities/ApiPermissionAssignment.ts @@ -1,6 +1,6 @@ import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm"; -import { ApiPermissionTypes } from "../ApiPermissionAssignments"; -import { ApiUserInfo } from "./ApiUserInfo"; +import { ApiPermissionTypes } from "../ApiPermissionAssignments.js"; +import { ApiUserInfo } from "./ApiUserInfo.js"; @Entity("api_permissions") export class ApiPermissionAssignment { diff --git a/backend/src/data/entities/ApiUserInfo.ts b/backend/src/data/entities/ApiUserInfo.ts index bb0844b5..80459455 100644 --- a/backend/src/data/entities/ApiUserInfo.ts +++ b/backend/src/data/entities/ApiUserInfo.ts @@ -1,6 +1,6 @@ import { Column, Entity, OneToMany, PrimaryColumn } from "typeorm"; -import { ApiLogin } from "./ApiLogin"; -import { ApiPermissionAssignment } from "./ApiPermissionAssignment"; +import { ApiLogin } from "./ApiLogin.js"; +import { ApiPermissionAssignment } from "./ApiPermissionAssignment.js"; export interface ApiUserInfoData { username: string; diff --git a/backend/src/data/entities/Case.ts b/backend/src/data/entities/Case.ts index 5fb52003..298fe739 100644 --- a/backend/src/data/entities/Case.ts +++ b/backend/src/data/entities/Case.ts @@ -1,5 +1,5 @@ import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; -import { CaseNote } from "./CaseNote"; +import { CaseNote } from "./CaseNote.js"; @Entity("cases") export class Case { diff --git a/backend/src/data/entities/CaseNote.ts b/backend/src/data/entities/CaseNote.ts index e82aa405..bbf11d80 100644 --- a/backend/src/data/entities/CaseNote.ts +++ b/backend/src/data/entities/CaseNote.ts @@ -1,5 +1,5 @@ import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; -import { Case } from "./Case"; +import { Case } from "./Case.js"; @Entity("case_notes") export class CaseNote { diff --git a/backend/src/data/entities/Config.ts b/backend/src/data/entities/Config.ts index 6d4a38c7..1b037319 100644 --- a/backend/src/data/entities/Config.ts +++ b/backend/src/data/entities/Config.ts @@ -1,5 +1,5 @@ import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from "typeorm"; -import { ApiUserInfo } from "./ApiUserInfo"; +import { ApiUserInfo } from "./ApiUserInfo.js"; @Entity("configs") export class Config { diff --git a/backend/src/data/entities/PhishermanCacheEntry.ts b/backend/src/data/entities/PhishermanCacheEntry.ts index cad135bf..e7dd0bdd 100644 --- a/backend/src/data/entities/PhishermanCacheEntry.ts +++ b/backend/src/data/entities/PhishermanCacheEntry.ts @@ -1,5 +1,5 @@ import { Column, Entity, PrimaryColumn } from "typeorm"; -import { PhishermanDomainInfo } from "../types/phisherman"; +import { PhishermanDomainInfo } from "../types/phisherman.js"; @Entity("phisherman_cache") export class PhishermanCacheEntry { diff --git a/backend/src/data/entities/ScheduledPost.ts b/backend/src/data/entities/ScheduledPost.ts index 45ba547e..542e6f50 100644 --- a/backend/src/data/entities/ScheduledPost.ts +++ b/backend/src/data/entities/ScheduledPost.ts @@ -1,6 +1,6 @@ import { Attachment } from "discord.js"; import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; -import { StrictMessageContent } from "../../utils"; +import { StrictMessageContent } from "../../utils.js"; @Entity("scheduled_posts") export class ScheduledPost { diff --git a/backend/src/data/entities/StarboardMessage.ts b/backend/src/data/entities/StarboardMessage.ts index 88512adf..980ac735 100644 --- a/backend/src/data/entities/StarboardMessage.ts +++ b/backend/src/data/entities/StarboardMessage.ts @@ -1,5 +1,5 @@ import { Column, Entity, JoinColumn, OneToOne, PrimaryColumn } from "typeorm"; -import { SavedMessage } from "./SavedMessage"; +import { SavedMessage } from "./SavedMessage.js"; @Entity("starboard_messages") export class StarboardMessage { diff --git a/backend/src/data/entities/StarboardReaction.ts b/backend/src/data/entities/StarboardReaction.ts index 9cc02850..417b476a 100644 --- a/backend/src/data/entities/StarboardReaction.ts +++ b/backend/src/data/entities/StarboardReaction.ts @@ -1,5 +1,5 @@ import { Column, Entity, JoinColumn, OneToOne, PrimaryColumn } from "typeorm"; -import { SavedMessage } from "./SavedMessage"; +import { SavedMessage } from "./SavedMessage.js"; @Entity("starboard_reactions") export class StarboardReaction { diff --git a/backend/src/data/getChannelIdFromMessageId.ts b/backend/src/data/getChannelIdFromMessageId.ts index 59095afb..676952c8 100644 --- a/backend/src/data/getChannelIdFromMessageId.ts +++ b/backend/src/data/getChannelIdFromMessageId.ts @@ -1,6 +1,6 @@ import { Repository } from "typeorm"; -import { dataSource } from "./dataSource"; -import { SavedMessage } from "./entities/SavedMessage"; +import { dataSource } from "./dataSource.js"; +import { SavedMessage } from "./entities/SavedMessage.js"; let repository: Repository; diff --git a/backend/src/data/loops/expiredArchiveDeletionLoop.ts b/backend/src/data/loops/expiredArchiveDeletionLoop.ts index be39ab27..a0357726 100644 --- a/backend/src/data/loops/expiredArchiveDeletionLoop.ts +++ b/backend/src/data/loops/expiredArchiveDeletionLoop.ts @@ -1,7 +1,7 @@ // tslint:disable:no-console -import { lazyMemoize, MINUTES } from "../../utils"; -import { Archives } from "../Archives"; +import { lazyMemoize, MINUTES } from "../../utils.js"; +import { Archives } from "../Archives.js"; const LOOP_INTERVAL = 15 * MINUTES; const getArchivesRepository = lazyMemoize(() => new Archives()); diff --git a/backend/src/data/loops/expiredMemberCacheDeletionLoop.ts b/backend/src/data/loops/expiredMemberCacheDeletionLoop.ts index 13c60da4..d7cb9161 100644 --- a/backend/src/data/loops/expiredMemberCacheDeletionLoop.ts +++ b/backend/src/data/loops/expiredMemberCacheDeletionLoop.ts @@ -1,7 +1,7 @@ // tslint:disable:no-console -import { HOURS, lazyMemoize } from "../../utils"; -import { MemberCache } from "../MemberCache"; +import { HOURS, lazyMemoize } from "../../utils.js"; +import { MemberCache } from "../MemberCache.js"; const LOOP_INTERVAL = 6 * HOURS; const getMemberCacheRepository = lazyMemoize(() => new MemberCache()); diff --git a/backend/src/data/loops/expiringMutesLoop.ts b/backend/src/data/loops/expiringMutesLoop.ts index d8c5cd57..5e163559 100644 --- a/backend/src/data/loops/expiringMutesLoop.ts +++ b/backend/src/data/loops/expiringMutesLoop.ts @@ -1,10 +1,10 @@ // tslint:disable:no-console import moment from "moment-timezone"; -import { lazyMemoize, MINUTES, SECONDS } from "../../utils"; -import { Mute } from "../entities/Mute"; -import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents"; -import { Mutes, TIMEOUT_RENEWAL_THRESHOLD } from "../Mutes"; +import { lazyMemoize, MINUTES, SECONDS } from "../../utils.js"; +import { Mute } from "../entities/Mute.js"; +import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents.js"; +import { Mutes, TIMEOUT_RENEWAL_THRESHOLD } from "../Mutes.js"; import Timeout = NodeJS.Timeout; const LOOP_INTERVAL = 15 * MINUTES; diff --git a/backend/src/data/loops/expiringTempbansLoop.ts b/backend/src/data/loops/expiringTempbansLoop.ts index 3929125d..1d1f63a2 100644 --- a/backend/src/data/loops/expiringTempbansLoop.ts +++ b/backend/src/data/loops/expiringTempbansLoop.ts @@ -1,10 +1,10 @@ // tslint:disable:no-console import moment from "moment-timezone"; -import { lazyMemoize, MINUTES } from "../../utils"; -import { Tempban } from "../entities/Tempban"; -import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents"; -import { Tempbans } from "../Tempbans"; +import { lazyMemoize, MINUTES } from "../../utils.js"; +import { Tempban } from "../entities/Tempban.js"; +import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents.js"; +import { Tempbans } from "../Tempbans.js"; import Timeout = NodeJS.Timeout; const LOOP_INTERVAL = 15 * MINUTES; diff --git a/backend/src/data/loops/expiringVCAlertsLoop.ts b/backend/src/data/loops/expiringVCAlertsLoop.ts index dbf8c2ef..d8a09b4d 100644 --- a/backend/src/data/loops/expiringVCAlertsLoop.ts +++ b/backend/src/data/loops/expiringVCAlertsLoop.ts @@ -1,10 +1,10 @@ // tslint:disable:no-console import moment from "moment-timezone"; -import { lazyMemoize, MINUTES } from "../../utils"; -import { VCAlert } from "../entities/VCAlert"; -import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents"; -import { VCAlerts } from "../VCAlerts"; +import { lazyMemoize, MINUTES } from "../../utils.js"; +import { VCAlert } from "../entities/VCAlert.js"; +import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents.js"; +import { VCAlerts } from "../VCAlerts.js"; import Timeout = NodeJS.Timeout; const LOOP_INTERVAL = 15 * MINUTES; diff --git a/backend/src/data/loops/memberCacheDeletionLoop.ts b/backend/src/data/loops/memberCacheDeletionLoop.ts index ff1a6cab..8442a547 100644 --- a/backend/src/data/loops/memberCacheDeletionLoop.ts +++ b/backend/src/data/loops/memberCacheDeletionLoop.ts @@ -1,7 +1,7 @@ // tslint:disable:no-console -import { lazyMemoize, MINUTES } from "../../utils"; -import { MemberCache } from "../MemberCache"; +import { lazyMemoize, MINUTES } from "../../utils.js"; +import { MemberCache } from "../MemberCache.js"; const LOOP_INTERVAL = 5 * MINUTES; const getMemberCacheRepository = lazyMemoize(() => new MemberCache()); diff --git a/backend/src/data/loops/phishermanLoops.ts b/backend/src/data/loops/phishermanLoops.ts index 6ab89488..2550d450 100644 --- a/backend/src/data/loops/phishermanLoops.ts +++ b/backend/src/data/loops/phishermanLoops.ts @@ -1,11 +1,11 @@ // tslint:disable:no-console -import { MINUTES } from "../../utils"; +import { MINUTES } from "../../utils.js"; import { deleteStalePhishermanCacheEntries, deleteStalePhishermanKeyCacheEntries, reportTrackedDomainsToPhisherman, -} from "../Phisherman"; +} from "../Phisherman.js"; const CACHE_CLEANUP_LOOP_INTERVAL = 15 * MINUTES; const REPORT_LOOP_INTERVAL = 15 * MINUTES; diff --git a/backend/src/data/loops/savedMessageCleanupLoop.ts b/backend/src/data/loops/savedMessageCleanupLoop.ts index b5b4dcc7..05afb73a 100644 --- a/backend/src/data/loops/savedMessageCleanupLoop.ts +++ b/backend/src/data/loops/savedMessageCleanupLoop.ts @@ -1,7 +1,7 @@ // tslint:disable:no-console -import { MINUTES } from "../../utils"; -import { cleanupMessages } from "../cleanup/messages"; +import { MINUTES } from "../../utils.js"; +import { cleanupMessages } from "../cleanup/messages.js"; const LOOP_INTERVAL = 5 * MINUTES; diff --git a/backend/src/data/loops/upcomingRemindersLoop.ts b/backend/src/data/loops/upcomingRemindersLoop.ts index 3ecc661c..8bfd8b76 100644 --- a/backend/src/data/loops/upcomingRemindersLoop.ts +++ b/backend/src/data/loops/upcomingRemindersLoop.ts @@ -1,10 +1,10 @@ // tslint:disable:no-console import moment from "moment-timezone"; -import { lazyMemoize, MINUTES } from "../../utils"; -import { Reminder } from "../entities/Reminder"; -import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents"; -import { Reminders } from "../Reminders"; +import { lazyMemoize, MINUTES } from "../../utils.js"; +import { Reminder } from "../entities/Reminder.js"; +import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents.js"; +import { Reminders } from "../Reminders.js"; import Timeout = NodeJS.Timeout; const LOOP_INTERVAL = 15 * MINUTES; diff --git a/backend/src/data/loops/upcomingScheduledPostsLoop.ts b/backend/src/data/loops/upcomingScheduledPostsLoop.ts index edd9fdad..2138687a 100644 --- a/backend/src/data/loops/upcomingScheduledPostsLoop.ts +++ b/backend/src/data/loops/upcomingScheduledPostsLoop.ts @@ -1,10 +1,10 @@ // tslint:disable:no-console import moment from "moment-timezone"; -import { lazyMemoize, MINUTES } from "../../utils"; -import { ScheduledPost } from "../entities/ScheduledPost"; -import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents"; -import { ScheduledPosts } from "../ScheduledPosts"; +import { lazyMemoize, MINUTES } from "../../utils.js"; +import { ScheduledPost } from "../entities/ScheduledPost.js"; +import { emitGuildEvent, hasGuildEventListener } from "../GuildEvents.js"; +import { ScheduledPosts } from "../ScheduledPosts.js"; import Timeout = NodeJS.Timeout; const LOOP_INTERVAL = 15 * MINUTES; diff --git a/backend/src/env.ts b/backend/src/env.ts index f04e2cd5..e4b9214d 100644 --- a/backend/src/env.ts +++ b/backend/src/env.ts @@ -2,7 +2,7 @@ import dotenv from "dotenv"; import fs from "fs"; import path from "path"; import { z } from "zod"; -import { rootDir } from "./paths"; +import { rootDir } from "./paths.js"; const envType = z.object({ KEY: z.string().length(32), diff --git a/backend/src/exportSchemas.ts b/backend/src/exportSchemas.ts index 59cc5708..2ca0867d 100644 --- a/backend/src/exportSchemas.ts +++ b/backend/src/exportSchemas.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import zodToJsonSchema from "zod-to-json-schema"; -import { guildPluginInfo } from "./plugins/pluginInfo"; -import { zZeppelinGuildConfig } from "./types"; +import { guildPluginInfo } from "./plugins/pluginInfo.js"; +import { zZeppelinGuildConfig } from "./types.js"; const pluginSchemaMap = Object.entries(guildPluginInfo).reduce((map, [pluginName, pluginInfo]) => { if (pluginInfo.configSchema) { diff --git a/backend/src/index.ts b/backend/src/index.ts index c63aff66..244d1bfe 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,6 +1,6 @@ // KEEP THIS AS FIRST IMPORT // See comment in module for details -import "./threadsSignalFix"; +import "./threadsSignalFix.js"; import { Client, @@ -17,37 +17,37 @@ import { Knub, PluginError, PluginLoadError, PluginNotLoadedError } from "knub"; import moment from "moment-timezone"; import { performance } from "perf_hooks"; import process from "process"; -import { DiscordJSError } from "./DiscordJSError"; -import { RecoverablePluginError } from "./RecoverablePluginError"; -import { SimpleError } from "./SimpleError"; -import { AllowedGuilds } from "./data/AllowedGuilds"; -import { Configs } from "./data/Configs"; -import { GuildLogs } from "./data/GuildLogs"; -import { LogType } from "./data/LogType"; -import { hasPhishermanMasterAPIKey } from "./data/Phisherman"; -import { dataSource } from "./data/dataSource"; -import { connect } from "./data/db"; -import { runExpiredArchiveDeletionLoop } from "./data/loops/expiredArchiveDeletionLoop"; -import { runExpiredMemberCacheDeletionLoop } from "./data/loops/expiredMemberCacheDeletionLoop"; -import { runExpiringMutesLoop } from "./data/loops/expiringMutesLoop"; -import { runExpiringTempbansLoop } from "./data/loops/expiringTempbansLoop"; -import { runExpiringVCAlertsLoop } from "./data/loops/expiringVCAlertsLoop"; -import { runMemberCacheDeletionLoop } from "./data/loops/memberCacheDeletionLoop"; -import { runPhishermanCacheCleanupLoop, runPhishermanReportingLoop } from "./data/loops/phishermanLoops"; -import { runSavedMessageCleanupLoop } from "./data/loops/savedMessageCleanupLoop"; -import { runUpcomingRemindersLoop } from "./data/loops/upcomingRemindersLoop"; -import { runUpcomingScheduledPostsLoop } from "./data/loops/upcomingScheduledPostsLoop"; -import { consumeQueryStats } from "./data/queryLogger"; -import { env } from "./env"; -import { logger } from "./logger"; -import { baseGuildPlugins, globalPlugins, guildPlugins } from "./plugins/availablePlugins"; -import { setProfiler } from "./profiler"; -import { logRateLimit } from "./rateLimitStats"; -import { startUptimeCounter } from "./uptime"; -import { MINUTES, SECONDS, errorMessage, isDiscordAPIError, isDiscordHTTPError, sleep, successMessage } from "./utils"; -import { DecayingCounter } from "./utils/DecayingCounter"; -import { enableProfiling } from "./utils/easyProfiler"; -import { loadYamlSafely } from "./utils/loadYamlSafely"; +import { DiscordJSError } from "./DiscordJSError.js"; +import { RecoverablePluginError } from "./RecoverablePluginError.js"; +import { SimpleError } from "./SimpleError.js"; +import { AllowedGuilds } from "./data/AllowedGuilds.js"; +import { Configs } from "./data/Configs.js"; +import { GuildLogs } from "./data/GuildLogs.js"; +import { LogType } from "./data/LogType.js"; +import { hasPhishermanMasterAPIKey } from "./data/Phisherman.js"; +import { dataSource } from "./data/dataSource.js"; +import { connect } from "./data/db.js"; +import { runExpiredArchiveDeletionLoop } from "./data/loops/expiredArchiveDeletionLoop.js"; +import { runExpiredMemberCacheDeletionLoop } from "./data/loops/expiredMemberCacheDeletionLoop.js"; +import { runExpiringMutesLoop } from "./data/loops/expiringMutesLoop.js"; +import { runExpiringTempbansLoop } from "./data/loops/expiringTempbansLoop.js"; +import { runExpiringVCAlertsLoop } from "./data/loops/expiringVCAlertsLoop.js"; +import { runMemberCacheDeletionLoop } from "./data/loops/memberCacheDeletionLoop.js"; +import { runPhishermanCacheCleanupLoop, runPhishermanReportingLoop } from "./data/loops/phishermanLoops.js"; +import { runSavedMessageCleanupLoop } from "./data/loops/savedMessageCleanupLoop.js"; +import { runUpcomingRemindersLoop } from "./data/loops/upcomingRemindersLoop.js"; +import { runUpcomingScheduledPostsLoop } from "./data/loops/upcomingScheduledPostsLoop.js"; +import { consumeQueryStats } from "./data/queryLogger.js"; +import { env } from "./env.js"; +import { logger } from "./logger.js"; +import { baseGuildPlugins, globalPlugins, guildPlugins } from "./plugins/availablePlugins.js"; +import { setProfiler } from "./profiler.js"; +import { logRateLimit } from "./rateLimitStats.js"; +import { startUptimeCounter } from "./uptime.js"; +import { MINUTES, SECONDS, errorMessage, isDiscordAPIError, isDiscordHTTPError, sleep, successMessage } from "./utils.js"; +import { DecayingCounter } from "./utils/DecayingCounter.js"; +import { enableProfiling } from "./utils/easyProfiler.js"; +import { loadYamlSafely } from "./utils/loadYamlSafely.js"; // Error handling let recentPluginErrors = 0; diff --git a/backend/src/migrateConfigsToDB.ts b/backend/src/migrateConfigsToDB.ts index 67423c41..dd370e85 100644 --- a/backend/src/migrateConfigsToDB.ts +++ b/backend/src/migrateConfigsToDB.ts @@ -1,8 +1,8 @@ // tslint:disable:no-console import * as _fs from "fs"; import path from "path"; -import { Configs } from "./data/Configs"; -import { connect } from "./data/db"; +import { Configs } from "./data/Configs.js"; +import { connect } from "./data/db.js"; const fs = _fs.promises; diff --git a/backend/src/migrations/1600283341726-EncryptExistingMessages.ts b/backend/src/migrations/1600283341726-EncryptExistingMessages.ts index 19a21fca..50bbe6d2 100644 --- a/backend/src/migrations/1600283341726-EncryptExistingMessages.ts +++ b/backend/src/migrations/1600283341726-EncryptExistingMessages.ts @@ -1,5 +1,5 @@ import { MigrationInterface, QueryRunner } from "typeorm"; -import { decrypt, encrypt } from "../utils/crypt"; +import { decrypt, encrypt } from "../utils/crypt.js"; export class EncryptExistingMessages1600283341726 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { diff --git a/backend/src/migrations/1600285077890-EncryptArchives.ts b/backend/src/migrations/1600285077890-EncryptArchives.ts index 52d6393b..9ba1f2c9 100644 --- a/backend/src/migrations/1600285077890-EncryptArchives.ts +++ b/backend/src/migrations/1600285077890-EncryptArchives.ts @@ -1,5 +1,5 @@ import { MigrationInterface, QueryRunner } from "typeorm"; -import { decrypt, encrypt } from "../utils/crypt"; +import { decrypt, encrypt } from "../utils/crypt.js"; export class EncryptArchives1600285077890 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { diff --git a/backend/src/pluginUtils.ts b/backend/src/pluginUtils.ts index 2fa3375f..615ec7a0 100644 --- a/backend/src/pluginUtils.ts +++ b/backend/src/pluginUtils.ts @@ -13,9 +13,9 @@ import { User, } from "discord.js"; import { AnyPluginData, BasePluginData, CommandContext, ExtendedMatchParams, GuildPluginData, helpers } from "knub"; -import { isStaff } from "./staff"; -import { TZeppelinKnub } from "./types"; -import { Tail } from "./utils/typeUtils"; +import { isStaff } from "./staff.js"; +import { TZeppelinKnub } from "./types.js"; +import { Tail } from "./utils/typeUtils.js"; const { getMemberLevel } = helpers; diff --git a/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts b/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts index 4c537bf0..ab9d8ba7 100644 --- a/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts +++ b/backend/src/plugins/AutoDelete/AutoDeletePlugin.ts @@ -1,12 +1,12 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { AutoDeletePluginType, zAutoDeleteConfig } from "./types"; -import { onMessageCreate } from "./util/onMessageCreate"; -import { onMessageDelete } from "./util/onMessageDelete"; -import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin.js"; +import { AutoDeletePluginType, zAutoDeleteConfig } from "./types.js"; +import { onMessageCreate } from "./util/onMessageCreate.js"; +import { onMessageDelete } from "./util/onMessageDelete.js"; +import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/AutoDelete/info.ts b/backend/src/plugins/AutoDelete/info.ts index 9ceeddee..8a4438a3 100644 --- a/backend/src/plugins/AutoDelete/info.ts +++ b/backend/src/plugins/AutoDelete/info.ts @@ -1,4 +1,4 @@ -import { ZeppelinPluginInfo } from "../../types"; +import { ZeppelinPluginInfo } from "../../types.js"; export const autoDeletePluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/AutoDelete/types.ts b/backend/src/plugins/AutoDelete/types.ts index be6ff7ee..749eec49 100644 --- a/backend/src/plugins/AutoDelete/types.ts +++ b/backend/src/plugins/AutoDelete/types.ts @@ -1,9 +1,9 @@ import { BasePluginType } from "knub"; import z from "zod"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { SavedMessage } from "../../data/entities/SavedMessage"; -import { MINUTES, zDelayString } from "../../utils"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { SavedMessage } from "../../data/entities/SavedMessage.js"; +import { MINUTES, zDelayString } from "../../utils.js"; import Timeout = NodeJS.Timeout; export const MAX_DELAY = 5 * MINUTES; diff --git a/backend/src/plugins/AutoDelete/util/addMessageToDeletionQueue.ts b/backend/src/plugins/AutoDelete/util/addMessageToDeletionQueue.ts index 7d37c003..f965e58a 100644 --- a/backend/src/plugins/AutoDelete/util/addMessageToDeletionQueue.ts +++ b/backend/src/plugins/AutoDelete/util/addMessageToDeletionQueue.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { sorter } from "../../../utils"; -import { AutoDeletePluginType } from "../types"; -import { scheduleNextDeletion } from "./scheduleNextDeletion"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { sorter } from "../../../utils.js"; +import { AutoDeletePluginType } from "../types.js"; +import { scheduleNextDeletion } from "./scheduleNextDeletion.js"; export function addMessageToDeletionQueue( pluginData: GuildPluginData, diff --git a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts index c3aa6f72..af40ac93 100644 --- a/backend/src/plugins/AutoDelete/util/deleteNextItem.ts +++ b/backend/src/plugins/AutoDelete/util/deleteNextItem.ts @@ -1,14 +1,14 @@ import { ChannelType, PermissionsBitField, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { LogType } from "../../../data/LogType"; -import { logger } from "../../../logger"; -import { resolveUser, verboseChannelMention } from "../../../utils"; -import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { AutoDeletePluginType } from "../types"; -import { scheduleNextDeletion } from "./scheduleNextDeletion"; +import { LogType } from "../../../data/LogType.js"; +import { logger } from "../../../logger.js"; +import { resolveUser, verboseChannelMention } from "../../../utils.js"; +import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js"; +import { AutoDeletePluginType } from "../types.js"; +import { scheduleNextDeletion } from "./scheduleNextDeletion.js"; export async function deleteNextItem(pluginData: GuildPluginData) { const [itemToDelete] = pluginData.state.deletionQueue.splice(0, 1); diff --git a/backend/src/plugins/AutoDelete/util/onMessageCreate.ts b/backend/src/plugins/AutoDelete/util/onMessageCreate.ts index 024e3cf0..1f125900 100644 --- a/backend/src/plugins/AutoDelete/util/onMessageCreate.ts +++ b/backend/src/plugins/AutoDelete/util/onMessageCreate.ts @@ -1,9 +1,9 @@ import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { convertDelayStringToMS, resolveMember } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { AutoDeletePluginType, MAX_DELAY } from "../types"; -import { addMessageToDeletionQueue } from "./addMessageToDeletionQueue"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { convertDelayStringToMS, resolveMember } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { AutoDeletePluginType, MAX_DELAY } from "../types.js"; +import { addMessageToDeletionQueue } from "./addMessageToDeletionQueue.js"; export async function onMessageCreate(pluginData: GuildPluginData, msg: SavedMessage) { const member = await resolveMember(pluginData.client, pluginData.guild, msg.user_id); diff --git a/backend/src/plugins/AutoDelete/util/onMessageDelete.ts b/backend/src/plugins/AutoDelete/util/onMessageDelete.ts index 984a7850..c479f381 100644 --- a/backend/src/plugins/AutoDelete/util/onMessageDelete.ts +++ b/backend/src/plugins/AutoDelete/util/onMessageDelete.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { AutoDeletePluginType } from "../types"; -import { scheduleNextDeletion } from "./scheduleNextDeletion"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { AutoDeletePluginType } from "../types.js"; +import { scheduleNextDeletion } from "./scheduleNextDeletion.js"; export function onMessageDelete(pluginData: GuildPluginData, msg: SavedMessage) { const indexToDelete = pluginData.state.deletionQueue.findIndex((item) => item.message.id === msg.id); diff --git a/backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts b/backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts index 6c39a667..6114c8d4 100644 --- a/backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts +++ b/backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { AutoDeletePluginType } from "../types"; -import { onMessageDelete } from "./onMessageDelete"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { AutoDeletePluginType } from "../types.js"; +import { onMessageDelete } from "./onMessageDelete.js"; export function onMessageDeleteBulk(pluginData: GuildPluginData, messages: SavedMessage[]) { for (const msg of messages) { diff --git a/backend/src/plugins/AutoDelete/util/scheduleNextDeletion.ts b/backend/src/plugins/AutoDelete/util/scheduleNextDeletion.ts index ebae82a9..27611b39 100644 --- a/backend/src/plugins/AutoDelete/util/scheduleNextDeletion.ts +++ b/backend/src/plugins/AutoDelete/util/scheduleNextDeletion.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { AutoDeletePluginType } from "../types"; -import { deleteNextItem } from "./deleteNextItem"; +import { AutoDeletePluginType } from "../types.js"; +import { deleteNextItem } from "./deleteNextItem.js"; export function scheduleNextDeletion(pluginData: GuildPluginData) { if (pluginData.state.deletionQueue.length === 0) { diff --git a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts index bd901d49..915eab26 100644 --- a/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts +++ b/backend/src/plugins/AutoReactions/AutoReactionsPlugin.ts @@ -1,12 +1,12 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildAutoReactions } from "../../data/GuildAutoReactions"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { DisableAutoReactionsCmd } from "./commands/DisableAutoReactionsCmd"; -import { NewAutoReactionsCmd } from "./commands/NewAutoReactionsCmd"; -import { AddReactionsEvt } from "./events/AddReactionsEvt"; -import { AutoReactionsPluginType, zAutoReactionsConfig } from "./types"; +import { GuildAutoReactions } from "../../data/GuildAutoReactions.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { DisableAutoReactionsCmd } from "./commands/DisableAutoReactionsCmd.js"; +import { NewAutoReactionsCmd } from "./commands/NewAutoReactionsCmd.js"; +import { AddReactionsEvt } from "./events/AddReactionsEvt.js"; +import { AutoReactionsPluginType, zAutoReactionsConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts index 9d57a0dd..eba1f92b 100644 --- a/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/DisableAutoReactionsCmd.ts @@ -1,5 +1,5 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { autoReactionsCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { autoReactionsCmd } from "../types.js"; export const DisableAutoReactionsCmd = autoReactionsCmd({ trigger: "auto_reactions disable", diff --git a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts index 420948cc..c1250b53 100644 --- a/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts +++ b/backend/src/plugins/AutoReactions/commands/NewAutoReactionsCmd.ts @@ -1,10 +1,10 @@ import { PermissionsBitField } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canUseEmoji, customEmojiRegex, isEmoji } from "../../../utils"; -import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { readChannelPermissions } from "../../../utils/readChannelPermissions"; -import { autoReactionsCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { canUseEmoji, customEmojiRegex, isEmoji } from "../../../utils.js"; +import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions.js"; +import { missingPermissionError } from "../../../utils/missingPermissionError.js"; +import { readChannelPermissions } from "../../../utils/readChannelPermissions.js"; +import { autoReactionsCmd } from "../types.js"; const requiredPermissions = readChannelPermissions | PermissionsBitField.Flags.AddReactions; diff --git a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts index 574e500f..136cb042 100644 --- a/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts +++ b/backend/src/plugins/AutoReactions/events/AddReactionsEvt.ts @@ -1,11 +1,11 @@ import { GuildTextBasedChannel, PermissionsBitField } from "discord.js"; -import { AutoReaction } from "../../../data/entities/AutoReaction"; -import { isDiscordAPIError } from "../../../utils"; -import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { readChannelPermissions } from "../../../utils/readChannelPermissions"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { autoReactionsEvt } from "../types"; +import { AutoReaction } from "../../../data/entities/AutoReaction.js"; +import { isDiscordAPIError } from "../../../utils.js"; +import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions.js"; +import { missingPermissionError } from "../../../utils/missingPermissionError.js"; +import { readChannelPermissions } from "../../../utils/readChannelPermissions.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { autoReactionsEvt } from "../types.js"; const p = PermissionsBitField.Flags; diff --git a/backend/src/plugins/AutoReactions/info.ts b/backend/src/plugins/AutoReactions/info.ts index d908f163..05a41b74 100644 --- a/backend/src/plugins/AutoReactions/info.ts +++ b/backend/src/plugins/AutoReactions/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; export const autoReactionsInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/AutoReactions/types.ts b/backend/src/plugins/AutoReactions/types.ts index d060d59a..0a4c4db0 100644 --- a/backend/src/plugins/AutoReactions/types.ts +++ b/backend/src/plugins/AutoReactions/types.ts @@ -1,10 +1,10 @@ import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { GuildAutoReactions } from "../../data/GuildAutoReactions"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { AutoReaction } from "../../data/entities/AutoReaction"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { GuildAutoReactions } from "../../data/GuildAutoReactions.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { AutoReaction } from "../../data/entities/AutoReaction.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zAutoReactionsConfig = z.strictObject({ can_manage: z.boolean(), diff --git a/backend/src/plugins/Automod/AutomodPlugin.ts b/backend/src/plugins/Automod/AutomodPlugin.ts index abe0990c..de38d544 100644 --- a/backend/src/plugins/Automod/AutomodPlugin.ts +++ b/backend/src/plugins/Automod/AutomodPlugin.ts @@ -1,38 +1,38 @@ import { CooldownManager, guildPlugin } from "knub"; -import { Queue } from "../../Queue"; -import { GuildAntiraidLevels } from "../../data/GuildAntiraidLevels"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; -import { MINUTES, SECONDS } from "../../utils"; -import { registerEventListenersFromMap } from "../../utils/registerEventListenersFromMap"; -import { unregisterEventListenersFromMap } from "../../utils/unregisterEventListenersFromMap"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { CountersPlugin } from "../Counters/CountersPlugin"; -import { InternalPosterPlugin } from "../InternalPoster/InternalPosterPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { ModActionsPlugin } from "../ModActions/ModActionsPlugin"; -import { MutesPlugin } from "../Mutes/MutesPlugin"; -import { PhishermanPlugin } from "../Phisherman/PhishermanPlugin"; -import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin"; -import { AntiraidClearCmd } from "./commands/AntiraidClearCmd"; -import { SetAntiraidCmd } from "./commands/SetAntiraidCmd"; -import { ViewAntiraidCmd } from "./commands/ViewAntiraidCmd"; -import { RunAutomodOnJoinEvt, RunAutomodOnLeaveEvt } from "./events/RunAutomodOnJoinLeaveEvt"; -import { RunAutomodOnMemberUpdate } from "./events/RunAutomodOnMemberUpdate"; -import { runAutomodOnCounterTrigger } from "./events/runAutomodOnCounterTrigger"; -import { runAutomodOnMessage } from "./events/runAutomodOnMessage"; -import { runAutomodOnModAction } from "./events/runAutomodOnModAction"; +import { Queue } from "../../Queue.js"; +import { GuildAntiraidLevels } from "../../data/GuildAntiraidLevels.js"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners.js"; +import { MINUTES, SECONDS } from "../../utils.js"; +import { registerEventListenersFromMap } from "../../utils/registerEventListenersFromMap.js"; +import { unregisterEventListenersFromMap } from "../../utils/unregisterEventListenersFromMap.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { CountersPlugin } from "../Counters/CountersPlugin.js"; +import { InternalPosterPlugin } from "../InternalPoster/InternalPosterPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { ModActionsPlugin } from "../ModActions/ModActionsPlugin.js"; +import { MutesPlugin } from "../Mutes/MutesPlugin.js"; +import { PhishermanPlugin } from "../Phisherman/PhishermanPlugin.js"; +import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin.js"; +import { AntiraidClearCmd } from "./commands/AntiraidClearCmd.js"; +import { SetAntiraidCmd } from "./commands/SetAntiraidCmd.js"; +import { ViewAntiraidCmd } from "./commands/ViewAntiraidCmd.js"; +import { RunAutomodOnJoinEvt, RunAutomodOnLeaveEvt } from "./events/RunAutomodOnJoinLeaveEvt.js"; +import { RunAutomodOnMemberUpdate } from "./events/RunAutomodOnMemberUpdate.js"; +import { runAutomodOnCounterTrigger } from "./events/runAutomodOnCounterTrigger.js"; +import { runAutomodOnMessage } from "./events/runAutomodOnMessage.js"; +import { runAutomodOnModAction } from "./events/runAutomodOnModAction.js"; import { RunAutomodOnThreadCreate, RunAutomodOnThreadDelete, RunAutomodOnThreadUpdate, -} from "./events/runAutomodOnThreadEvents"; -import { clearOldRecentNicknameChanges } from "./functions/clearOldNicknameChanges"; -import { clearOldRecentActions } from "./functions/clearOldRecentActions"; -import { clearOldRecentSpam } from "./functions/clearOldRecentSpam"; -import { AutomodPluginType, zAutomodConfig } from "./types"; +} from "./events/runAutomodOnThreadEvents.js"; +import { clearOldRecentNicknameChanges } from "./functions/clearOldNicknameChanges.js"; +import { clearOldRecentActions } from "./functions/clearOldRecentActions.js"; +import { clearOldRecentSpam } from "./functions/clearOldRecentSpam.js"; +import { AutomodPluginType, zAutomodConfig } from "./types.js"; const defaultOptions = { config: { diff --git a/backend/src/plugins/Automod/actions/addRoles.ts b/backend/src/plugins/Automod/actions/addRoles.ts index 89294728..a1204314 100644 --- a/backend/src/plugins/Automod/actions/addRoles.ts +++ b/backend/src/plugins/Automod/actions/addRoles.ts @@ -1,13 +1,13 @@ import { PermissionFlagsBits, Snowflake } from "discord.js"; import z from "zod"; -import { nonNullish, unique, zSnowflake } from "../../../utils"; -import { canAssignRole } from "../../../utils/canAssignRole"; -import { getMissingPermissions } from "../../../utils/getMissingPermissions"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; -import { ignoreRoleChange } from "../functions/ignoredRoleChanges"; -import { automodAction } from "../helpers"; +import { nonNullish, unique, zSnowflake } from "../../../utils.js"; +import { canAssignRole } from "../../../utils/canAssignRole.js"; +import { getMissingPermissions } from "../../../utils/getMissingPermissions.js"; +import { missingPermissionError } from "../../../utils/missingPermissionError.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin.js"; +import { ignoreRoleChange } from "../functions/ignoredRoleChanges.js"; +import { automodAction } from "../helpers.js"; const p = PermissionFlagsBits; diff --git a/backend/src/plugins/Automod/actions/addToCounter.ts b/backend/src/plugins/Automod/actions/addToCounter.ts index 30ffe8fa..17a74462 100644 --- a/backend/src/plugins/Automod/actions/addToCounter.ts +++ b/backend/src/plugins/Automod/actions/addToCounter.ts @@ -1,8 +1,8 @@ import z from "zod"; -import { zBoundedCharacters } from "../../../utils"; -import { CountersPlugin } from "../../Counters/CountersPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { automodAction } from "../helpers"; +import { zBoundedCharacters } from "../../../utils.js"; +import { CountersPlugin } from "../../Counters/CountersPlugin.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { automodAction } from "../helpers.js"; const configSchema = z.object({ counter: zBoundedCharacters(0, 100), diff --git a/backend/src/plugins/Automod/actions/alert.ts b/backend/src/plugins/Automod/actions/alert.ts index d21fb4d5..ea26d5bb 100644 --- a/backend/src/plugins/Automod/actions/alert.ts +++ b/backend/src/plugins/Automod/actions/alert.ts @@ -1,12 +1,12 @@ import { Snowflake } from "discord.js"; import z from "zod"; -import { LogType } from "../../../data/LogType"; +import { LogType } from "../../../data/LogType.js"; import { createTypedTemplateSafeValueContainer, renderTemplate, TemplateParseError, TemplateSafeValueContainer, -} from "../../../templateFormatter"; +} from "../../../templateFormatter.js"; import { chunkMessageLines, isTruthy, @@ -17,13 +17,13 @@ import { zBoundedCharacters, zNullishToUndefined, zSnowflake, -} from "../../../utils"; -import { erisAllowedMentionsToDjsMentionOptions } from "../../../utils/erisAllowedMentionsToDjsMentionOptions"; -import { messageIsEmpty } from "../../../utils/messageIsEmpty"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { InternalPosterPlugin } from "../../InternalPoster/InternalPosterPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { automodAction } from "../helpers"; +} from "../../../utils.js"; +import { erisAllowedMentionsToDjsMentionOptions } from "../../../utils/erisAllowedMentionsToDjsMentionOptions.js"; +import { messageIsEmpty } from "../../../utils/messageIsEmpty.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { InternalPosterPlugin } from "../../InternalPoster/InternalPosterPlugin.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { automodAction } from "../helpers.js"; const configSchema = z.object({ channel: zSnowflake, diff --git a/backend/src/plugins/Automod/actions/archiveThread.ts b/backend/src/plugins/Automod/actions/archiveThread.ts index e73cb3dd..ca1e6242 100644 --- a/backend/src/plugins/Automod/actions/archiveThread.ts +++ b/backend/src/plugins/Automod/actions/archiveThread.ts @@ -1,7 +1,7 @@ import { AnyThreadChannel } from "discord.js"; import z from "zod"; -import { noop } from "../../../utils"; -import { automodAction } from "../helpers"; +import { noop } from "../../../utils.js"; +import { automodAction } from "../helpers.js"; const configSchema = z.strictObject({}); diff --git a/backend/src/plugins/Automod/actions/availableActions.ts b/backend/src/plugins/Automod/actions/availableActions.ts index a5183326..e499a42d 100644 --- a/backend/src/plugins/Automod/actions/availableActions.ts +++ b/backend/src/plugins/Automod/actions/availableActions.ts @@ -1,23 +1,23 @@ -import { AutomodActionBlueprint } from "../helpers"; -import { AddRolesAction } from "./addRoles"; -import { AddToCounterAction } from "./addToCounter"; -import { AlertAction } from "./alert"; -import { ArchiveThreadAction } from "./archiveThread"; -import { BanAction } from "./ban"; -import { ChangeNicknameAction } from "./changeNickname"; -import { ChangePermsAction } from "./changePerms"; -import { CleanAction } from "./clean"; -import { KickAction } from "./kick"; -import { LogAction } from "./log"; -import { MuteAction } from "./mute"; -import { PauseInvitesAction } from "./pauseInvites"; -import { RemoveRolesAction } from "./removeRoles"; -import { ReplyAction } from "./reply"; -import { SetAntiraidLevelAction } from "./setAntiraidLevel"; -import { SetCounterAction } from "./setCounter"; -import { SetSlowmodeAction } from "./setSlowmode"; -import { StartThreadAction } from "./startThread"; -import { WarnAction } from "./warn"; +import { AutomodActionBlueprint } from "../helpers.js"; +import { AddRolesAction } from "./addRoles.js"; +import { AddToCounterAction } from "./addToCounter.js"; +import { AlertAction } from "./alert.js"; +import { ArchiveThreadAction } from "./archiveThread.js"; +import { BanAction } from "./ban.js"; +import { ChangeNicknameAction } from "./changeNickname.js"; +import { ChangePermsAction } from "./changePerms.js"; +import { CleanAction } from "./clean.js"; +import { KickAction } from "./kick.js"; +import { LogAction } from "./log.js"; +import { MuteAction } from "./mute.js"; +import { PauseInvitesAction } from "./pauseInvites.js"; +import { RemoveRolesAction } from "./removeRoles.js"; +import { ReplyAction } from "./reply.js"; +import { SetAntiraidLevelAction } from "./setAntiraidLevel.js"; +import { SetCounterAction } from "./setCounter.js"; +import { SetSlowmodeAction } from "./setSlowmode.js"; +import { StartThreadAction } from "./startThread.js"; +import { WarnAction } from "./warn.js"; export const availableActions = { clean: CleanAction, diff --git a/backend/src/plugins/Automod/actions/ban.ts b/backend/src/plugins/Automod/actions/ban.ts index f5a18197..d64de15c 100644 --- a/backend/src/plugins/Automod/actions/ban.ts +++ b/backend/src/plugins/Automod/actions/ban.ts @@ -6,12 +6,12 @@ import { zBoundedCharacters, zDelayString, zSnowflake, -} from "../../../utils"; -import { CaseArgs } from "../../Cases/types"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; -import { zNotify } from "../constants"; -import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; -import { automodAction } from "../helpers"; +} from "../../../utils.js"; +import { CaseArgs } from "../../Cases/types.js"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin.js"; +import { zNotify } from "../constants.js"; +import { resolveActionContactMethods } from "../functions/resolveActionContactMethods.js"; +import { automodAction } from "../helpers.js"; const configSchema = z.strictObject({ reason: zBoundedCharacters(0, 4000).nullable().default(null), diff --git a/backend/src/plugins/Automod/actions/changeNickname.ts b/backend/src/plugins/Automod/actions/changeNickname.ts index ce7c610e..a2a9ad4a 100644 --- a/backend/src/plugins/Automod/actions/changeNickname.ts +++ b/backend/src/plugins/Automod/actions/changeNickname.ts @@ -1,7 +1,7 @@ import z from "zod"; -import { nonNullish, unique, zBoundedCharacters } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { automodAction } from "../helpers"; +import { nonNullish, unique, zBoundedCharacters } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { automodAction } from "../helpers.js"; export const ChangeNicknameAction = automodAction({ configSchema: z.union([ diff --git a/backend/src/plugins/Automod/actions/changePerms.ts b/backend/src/plugins/Automod/actions/changePerms.ts index 351b1637..87f302d5 100644 --- a/backend/src/plugins/Automod/actions/changePerms.ts +++ b/backend/src/plugins/Automod/actions/changePerms.ts @@ -1,15 +1,15 @@ import { PermissionsBitField, PermissionsString } from "discord.js"; import { U } from "ts-toolbelt"; import z from "zod"; -import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; -import { isValidSnowflake, keys, noop, zBoundedCharacters } from "../../../utils"; +import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter.js"; +import { isValidSnowflake, keys, noop, zBoundedCharacters } from "../../../utils.js"; import { guildToTemplateSafeGuild, savedMessageToTemplateSafeSavedMessage, userToTemplateSafeUser, -} from "../../../utils/templateSafeObjects"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { automodAction } from "../helpers"; +} from "../../../utils/templateSafeObjects.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { automodAction } from "../helpers.js"; type LegacyPermMap = Record; const legacyPermMap = { diff --git a/backend/src/plugins/Automod/actions/clean.ts b/backend/src/plugins/Automod/actions/clean.ts index 5c66d370..c44cd67a 100644 --- a/backend/src/plugins/Automod/actions/clean.ts +++ b/backend/src/plugins/Automod/actions/clean.ts @@ -1,8 +1,8 @@ import { GuildTextBasedChannel, Snowflake } from "discord.js"; import z from "zod"; -import { LogType } from "../../../data/LogType"; -import { noop } from "../../../utils"; -import { automodAction } from "../helpers"; +import { LogType } from "../../../data/LogType.js"; +import { noop } from "../../../utils.js"; +import { automodAction } from "../helpers.js"; export const CleanAction = automodAction({ configSchema: z.boolean().default(false), diff --git a/backend/src/plugins/Automod/actions/exampleAction.ts b/backend/src/plugins/Automod/actions/exampleAction.ts index a43fc676..f5406694 100644 --- a/backend/src/plugins/Automod/actions/exampleAction.ts +++ b/backend/src/plugins/Automod/actions/exampleAction.ts @@ -1,6 +1,6 @@ import z from "zod"; -import { zBoundedCharacters } from "../../../utils"; -import { automodAction } from "../helpers"; +import { zBoundedCharacters } from "../../../utils.js"; +import { automodAction } from "../helpers.js"; export const ExampleAction = automodAction({ configSchema: z.strictObject({ diff --git a/backend/src/plugins/Automod/actions/kick.ts b/backend/src/plugins/Automod/actions/kick.ts index 1515f6f7..7abed550 100644 --- a/backend/src/plugins/Automod/actions/kick.ts +++ b/backend/src/plugins/Automod/actions/kick.ts @@ -1,10 +1,10 @@ import z from "zod"; -import { asyncMap, nonNullish, resolveMember, unique, zBoundedCharacters, zSnowflake } from "../../../utils"; -import { CaseArgs } from "../../Cases/types"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; -import { zNotify } from "../constants"; -import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; -import { automodAction } from "../helpers"; +import { asyncMap, nonNullish, resolveMember, unique, zBoundedCharacters, zSnowflake } from "../../../utils.js"; +import { CaseArgs } from "../../Cases/types.js"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin.js"; +import { zNotify } from "../constants.js"; +import { resolveActionContactMethods } from "../functions/resolveActionContactMethods.js"; +import { automodAction } from "../helpers.js"; export const KickAction = automodAction({ configSchema: z.strictObject({ diff --git a/backend/src/plugins/Automod/actions/log.ts b/backend/src/plugins/Automod/actions/log.ts index dace25f1..fefa3168 100644 --- a/backend/src/plugins/Automod/actions/log.ts +++ b/backend/src/plugins/Automod/actions/log.ts @@ -1,7 +1,7 @@ import z from "zod"; -import { isTruthy, unique } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { automodAction } from "../helpers"; +import { isTruthy, unique } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { automodAction } from "../helpers.js"; export const LogAction = automodAction({ configSchema: z.boolean().default(true), diff --git a/backend/src/plugins/Automod/actions/mute.ts b/backend/src/plugins/Automod/actions/mute.ts index 504cab91..abb87916 100644 --- a/backend/src/plugins/Automod/actions/mute.ts +++ b/backend/src/plugins/Automod/actions/mute.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError.js"; import { convertDelayStringToMS, nonNullish, @@ -7,13 +7,13 @@ import { zBoundedCharacters, zDelayString, zSnowflake, -} from "../../../utils"; -import { CaseArgs } from "../../Cases/types"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { MutesPlugin } from "../../Mutes/MutesPlugin"; -import { zNotify } from "../constants"; -import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; -import { automodAction } from "../helpers"; +} from "../../../utils.js"; +import { CaseArgs } from "../../Cases/types.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { MutesPlugin } from "../../Mutes/MutesPlugin.js"; +import { zNotify } from "../constants.js"; +import { resolveActionContactMethods } from "../functions/resolveActionContactMethods.js"; +import { automodAction } from "../helpers.js"; export const MuteAction = automodAction({ configSchema: z.strictObject({ diff --git a/backend/src/plugins/Automod/actions/pauseInvites.ts b/backend/src/plugins/Automod/actions/pauseInvites.ts index 819bd1ff..2fef2b33 100644 --- a/backend/src/plugins/Automod/actions/pauseInvites.ts +++ b/backend/src/plugins/Automod/actions/pauseInvites.ts @@ -1,6 +1,6 @@ import { GuildFeature } from "discord.js"; import z from "zod"; -import { automodAction } from "../helpers"; +import { automodAction } from "../helpers.js"; export const PauseInvitesAction = automodAction({ configSchema: z.strictObject({ diff --git a/backend/src/plugins/Automod/actions/removeRoles.ts b/backend/src/plugins/Automod/actions/removeRoles.ts index 8b065702..5c2cef66 100644 --- a/backend/src/plugins/Automod/actions/removeRoles.ts +++ b/backend/src/plugins/Automod/actions/removeRoles.ts @@ -1,13 +1,13 @@ import { PermissionFlagsBits, Snowflake } from "discord.js"; import z from "zod"; -import { nonNullish, unique, zSnowflake } from "../../../utils"; -import { canAssignRole } from "../../../utils/canAssignRole"; -import { getMissingPermissions } from "../../../utils/getMissingPermissions"; -import { memberRolesLock } from "../../../utils/lockNameHelpers"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { ignoreRoleChange } from "../functions/ignoredRoleChanges"; -import { automodAction } from "../helpers"; +import { nonNullish, unique, zSnowflake } from "../../../utils.js"; +import { canAssignRole } from "../../../utils/canAssignRole.js"; +import { getMissingPermissions } from "../../../utils/getMissingPermissions.js"; +import { memberRolesLock } from "../../../utils/lockNameHelpers.js"; +import { missingPermissionError } from "../../../utils/missingPermissionError.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { ignoreRoleChange } from "../functions/ignoredRoleChanges.js"; +import { automodAction } from "../helpers.js"; const p = PermissionFlagsBits; diff --git a/backend/src/plugins/Automod/actions/reply.ts b/backend/src/plugins/Automod/actions/reply.ts index 0628e26f..aade027d 100644 --- a/backend/src/plugins/Automod/actions/reply.ts +++ b/backend/src/plugins/Automod/actions/reply.ts @@ -1,6 +1,6 @@ import { GuildTextBasedChannel, MessageCreateOptions, PermissionsBitField, Snowflake, User } from "discord.js"; import z from "zod"; -import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; +import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter.js"; import { convertDelayStringToMS, noop, @@ -11,13 +11,13 @@ import { zBoundedCharacters, zDelayString, zMessageContent, -} from "../../../utils"; -import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; -import { messageIsEmpty } from "../../../utils/messageIsEmpty"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { automodAction } from "../helpers"; -import { AutomodContext } from "../types"; +} from "../../../utils.js"; +import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions.js"; +import { messageIsEmpty } from "../../../utils/messageIsEmpty.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { automodAction } from "../helpers.js"; +import { AutomodContext } from "../types.js"; export const ReplyAction = automodAction({ configSchema: z.union([ diff --git a/backend/src/plugins/Automod/actions/setAntiraidLevel.ts b/backend/src/plugins/Automod/actions/setAntiraidLevel.ts index db2a6bef..611195e4 100644 --- a/backend/src/plugins/Automod/actions/setAntiraidLevel.ts +++ b/backend/src/plugins/Automod/actions/setAntiraidLevel.ts @@ -1,6 +1,6 @@ -import { zBoundedCharacters } from "../../../utils"; -import { setAntiraidLevel } from "../functions/setAntiraidLevel"; -import { automodAction } from "../helpers"; +import { zBoundedCharacters } from "../../../utils.js"; +import { setAntiraidLevel } from "../functions/setAntiraidLevel.js"; +import { automodAction } from "../helpers.js"; export const SetAntiraidLevelAction = automodAction({ configSchema: zBoundedCharacters(0, 100).nullable(), diff --git a/backend/src/plugins/Automod/actions/setCounter.ts b/backend/src/plugins/Automod/actions/setCounter.ts index 604d9bf4..8b60a43a 100644 --- a/backend/src/plugins/Automod/actions/setCounter.ts +++ b/backend/src/plugins/Automod/actions/setCounter.ts @@ -1,9 +1,9 @@ import z from "zod"; -import { MAX_COUNTER_VALUE, MIN_COUNTER_VALUE } from "../../../data/GuildCounters"; -import { zBoundedCharacters } from "../../../utils"; -import { CountersPlugin } from "../../Counters/CountersPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { automodAction } from "../helpers"; +import { MAX_COUNTER_VALUE, MIN_COUNTER_VALUE } from "../../../data/GuildCounters.js"; +import { zBoundedCharacters } from "../../../utils.js"; +import { CountersPlugin } from "../../Counters/CountersPlugin.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { automodAction } from "../helpers.js"; export const SetCounterAction = automodAction({ configSchema: z.strictObject({ diff --git a/backend/src/plugins/Automod/actions/setSlowmode.ts b/backend/src/plugins/Automod/actions/setSlowmode.ts index 7015e8f4..d23e1673 100644 --- a/backend/src/plugins/Automod/actions/setSlowmode.ts +++ b/backend/src/plugins/Automod/actions/setSlowmode.ts @@ -1,8 +1,8 @@ import { ChannelType, GuildTextBasedChannel, Snowflake } from "discord.js"; import z from "zod"; -import { convertDelayStringToMS, isDiscordAPIError, zDelayString, zSnowflake } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { automodAction } from "../helpers"; +import { convertDelayStringToMS, isDiscordAPIError, zDelayString, zSnowflake } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { automodAction } from "../helpers.js"; export const SetSlowmodeAction = automodAction({ configSchema: z.strictObject({ diff --git a/backend/src/plugins/Automod/actions/startThread.ts b/backend/src/plugins/Automod/actions/startThread.ts index a521d72f..81b18033 100644 --- a/backend/src/plugins/Automod/actions/startThread.ts +++ b/backend/src/plugins/Automod/actions/startThread.ts @@ -1,10 +1,10 @@ import { ChannelType, GuildTextThreadCreateOptions, ThreadAutoArchiveDuration, ThreadChannel } from "discord.js"; import z from "zod"; -import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; -import { MINUTES, convertDelayStringToMS, noop, zBoundedCharacters, zDelayString } from "../../../utils"; -import { savedMessageToTemplateSafeSavedMessage, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { automodAction } from "../helpers"; +import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter.js"; +import { MINUTES, convertDelayStringToMS, noop, zBoundedCharacters, zDelayString } from "../../../utils.js"; +import { savedMessageToTemplateSafeSavedMessage, userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { automodAction } from "../helpers.js"; const validThreadAutoArchiveDurations: ThreadAutoArchiveDuration[] = [ ThreadAutoArchiveDuration.OneHour, diff --git a/backend/src/plugins/Automod/actions/warn.ts b/backend/src/plugins/Automod/actions/warn.ts index dd3ad262..6e58d494 100644 --- a/backend/src/plugins/Automod/actions/warn.ts +++ b/backend/src/plugins/Automod/actions/warn.ts @@ -1,10 +1,10 @@ import z from "zod"; -import { asyncMap, nonNullish, resolveMember, unique, zBoundedCharacters, zSnowflake } from "../../../utils"; -import { CaseArgs } from "../../Cases/types"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; -import { zNotify } from "../constants"; -import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; -import { automodAction } from "../helpers"; +import { asyncMap, nonNullish, resolveMember, unique, zBoundedCharacters, zSnowflake } from "../../../utils.js"; +import { CaseArgs } from "../../Cases/types.js"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin.js"; +import { zNotify } from "../constants.js"; +import { resolveActionContactMethods } from "../functions/resolveActionContactMethods.js"; +import { automodAction } from "../helpers.js"; export const WarnAction = automodAction({ configSchema: z.strictObject({ diff --git a/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts b/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts index 85f9bbcb..7686fd8c 100644 --- a/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts +++ b/backend/src/plugins/Automod/commands/AntiraidClearCmd.ts @@ -1,6 +1,6 @@ import { guildPluginMessageCommand } from "knub"; -import { setAntiraidLevel } from "../functions/setAntiraidLevel"; -import { AutomodPluginType } from "../types"; +import { setAntiraidLevel } from "../functions/setAntiraidLevel.js"; +import { AutomodPluginType } from "../types.js"; export const AntiraidClearCmd = guildPluginMessageCommand()({ trigger: ["antiraid clear", "antiraid reset", "antiraid none", "antiraid off"], diff --git a/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts b/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts index 46c2106f..1b8beaf2 100644 --- a/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts +++ b/backend/src/plugins/Automod/commands/SetAntiraidCmd.ts @@ -1,7 +1,7 @@ import { guildPluginMessageCommand } from "knub"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { setAntiraidLevel } from "../functions/setAntiraidLevel"; -import { AutomodPluginType } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { setAntiraidLevel } from "../functions/setAntiraidLevel.js"; +import { AutomodPluginType } from "../types.js"; export const SetAntiraidCmd = guildPluginMessageCommand()({ trigger: "antiraid", diff --git a/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts b/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts index f25f8e96..15762d2c 100644 --- a/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts +++ b/backend/src/plugins/Automod/commands/ViewAntiraidCmd.ts @@ -1,5 +1,5 @@ import { guildPluginMessageCommand } from "knub"; -import { AutomodPluginType } from "../types"; +import { AutomodPluginType } from "../types.js"; export const ViewAntiraidCmd = guildPluginMessageCommand()({ trigger: "antiraid", diff --git a/backend/src/plugins/Automod/constants.ts b/backend/src/plugins/Automod/constants.ts index c2baae77..034122e5 100644 --- a/backend/src/plugins/Automod/constants.ts +++ b/backend/src/plugins/Automod/constants.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { MINUTES, SECONDS } from "../../utils"; +import { MINUTES, SECONDS } from "../../utils.js"; export const RECENT_SPAM_EXPIRY_TIME = 10 * SECONDS; export const RECENT_ACTION_EXPIRY_TIME = 5 * MINUTES; diff --git a/backend/src/plugins/Automod/events/RunAutomodOnJoinLeaveEvt.ts b/backend/src/plugins/Automod/events/RunAutomodOnJoinLeaveEvt.ts index 4cf34db2..edf4314c 100644 --- a/backend/src/plugins/Automod/events/RunAutomodOnJoinLeaveEvt.ts +++ b/backend/src/plugins/Automod/events/RunAutomodOnJoinLeaveEvt.ts @@ -1,7 +1,7 @@ import { guildPluginEventListener } from "knub"; -import { RecentActionType } from "../constants"; -import { runAutomod } from "../functions/runAutomod"; -import { AutomodContext, AutomodPluginType } from "../types"; +import { RecentActionType } from "../constants.js"; +import { runAutomod } from "../functions/runAutomod.js"; +import { AutomodContext, AutomodPluginType } from "../types.js"; export const RunAutomodOnJoinEvt = guildPluginEventListener()({ event: "guildMemberAdd", diff --git a/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts b/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts index f6c3518a..aeea867d 100644 --- a/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts +++ b/backend/src/plugins/Automod/events/RunAutomodOnMemberUpdate.ts @@ -1,8 +1,8 @@ import { guildPluginEventListener } from "knub"; import diff from "lodash.difference"; import isEqual from "lodash.isequal"; -import { runAutomod } from "../functions/runAutomod"; -import { AutomodContext, AutomodPluginType } from "../types"; +import { runAutomod } from "../functions/runAutomod.js"; +import { AutomodContext, AutomodPluginType } from "../types.js"; export const RunAutomodOnMemberUpdate = guildPluginEventListener()({ event: "guildMemberUpdate", diff --git a/backend/src/plugins/Automod/events/runAutomodOnAntiraidLevel.ts b/backend/src/plugins/Automod/events/runAutomodOnAntiraidLevel.ts index 05dbb6f3..1ca8e848 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnAntiraidLevel.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnAntiraidLevel.ts @@ -1,7 +1,7 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { runAutomod } from "../functions/runAutomod"; -import { AutomodContext, AutomodPluginType } from "../types"; +import { runAutomod } from "../functions/runAutomod.js"; +import { AutomodContext, AutomodPluginType } from "../types.js"; export async function runAutomodOnAntiraidLevel( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/events/runAutomodOnCounterTrigger.ts b/backend/src/plugins/Automod/events/runAutomodOnCounterTrigger.ts index 9de3dae0..b94cc8e7 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnCounterTrigger.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnCounterTrigger.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { resolveMember, resolveUser, UnknownUser } from "../../../utils"; -import { CountersPlugin } from "../../Counters/CountersPlugin"; -import { runAutomod } from "../functions/runAutomod"; -import { AutomodContext, AutomodPluginType } from "../types"; +import { resolveMember, resolveUser, UnknownUser } from "../../../utils.js"; +import { CountersPlugin } from "../../Counters/CountersPlugin.js"; +import { runAutomod } from "../functions/runAutomod.js"; +import { AutomodContext, AutomodPluginType } from "../types.js"; export async function runAutomodOnCounterTrigger( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts index 915a0cd7..c8497257 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnMessage.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnMessage.ts @@ -1,12 +1,12 @@ import { GuildPluginData } from "knub"; import moment from "moment-timezone"; import { performance } from "perf_hooks"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { profilingEnabled } from "../../../utils/easyProfiler"; -import { addRecentActionsFromMessage } from "../functions/addRecentActionsFromMessage"; -import { clearRecentActionsForMessage } from "../functions/clearRecentActionsForMessage"; -import { runAutomod } from "../functions/runAutomod"; -import { AutomodContext, AutomodPluginType } from "../types"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { profilingEnabled } from "../../../utils/easyProfiler.js"; +import { addRecentActionsFromMessage } from "../functions/addRecentActionsFromMessage.js"; +import { clearRecentActionsForMessage } from "../functions/clearRecentActionsForMessage.js"; +import { runAutomod } from "../functions/runAutomod.js"; +import { AutomodContext, AutomodPluginType } from "../types.js"; export async function runAutomodOnMessage( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/events/runAutomodOnModAction.ts b/backend/src/plugins/Automod/events/runAutomodOnModAction.ts index cd7e70e4..19273686 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnModAction.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnModAction.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { resolveMember, resolveUser, UnknownUser } from "../../../utils"; -import { ModActionType } from "../../ModActions/types"; -import { runAutomod } from "../functions/runAutomod"; -import { AutomodContext, AutomodPluginType } from "../types"; +import { resolveMember, resolveUser, UnknownUser } from "../../../utils.js"; +import { ModActionType } from "../../ModActions/types.js"; +import { runAutomod } from "../functions/runAutomod.js"; +import { AutomodContext, AutomodPluginType } from "../types.js"; export async function runAutomodOnModAction( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/events/runAutomodOnThreadEvents.ts b/backend/src/plugins/Automod/events/runAutomodOnThreadEvents.ts index 977c8426..f428b9ca 100644 --- a/backend/src/plugins/Automod/events/runAutomodOnThreadEvents.ts +++ b/backend/src/plugins/Automod/events/runAutomodOnThreadEvents.ts @@ -1,7 +1,7 @@ import { guildPluginEventListener } from "knub"; -import { RecentActionType } from "../constants"; -import { runAutomod } from "../functions/runAutomod"; -import { AutomodContext, AutomodPluginType } from "../types"; +import { RecentActionType } from "../constants.js"; +import { runAutomod } from "../functions/runAutomod.js"; +import { AutomodContext, AutomodPluginType } from "../types.js"; export const RunAutomodOnThreadCreate = guildPluginEventListener()({ event: "threadCreate", diff --git a/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts b/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts index 9b5b8800..cdcb097f 100644 --- a/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts +++ b/backend/src/plugins/Automod/functions/addRecentActionsFromMessage.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils"; -import { RecentActionType } from "../constants"; -import { AutomodContext, AutomodPluginType } from "../types"; +import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils.js"; +import { RecentActionType } from "../constants.js"; +import { AutomodContext, AutomodPluginType } from "../types.js"; export function addRecentActionsFromMessage(pluginData: GuildPluginData, context: AutomodContext) { const message = context.message!; diff --git a/backend/src/plugins/Automod/functions/applyCooldown.ts b/backend/src/plugins/Automod/functions/applyCooldown.ts index 387ac448..ff1bc44d 100644 --- a/backend/src/plugins/Automod/functions/applyCooldown.ts +++ b/backend/src/plugins/Automod/functions/applyCooldown.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { convertDelayStringToMS } from "../../../utils"; -import { AutomodContext, AutomodPluginType, TRule } from "../types"; +import { convertDelayStringToMS } from "../../../utils.js"; +import { AutomodContext, AutomodPluginType, TRule } from "../types.js"; export function applyCooldown(pluginData: GuildPluginData, rule: TRule, context: AutomodContext) { const cooldownKey = `${rule.name}-${context.user?.id}`; diff --git a/backend/src/plugins/Automod/functions/checkCooldown.ts b/backend/src/plugins/Automod/functions/checkCooldown.ts index 3640c142..0f45485f 100644 --- a/backend/src/plugins/Automod/functions/checkCooldown.ts +++ b/backend/src/plugins/Automod/functions/checkCooldown.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { AutomodContext, AutomodPluginType, TRule } from "../types"; +import { AutomodContext, AutomodPluginType, TRule } from "../types.js"; export function checkCooldown(pluginData: GuildPluginData, rule: TRule, context: AutomodContext) { const cooldownKey = `${rule.name}-${context.user?.id}`; diff --git a/backend/src/plugins/Automod/functions/clearOldNicknameChanges.ts b/backend/src/plugins/Automod/functions/clearOldNicknameChanges.ts index 0d720c2d..5572f294 100644 --- a/backend/src/plugins/Automod/functions/clearOldNicknameChanges.ts +++ b/backend/src/plugins/Automod/functions/clearOldNicknameChanges.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { RECENT_NICKNAME_CHANGE_EXPIRY_TIME } from "../constants"; -import { AutomodPluginType } from "../types"; +import { RECENT_NICKNAME_CHANGE_EXPIRY_TIME } from "../constants.js"; +import { AutomodPluginType } from "../types.js"; export function clearOldRecentNicknameChanges(pluginData: GuildPluginData) { const now = Date.now(); diff --git a/backend/src/plugins/Automod/functions/clearOldRecentActions.ts b/backend/src/plugins/Automod/functions/clearOldRecentActions.ts index 881f3ff1..8951ee38 100644 --- a/backend/src/plugins/Automod/functions/clearOldRecentActions.ts +++ b/backend/src/plugins/Automod/functions/clearOldRecentActions.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { startProfiling } from "../../../utils/easyProfiler"; -import { RECENT_ACTION_EXPIRY_TIME } from "../constants"; -import { AutomodPluginType } from "../types"; +import { startProfiling } from "../../../utils/easyProfiler.js"; +import { RECENT_ACTION_EXPIRY_TIME } from "../constants.js"; +import { AutomodPluginType } from "../types.js"; export function clearOldRecentActions(pluginData: GuildPluginData) { const stopProfiling = startProfiling(pluginData.getKnubInstance().profiler, "automod:fns:clearOldRecentActions"); diff --git a/backend/src/plugins/Automod/functions/clearOldRecentSpam.ts b/backend/src/plugins/Automod/functions/clearOldRecentSpam.ts index f240b2da..dce2f20c 100644 --- a/backend/src/plugins/Automod/functions/clearOldRecentSpam.ts +++ b/backend/src/plugins/Automod/functions/clearOldRecentSpam.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { startProfiling } from "../../../utils/easyProfiler"; -import { RECENT_SPAM_EXPIRY_TIME } from "../constants"; -import { AutomodPluginType } from "../types"; +import { startProfiling } from "../../../utils/easyProfiler.js"; +import { RECENT_SPAM_EXPIRY_TIME } from "../constants.js"; +import { AutomodPluginType } from "../types.js"; export function clearOldRecentSpam(pluginData: GuildPluginData) { const stopProfiling = startProfiling(pluginData.getKnubInstance().profiler, "automod:fns:clearOldRecentSpam"); diff --git a/backend/src/plugins/Automod/functions/clearRecentActionsForMessage.ts b/backend/src/plugins/Automod/functions/clearRecentActionsForMessage.ts index 6f1fcdb6..69e188c1 100644 --- a/backend/src/plugins/Automod/functions/clearRecentActionsForMessage.ts +++ b/backend/src/plugins/Automod/functions/clearRecentActionsForMessage.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { startProfiling } from "../../../utils/easyProfiler"; -import { AutomodContext, AutomodPluginType } from "../types"; +import { startProfiling } from "../../../utils/easyProfiler.js"; +import { AutomodContext, AutomodPluginType } from "../types.js"; export function clearRecentActionsForMessage(pluginData: GuildPluginData, context: AutomodContext) { const stopProfiling = startProfiling( diff --git a/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts b/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts index cb7eb288..0e13def1 100644 --- a/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts +++ b/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts @@ -1,13 +1,13 @@ import z from "zod"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { humanizeDurationShort } from "../../../humanizeDurationShort"; -import { getBaseUrl } from "../../../pluginUtils"; -import { convertDelayStringToMS, sorter, zDelayString } from "../../../utils"; -import { RecentActionType } from "../constants"; -import { automodTrigger } from "../helpers"; -import { findRecentSpam } from "./findRecentSpam"; -import { getMatchingMessageRecentActions } from "./getMatchingMessageRecentActions"; -import { getMessageSpamIdentifier } from "./getSpamIdentifier"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { humanizeDurationShort } from "../../../humanizeDurationShort.js"; +import { getBaseUrl } from "../../../pluginUtils.js"; +import { convertDelayStringToMS, sorter, zDelayString } from "../../../utils.js"; +import { RecentActionType } from "../constants.js"; +import { automodTrigger } from "../helpers.js"; +import { findRecentSpam } from "./findRecentSpam.js"; +import { getMatchingMessageRecentActions } from "./getMatchingMessageRecentActions.js"; +import { getMessageSpamIdentifier } from "./getSpamIdentifier.js"; interface TMessageSpamMatchResultType { archiveId: string; diff --git a/backend/src/plugins/Automod/functions/findRecentSpam.ts b/backend/src/plugins/Automod/functions/findRecentSpam.ts index 93553b83..d13a0bc1 100644 --- a/backend/src/plugins/Automod/functions/findRecentSpam.ts +++ b/backend/src/plugins/Automod/functions/findRecentSpam.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { startProfiling } from "../../../utils/easyProfiler"; -import { RecentActionType } from "../constants"; -import { AutomodPluginType } from "../types"; +import { startProfiling } from "../../../utils/easyProfiler.js"; +import { RecentActionType } from "../constants.js"; +import { AutomodPluginType } from "../types.js"; export function findRecentSpam( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/getMatchingMessageRecentActions.ts b/backend/src/plugins/Automod/functions/getMatchingMessageRecentActions.ts index 99dae716..6e509ac8 100644 --- a/backend/src/plugins/Automod/functions/getMatchingMessageRecentActions.ts +++ b/backend/src/plugins/Automod/functions/getMatchingMessageRecentActions.ts @@ -1,10 +1,10 @@ import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { startProfiling } from "../../../utils/easyProfiler"; -import { RecentActionType } from "../constants"; -import { AutomodPluginType } from "../types"; -import { getMatchingRecentActions } from "./getMatchingRecentActions"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { startProfiling } from "../../../utils/easyProfiler.js"; +import { RecentActionType } from "../constants.js"; +import { AutomodPluginType } from "../types.js"; +import { getMatchingRecentActions } from "./getMatchingRecentActions.js"; export function getMatchingMessageRecentActions( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/getMatchingRecentActions.ts b/backend/src/plugins/Automod/functions/getMatchingRecentActions.ts index b22817c4..9262124b 100644 --- a/backend/src/plugins/Automod/functions/getMatchingRecentActions.ts +++ b/backend/src/plugins/Automod/functions/getMatchingRecentActions.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { startProfiling } from "../../../utils/easyProfiler"; -import { RecentActionType } from "../constants"; -import { AutomodPluginType } from "../types"; +import { startProfiling } from "../../../utils/easyProfiler.js"; +import { RecentActionType } from "../constants.js"; +import { AutomodPluginType } from "../types.js"; export function getMatchingRecentActions( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/getSpamIdentifier.ts b/backend/src/plugins/Automod/functions/getSpamIdentifier.ts index 084332a4..e76e5f87 100644 --- a/backend/src/plugins/Automod/functions/getSpamIdentifier.ts +++ b/backend/src/plugins/Automod/functions/getSpamIdentifier.ts @@ -1,4 +1,4 @@ -import { SavedMessage } from "../../../data/entities/SavedMessage"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; export function getMessageSpamIdentifier(message: SavedMessage, perChannel: boolean) { return perChannel ? `${message.channel_id}-${message.user_id}` : message.user_id; diff --git a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts index 3d7e993f..3feb5eea 100644 --- a/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts +++ b/backend/src/plugins/Automod/functions/getTextMatchPartialSummary.ts @@ -1,8 +1,8 @@ import { ActivityType, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { messageSummary, verboseChannelMention } from "../../../utils"; -import { AutomodContext, AutomodPluginType } from "../types"; -import { MatchableTextType } from "./matchMultipleTextTypesOnMessage"; +import { messageSummary, verboseChannelMention } from "../../../utils.js"; +import { AutomodContext, AutomodPluginType } from "../types.js"; +import { MatchableTextType } from "./matchMultipleTextTypesOnMessage.js"; export function getTextMatchPartialSummary( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/ignoredRoleChanges.ts b/backend/src/plugins/Automod/functions/ignoredRoleChanges.ts index a8314a85..77336877 100644 --- a/backend/src/plugins/Automod/functions/ignoredRoleChanges.ts +++ b/backend/src/plugins/Automod/functions/ignoredRoleChanges.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { MINUTES } from "../../../utils"; -import { AutomodPluginType } from "../types"; +import { MINUTES } from "../../../utils.js"; +import { AutomodPluginType } from "../types.js"; const IGNORED_ROLE_CHANGE_LIFETIME = 5 * MINUTES; diff --git a/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts b/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts index a82c526e..2152b4c2 100644 --- a/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts +++ b/backend/src/plugins/Automod/functions/matchMultipleTextTypesOnMessage.ts @@ -1,9 +1,9 @@ import { ActivityType, Embed } from "discord.js"; import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { renderUsername, resolveMember } from "../../../utils"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { renderUsername, resolveMember } from "../../../utils.js"; import { DeepMutable } from "../../../utils/typeUtils.js"; -import { AutomodPluginType } from "../types"; +import { AutomodPluginType } from "../types.js"; type TextTriggerWithMultipleMatchTypes = { match_messages: boolean; diff --git a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts index 24d3ac6a..93a0846d 100644 --- a/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts +++ b/backend/src/plugins/Automod/functions/resolveActionContactMethods.ts @@ -1,8 +1,8 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { UserNotificationMethod, disableUserNotificationStrings } from "../../../utils"; -import { AutomodPluginType } from "../types"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError.js"; +import { UserNotificationMethod, disableUserNotificationStrings } from "../../../utils.js"; +import { AutomodPluginType } from "../types.js"; export function resolveActionContactMethods( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/runAutomod.ts b/backend/src/plugins/Automod/functions/runAutomod.ts index 4ccc38de..8d3e78eb 100644 --- a/backend/src/plugins/Automod/functions/runAutomod.ts +++ b/backend/src/plugins/Automod/functions/runAutomod.ts @@ -1,14 +1,14 @@ import { GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { performance } from "perf_hooks"; -import { calculateBlocking, profilingEnabled } from "../../../utils/easyProfiler"; -import { availableActions } from "../actions/availableActions"; -import { CleanAction } from "../actions/clean"; -import { AutomodTriggerMatchResult } from "../helpers"; -import { availableTriggers } from "../triggers/availableTriggers"; -import { AutomodContext, AutomodPluginType } from "../types"; -import { applyCooldown } from "./applyCooldown"; -import { checkCooldown } from "./checkCooldown"; +import { calculateBlocking, profilingEnabled } from "../../../utils/easyProfiler.js"; +import { availableActions } from "../actions/availableActions.js"; +import { CleanAction } from "../actions/clean.js"; +import { AutomodTriggerMatchResult } from "../helpers.js"; +import { availableTriggers } from "../triggers/availableTriggers.js"; +import { AutomodContext, AutomodPluginType } from "../types.js"; +import { applyCooldown } from "./applyCooldown.js"; +import { checkCooldown } from "./checkCooldown.js"; export async function runAutomod(pluginData: GuildPluginData, context: AutomodContext) { const userId = context.user?.id || context.member?.id || context.message?.user_id; diff --git a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts index c76555c2..a32155d1 100644 --- a/backend/src/plugins/Automod/functions/setAntiraidLevel.ts +++ b/backend/src/plugins/Automod/functions/setAntiraidLevel.ts @@ -1,8 +1,8 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { runAutomodOnAntiraidLevel } from "../events/runAutomodOnAntiraidLevel"; -import { AutomodPluginType } from "../types"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { runAutomodOnAntiraidLevel } from "../events/runAutomodOnAntiraidLevel.js"; +import { AutomodPluginType } from "../types.js"; export async function setAntiraidLevel( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Automod/functions/sumRecentActionCounts.ts b/backend/src/plugins/Automod/functions/sumRecentActionCounts.ts index 021e44e6..0da9a5d1 100644 --- a/backend/src/plugins/Automod/functions/sumRecentActionCounts.ts +++ b/backend/src/plugins/Automod/functions/sumRecentActionCounts.ts @@ -1,4 +1,4 @@ -import { RecentAction } from "../types"; +import { RecentAction } from "../types.js"; export function sumRecentActionCounts(actions: RecentAction[]) { return actions.reduce((total, action) => total + action.count, 0); diff --git a/backend/src/plugins/Automod/helpers.ts b/backend/src/plugins/Automod/helpers.ts index b4b9f764..61d68076 100644 --- a/backend/src/plugins/Automod/helpers.ts +++ b/backend/src/plugins/Automod/helpers.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; import z, { ZodTypeAny } from "zod"; -import { Awaitable } from "../../utils/typeUtils"; -import { AutomodContext, AutomodPluginType } from "./types"; +import { Awaitable } from "../../utils/typeUtils.js"; +import { AutomodContext, AutomodPluginType } from "./types.js"; interface BaseAutomodTriggerMatchResult { extraContexts?: AutomodContext[]; diff --git a/backend/src/plugins/Automod/info.ts b/backend/src/plugins/Automod/info.ts index d33d628f..7dd94560 100644 --- a/backend/src/plugins/Automod/info.ts +++ b/backend/src/plugins/Automod/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; export const automodPluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/Automod/triggers/antiraidLevel.ts b/backend/src/plugins/Automod/triggers/antiraidLevel.ts index c1467bf8..1aacbd4d 100644 --- a/backend/src/plugins/Automod/triggers/antiraidLevel.ts +++ b/backend/src/plugins/Automod/triggers/antiraidLevel.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; interface AntiraidLevelTriggerResult {} diff --git a/backend/src/plugins/Automod/triggers/anyMessage.ts b/backend/src/plugins/Automod/triggers/anyMessage.ts index 71c92019..84f61426 100644 --- a/backend/src/plugins/Automod/triggers/anyMessage.ts +++ b/backend/src/plugins/Automod/triggers/anyMessage.ts @@ -1,7 +1,7 @@ import { Snowflake } from "discord.js"; import z from "zod"; -import { verboseChannelMention } from "../../../utils"; -import { automodTrigger } from "../helpers"; +import { verboseChannelMention } from "../../../utils.js"; +import { automodTrigger } from "../helpers.js"; interface AnyMessageResultType {} diff --git a/backend/src/plugins/Automod/triggers/attachmentSpam.ts b/backend/src/plugins/Automod/triggers/attachmentSpam.ts index 79c46d84..9d8e991b 100644 --- a/backend/src/plugins/Automod/triggers/attachmentSpam.ts +++ b/backend/src/plugins/Automod/triggers/attachmentSpam.ts @@ -1,4 +1,4 @@ -import { RecentActionType } from "../constants"; -import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger"; +import { RecentActionType } from "../constants.js"; +import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger.js"; export const AttachmentSpamTrigger = createMessageSpamTrigger(RecentActionType.Attachment, "attachment"); diff --git a/backend/src/plugins/Automod/triggers/availableTriggers.ts b/backend/src/plugins/Automod/triggers/availableTriggers.ts index a2ac60fb..04f8fc1f 100644 --- a/backend/src/plugins/Automod/triggers/availableTriggers.ts +++ b/backend/src/plugins/Automod/triggers/availableTriggers.ts @@ -1,38 +1,38 @@ -import { AutomodTriggerBlueprint } from "../helpers"; -import { AntiraidLevelTrigger } from "./antiraidLevel"; -import { AnyMessageTrigger } from "./anyMessage"; -import { AttachmentSpamTrigger } from "./attachmentSpam"; -import { BanTrigger } from "./ban"; -import { CharacterSpamTrigger } from "./characterSpam"; -import { CounterTrigger } from "./counterTrigger"; -import { EmojiSpamTrigger } from "./emojiSpam"; -import { KickTrigger } from "./kick"; -import { LineSpamTrigger } from "./lineSpam"; -import { LinkSpamTrigger } from "./linkSpam"; -import { MatchAttachmentTypeTrigger } from "./matchAttachmentType"; -import { MatchInvitesTrigger } from "./matchInvites"; -import { MatchLinksTrigger } from "./matchLinks"; -import { MatchMimeTypeTrigger } from "./matchMimeType"; -import { MatchRegexTrigger } from "./matchRegex"; -import { MatchWordsTrigger } from "./matchWords"; -import { MemberJoinTrigger } from "./memberJoin"; -import { MemberJoinSpamTrigger } from "./memberJoinSpam"; -import { MemberLeaveTrigger } from "./memberLeave"; -import { MentionSpamTrigger } from "./mentionSpam"; -import { MessageSpamTrigger } from "./messageSpam"; -import { MuteTrigger } from "./mute"; -import { NoteTrigger } from "./note"; -import { RoleAddedTrigger } from "./roleAdded"; -import { RoleRemovedTrigger } from "./roleRemoved"; -import { StickerSpamTrigger } from "./stickerSpam"; -import { ThreadArchiveTrigger } from "./threadArchive"; -import { ThreadCreateTrigger } from "./threadCreate"; -import { ThreadCreateSpamTrigger } from "./threadCreateSpam"; -import { ThreadDeleteTrigger } from "./threadDelete"; -import { ThreadUnarchiveTrigger } from "./threadUnarchive"; -import { UnbanTrigger } from "./unban"; -import { UnmuteTrigger } from "./unmute"; -import { WarnTrigger } from "./warn"; +import { AutomodTriggerBlueprint } from "../helpers.js"; +import { AntiraidLevelTrigger } from "./antiraidLevel.js"; +import { AnyMessageTrigger } from "./anyMessage.js"; +import { AttachmentSpamTrigger } from "./attachmentSpam.js"; +import { BanTrigger } from "./ban.js"; +import { CharacterSpamTrigger } from "./characterSpam.js"; +import { CounterTrigger } from "./counterTrigger.js"; +import { EmojiSpamTrigger } from "./emojiSpam.js"; +import { KickTrigger } from "./kick.js"; +import { LineSpamTrigger } from "./lineSpam.js"; +import { LinkSpamTrigger } from "./linkSpam.js"; +import { MatchAttachmentTypeTrigger } from "./matchAttachmentType.js"; +import { MatchInvitesTrigger } from "./matchInvites.js"; +import { MatchLinksTrigger } from "./matchLinks.js"; +import { MatchMimeTypeTrigger } from "./matchMimeType.js"; +import { MatchRegexTrigger } from "./matchRegex.js"; +import { MatchWordsTrigger } from "./matchWords.js"; +import { MemberJoinTrigger } from "./memberJoin.js"; +import { MemberJoinSpamTrigger } from "./memberJoinSpam.js"; +import { MemberLeaveTrigger } from "./memberLeave.js"; +import { MentionSpamTrigger } from "./mentionSpam.js"; +import { MessageSpamTrigger } from "./messageSpam.js"; +import { MuteTrigger } from "./mute.js"; +import { NoteTrigger } from "./note.js"; +import { RoleAddedTrigger } from "./roleAdded.js"; +import { RoleRemovedTrigger } from "./roleRemoved.js"; +import { StickerSpamTrigger } from "./stickerSpam.js"; +import { ThreadArchiveTrigger } from "./threadArchive.js"; +import { ThreadCreateTrigger } from "./threadCreate.js"; +import { ThreadCreateSpamTrigger } from "./threadCreateSpam.js"; +import { ThreadDeleteTrigger } from "./threadDelete.js"; +import { ThreadUnarchiveTrigger } from "./threadUnarchive.js"; +import { UnbanTrigger } from "./unban.js"; +import { UnmuteTrigger } from "./unmute.js"; +import { WarnTrigger } from "./warn.js"; export const availableTriggers: Record> = { any_message: AnyMessageTrigger, diff --git a/backend/src/plugins/Automod/triggers/ban.ts b/backend/src/plugins/Automod/triggers/ban.ts index f6df0fd6..5ed8180d 100644 --- a/backend/src/plugins/Automod/triggers/ban.ts +++ b/backend/src/plugins/Automod/triggers/ban.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; // tslint:disable-next-line:no-empty-interface interface BanTriggerResultType {} diff --git a/backend/src/plugins/Automod/triggers/characterSpam.ts b/backend/src/plugins/Automod/triggers/characterSpam.ts index 5412ffb2..ec0f7ac0 100644 --- a/backend/src/plugins/Automod/triggers/characterSpam.ts +++ b/backend/src/plugins/Automod/triggers/characterSpam.ts @@ -1,4 +1,4 @@ -import { RecentActionType } from "../constants"; -import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger"; +import { RecentActionType } from "../constants.js"; +import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger.js"; export const CharacterSpamTrigger = createMessageSpamTrigger(RecentActionType.Character, "character"); diff --git a/backend/src/plugins/Automod/triggers/counterTrigger.ts b/backend/src/plugins/Automod/triggers/counterTrigger.ts index 22de3df1..a9866eea 100644 --- a/backend/src/plugins/Automod/triggers/counterTrigger.ts +++ b/backend/src/plugins/Automod/triggers/counterTrigger.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; // tslint:disable-next-line interface CounterTriggerResult {} diff --git a/backend/src/plugins/Automod/triggers/emojiSpam.ts b/backend/src/plugins/Automod/triggers/emojiSpam.ts index 018cb891..608d6c2d 100644 --- a/backend/src/plugins/Automod/triggers/emojiSpam.ts +++ b/backend/src/plugins/Automod/triggers/emojiSpam.ts @@ -1,4 +1,4 @@ -import { RecentActionType } from "../constants"; -import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger"; +import { RecentActionType } from "../constants.js"; +import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger.js"; export const EmojiSpamTrigger = createMessageSpamTrigger(RecentActionType.Emoji, "emoji"); diff --git a/backend/src/plugins/Automod/triggers/exampleTrigger.ts b/backend/src/plugins/Automod/triggers/exampleTrigger.ts index e6005e07..90424996 100644 --- a/backend/src/plugins/Automod/triggers/exampleTrigger.ts +++ b/backend/src/plugins/Automod/triggers/exampleTrigger.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; interface ExampleMatchResultType { isBanana: boolean; diff --git a/backend/src/plugins/Automod/triggers/kick.ts b/backend/src/plugins/Automod/triggers/kick.ts index add6803e..266ab7a7 100644 --- a/backend/src/plugins/Automod/triggers/kick.ts +++ b/backend/src/plugins/Automod/triggers/kick.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; // tslint:disable-next-line:no-empty-interface interface KickTriggerResultType {} diff --git a/backend/src/plugins/Automod/triggers/lineSpam.ts b/backend/src/plugins/Automod/triggers/lineSpam.ts index 2a54f1b4..391d9fcb 100644 --- a/backend/src/plugins/Automod/triggers/lineSpam.ts +++ b/backend/src/plugins/Automod/triggers/lineSpam.ts @@ -1,4 +1,4 @@ -import { RecentActionType } from "../constants"; -import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger"; +import { RecentActionType } from "../constants.js"; +import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger.js"; export const LineSpamTrigger = createMessageSpamTrigger(RecentActionType.Line, "line"); diff --git a/backend/src/plugins/Automod/triggers/linkSpam.ts b/backend/src/plugins/Automod/triggers/linkSpam.ts index 0278d8d5..b987eb4c 100644 --- a/backend/src/plugins/Automod/triggers/linkSpam.ts +++ b/backend/src/plugins/Automod/triggers/linkSpam.ts @@ -1,4 +1,4 @@ -import { RecentActionType } from "../constants"; -import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger"; +import { RecentActionType } from "../constants.js"; +import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger.js"; export const LinkSpamTrigger = createMessageSpamTrigger(RecentActionType.Link, "link"); diff --git a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts index 8c562eb1..5c871cc5 100644 --- a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts +++ b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts @@ -1,8 +1,8 @@ import { escapeInlineCode, Snowflake } from "discord.js"; import { extname } from "path"; import z from "zod"; -import { asSingleLine, messageSummary, verboseChannelMention } from "../../../utils"; -import { automodTrigger } from "../helpers"; +import { asSingleLine, messageSummary, verboseChannelMention } from "../../../utils.js"; +import { automodTrigger } from "../helpers.js"; interface MatchResultType { matchedType: string; diff --git a/backend/src/plugins/Automod/triggers/matchInvites.ts b/backend/src/plugins/Automod/triggers/matchInvites.ts index 4ea7c3cd..54c881c9 100644 --- a/backend/src/plugins/Automod/triggers/matchInvites.ts +++ b/backend/src/plugins/Automod/triggers/matchInvites.ts @@ -1,8 +1,8 @@ import z from "zod"; -import { getInviteCodesInString, GuildInvite, isGuildInvite, resolveInvite, zSnowflake } from "../../../utils"; -import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; -import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; -import { automodTrigger } from "../helpers"; +import { getInviteCodesInString, GuildInvite, isGuildInvite, resolveInvite, zSnowflake } from "../../../utils.js"; +import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary.js"; +import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage.js"; +import { automodTrigger } from "../helpers.js"; interface MatchResultType { type: MatchableTextType; diff --git a/backend/src/plugins/Automod/triggers/matchLinks.ts b/backend/src/plugins/Automod/triggers/matchLinks.ts index c43d8320..e40be002 100644 --- a/backend/src/plugins/Automod/triggers/matchLinks.ts +++ b/backend/src/plugins/Automod/triggers/matchLinks.ts @@ -1,14 +1,14 @@ import { escapeInlineCode } from "discord.js"; import z from "zod"; -import { allowTimeout } from "../../../RegExpRunner"; -import { phishermanDomainIsSafe } from "../../../data/Phisherman"; -import { getUrlsInString, zRegex } from "../../../utils"; -import { mergeRegexes } from "../../../utils/mergeRegexes"; -import { mergeWordsIntoRegex } from "../../../utils/mergeWordsIntoRegex"; -import { PhishermanPlugin } from "../../Phisherman/PhishermanPlugin"; -import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; -import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; -import { automodTrigger } from "../helpers"; +import { allowTimeout } from "../../../RegExpRunner.js"; +import { phishermanDomainIsSafe } from "../../../data/Phisherman.js"; +import { getUrlsInString, zRegex } from "../../../utils.js"; +import { mergeRegexes } from "../../../utils/mergeRegexes.js"; +import { mergeWordsIntoRegex } from "../../../utils/mergeWordsIntoRegex.js"; +import { PhishermanPlugin } from "../../Phisherman/PhishermanPlugin.js"; +import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary.js"; +import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage.js"; +import { automodTrigger } from "../helpers.js"; interface MatchResultType { type: MatchableTextType; diff --git a/backend/src/plugins/Automod/triggers/matchMimeType.ts b/backend/src/plugins/Automod/triggers/matchMimeType.ts index 86232916..725665e4 100644 --- a/backend/src/plugins/Automod/triggers/matchMimeType.ts +++ b/backend/src/plugins/Automod/triggers/matchMimeType.ts @@ -1,7 +1,7 @@ import { escapeInlineCode } from "discord.js"; import z from "zod"; -import { asSingleLine, messageSummary, verboseChannelMention } from "../../../utils"; -import { automodTrigger } from "../helpers"; +import { asSingleLine, messageSummary, verboseChannelMention } from "../../../utils.js"; +import { automodTrigger } from "../helpers.js"; interface MatchResultType { matchedType: string; diff --git a/backend/src/plugins/Automod/triggers/matchRegex.ts b/backend/src/plugins/Automod/triggers/matchRegex.ts index 41df0396..507d4bc6 100644 --- a/backend/src/plugins/Automod/triggers/matchRegex.ts +++ b/backend/src/plugins/Automod/triggers/matchRegex.ts @@ -1,12 +1,12 @@ import z from "zod"; -import { allowTimeout } from "../../../RegExpRunner"; -import { zRegex } from "../../../utils"; -import { mergeRegexes } from "../../../utils/mergeRegexes"; -import { normalizeText } from "../../../utils/normalizeText"; -import { stripMarkdown } from "../../../utils/stripMarkdown"; -import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; -import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; -import { automodTrigger } from "../helpers"; +import { allowTimeout } from "../../../RegExpRunner.js"; +import { zRegex } from "../../../utils.js"; +import { mergeRegexes } from "../../../utils/mergeRegexes.js"; +import { normalizeText } from "../../../utils/normalizeText.js"; +import { stripMarkdown } from "../../../utils/stripMarkdown.js"; +import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary.js"; +import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage.js"; +import { automodTrigger } from "../helpers.js"; interface MatchResultType { pattern: string; diff --git a/backend/src/plugins/Automod/triggers/matchWords.ts b/backend/src/plugins/Automod/triggers/matchWords.ts index df3ee366..ef3f0ca2 100644 --- a/backend/src/plugins/Automod/triggers/matchWords.ts +++ b/backend/src/plugins/Automod/triggers/matchWords.ts @@ -1,10 +1,10 @@ import escapeStringRegexp from "escape-string-regexp"; import z from "zod"; -import { normalizeText } from "../../../utils/normalizeText"; -import { stripMarkdown } from "../../../utils/stripMarkdown"; -import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary"; -import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage"; -import { automodTrigger } from "../helpers"; +import { normalizeText } from "../../../utils/normalizeText.js"; +import { stripMarkdown } from "../../../utils/stripMarkdown.js"; +import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary.js"; +import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage.js"; +import { automodTrigger } from "../helpers.js"; interface MatchResultType { word: string; diff --git a/backend/src/plugins/Automod/triggers/memberJoin.ts b/backend/src/plugins/Automod/triggers/memberJoin.ts index af9a1fae..4d694e42 100644 --- a/backend/src/plugins/Automod/triggers/memberJoin.ts +++ b/backend/src/plugins/Automod/triggers/memberJoin.ts @@ -1,6 +1,6 @@ import z from "zod"; -import { convertDelayStringToMS, zDelayString } from "../../../utils"; -import { automodTrigger } from "../helpers"; +import { convertDelayStringToMS, zDelayString } from "../../../utils.js"; +import { automodTrigger } from "../helpers.js"; const configSchema = z.strictObject({ only_new: z.boolean().default(false), diff --git a/backend/src/plugins/Automod/triggers/memberJoinSpam.ts b/backend/src/plugins/Automod/triggers/memberJoinSpam.ts index e346a8d3..3e53a62d 100644 --- a/backend/src/plugins/Automod/triggers/memberJoinSpam.ts +++ b/backend/src/plugins/Automod/triggers/memberJoinSpam.ts @@ -1,10 +1,10 @@ import z from "zod"; -import { convertDelayStringToMS, zDelayString } from "../../../utils"; -import { RecentActionType } from "../constants"; -import { findRecentSpam } from "../functions/findRecentSpam"; -import { getMatchingRecentActions } from "../functions/getMatchingRecentActions"; -import { sumRecentActionCounts } from "../functions/sumRecentActionCounts"; -import { automodTrigger } from "../helpers"; +import { convertDelayStringToMS, zDelayString } from "../../../utils.js"; +import { RecentActionType } from "../constants.js"; +import { findRecentSpam } from "../functions/findRecentSpam.js"; +import { getMatchingRecentActions } from "../functions/getMatchingRecentActions.js"; +import { sumRecentActionCounts } from "../functions/sumRecentActionCounts.js"; +import { automodTrigger } from "../helpers.js"; const configSchema = z.strictObject({ amount: z.number().int(), diff --git a/backend/src/plugins/Automod/triggers/memberLeave.ts b/backend/src/plugins/Automod/triggers/memberLeave.ts index fa9f37a8..2c6bb9f2 100644 --- a/backend/src/plugins/Automod/triggers/memberLeave.ts +++ b/backend/src/plugins/Automod/triggers/memberLeave.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; const configSchema = z.strictObject({}); diff --git a/backend/src/plugins/Automod/triggers/mentionSpam.ts b/backend/src/plugins/Automod/triggers/mentionSpam.ts index fdcd8f46..5b5c7326 100644 --- a/backend/src/plugins/Automod/triggers/mentionSpam.ts +++ b/backend/src/plugins/Automod/triggers/mentionSpam.ts @@ -1,4 +1,4 @@ -import { RecentActionType } from "../constants"; -import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger"; +import { RecentActionType } from "../constants.js"; +import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger.js"; export const MentionSpamTrigger = createMessageSpamTrigger(RecentActionType.Mention, "mention"); diff --git a/backend/src/plugins/Automod/triggers/messageSpam.ts b/backend/src/plugins/Automod/triggers/messageSpam.ts index 91b4f63b..85e686f9 100644 --- a/backend/src/plugins/Automod/triggers/messageSpam.ts +++ b/backend/src/plugins/Automod/triggers/messageSpam.ts @@ -1,4 +1,4 @@ -import { RecentActionType } from "../constants"; -import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger"; +import { RecentActionType } from "../constants.js"; +import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger.js"; export const MessageSpamTrigger = createMessageSpamTrigger(RecentActionType.Message, "message"); diff --git a/backend/src/plugins/Automod/triggers/mute.ts b/backend/src/plugins/Automod/triggers/mute.ts index dcaf96c5..b8be5713 100644 --- a/backend/src/plugins/Automod/triggers/mute.ts +++ b/backend/src/plugins/Automod/triggers/mute.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; // tslint:disable-next-line:no-empty-interface interface MuteTriggerResultType {} diff --git a/backend/src/plugins/Automod/triggers/note.ts b/backend/src/plugins/Automod/triggers/note.ts index eeaa2c27..22ccc40f 100644 --- a/backend/src/plugins/Automod/triggers/note.ts +++ b/backend/src/plugins/Automod/triggers/note.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; // tslint:disable-next-line:no-empty-interface interface NoteTriggerResultType {} diff --git a/backend/src/plugins/Automod/triggers/roleAdded.ts b/backend/src/plugins/Automod/triggers/roleAdded.ts index 5a9ee3af..584a7a20 100644 --- a/backend/src/plugins/Automod/triggers/roleAdded.ts +++ b/backend/src/plugins/Automod/triggers/roleAdded.ts @@ -1,8 +1,8 @@ import { Snowflake } from "discord.js"; import z from "zod"; -import { renderUsername, zSnowflake } from "../../../utils"; -import { consumeIgnoredRoleChange } from "../functions/ignoredRoleChanges"; -import { automodTrigger } from "../helpers"; +import { renderUsername, zSnowflake } from "../../../utils.js"; +import { consumeIgnoredRoleChange } from "../functions/ignoredRoleChanges.js"; +import { automodTrigger } from "../helpers.js"; interface RoleAddedMatchResult { matchedRoleId: string; diff --git a/backend/src/plugins/Automod/triggers/roleRemoved.ts b/backend/src/plugins/Automod/triggers/roleRemoved.ts index 82479c0e..3ce92474 100644 --- a/backend/src/plugins/Automod/triggers/roleRemoved.ts +++ b/backend/src/plugins/Automod/triggers/roleRemoved.ts @@ -1,8 +1,8 @@ import { Snowflake } from "discord.js"; import z from "zod"; -import { renderUsername, zSnowflake } from "../../../utils"; -import { consumeIgnoredRoleChange } from "../functions/ignoredRoleChanges"; -import { automodTrigger } from "../helpers"; +import { renderUsername, zSnowflake } from "../../../utils.js"; +import { consumeIgnoredRoleChange } from "../functions/ignoredRoleChanges.js"; +import { automodTrigger } from "../helpers.js"; interface RoleAddedMatchResult { matchedRoleId: string; diff --git a/backend/src/plugins/Automod/triggers/stickerSpam.ts b/backend/src/plugins/Automod/triggers/stickerSpam.ts index 05fcbc45..9d0ac935 100644 --- a/backend/src/plugins/Automod/triggers/stickerSpam.ts +++ b/backend/src/plugins/Automod/triggers/stickerSpam.ts @@ -1,4 +1,4 @@ -import { RecentActionType } from "../constants"; -import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger"; +import { RecentActionType } from "../constants.js"; +import { createMessageSpamTrigger } from "../functions/createMessageSpamTrigger.js"; export const StickerSpamTrigger = createMessageSpamTrigger(RecentActionType.Sticker, "sticker"); diff --git a/backend/src/plugins/Automod/triggers/threadArchive.ts b/backend/src/plugins/Automod/triggers/threadArchive.ts index c9f7b75e..599f64c4 100644 --- a/backend/src/plugins/Automod/triggers/threadArchive.ts +++ b/backend/src/plugins/Automod/triggers/threadArchive.ts @@ -1,7 +1,7 @@ import { User, escapeBold, type Snowflake } from "discord.js"; import z from "zod"; -import { renderUsername } from "../../../utils"; -import { automodTrigger } from "../helpers"; +import { renderUsername } from "../../../utils.js"; +import { automodTrigger } from "../helpers.js"; interface ThreadArchiveResult { matchedThreadId: Snowflake; diff --git a/backend/src/plugins/Automod/triggers/threadCreate.ts b/backend/src/plugins/Automod/triggers/threadCreate.ts index 1e8a23e6..5f1e6db2 100644 --- a/backend/src/plugins/Automod/triggers/threadCreate.ts +++ b/backend/src/plugins/Automod/triggers/threadCreate.ts @@ -1,7 +1,7 @@ import { User, escapeBold, type Snowflake } from "discord.js"; import z from "zod"; import { renderUsername } from "../../../utils.js"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; interface ThreadCreateResult { matchedThreadId: Snowflake; diff --git a/backend/src/plugins/Automod/triggers/threadCreateSpam.ts b/backend/src/plugins/Automod/triggers/threadCreateSpam.ts index a4352c11..ff01b165 100644 --- a/backend/src/plugins/Automod/triggers/threadCreateSpam.ts +++ b/backend/src/plugins/Automod/triggers/threadCreateSpam.ts @@ -1,10 +1,10 @@ import z from "zod"; -import { convertDelayStringToMS, zDelayString } from "../../../utils"; -import { RecentActionType } from "../constants"; -import { findRecentSpam } from "../functions/findRecentSpam"; -import { getMatchingRecentActions } from "../functions/getMatchingRecentActions"; -import { sumRecentActionCounts } from "../functions/sumRecentActionCounts"; -import { automodTrigger } from "../helpers"; +import { convertDelayStringToMS, zDelayString } from "../../../utils.js"; +import { RecentActionType } from "../constants.js"; +import { findRecentSpam } from "../functions/findRecentSpam.js"; +import { getMatchingRecentActions } from "../functions/getMatchingRecentActions.js"; +import { sumRecentActionCounts } from "../functions/sumRecentActionCounts.js"; +import { automodTrigger } from "../helpers.js"; const configSchema = z.strictObject({ amount: z.number().int(), diff --git a/backend/src/plugins/Automod/triggers/threadDelete.ts b/backend/src/plugins/Automod/triggers/threadDelete.ts index 8c6d07d7..fb1d27f2 100644 --- a/backend/src/plugins/Automod/triggers/threadDelete.ts +++ b/backend/src/plugins/Automod/triggers/threadDelete.ts @@ -1,7 +1,7 @@ import { User, escapeBold, type Snowflake } from "discord.js"; import z from "zod"; import { renderUsername } from "../../../utils.js"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; interface ThreadDeleteResult { matchedThreadId: Snowflake; diff --git a/backend/src/plugins/Automod/triggers/threadUnarchive.ts b/backend/src/plugins/Automod/triggers/threadUnarchive.ts index 7eb7bf07..6b690832 100644 --- a/backend/src/plugins/Automod/triggers/threadUnarchive.ts +++ b/backend/src/plugins/Automod/triggers/threadUnarchive.ts @@ -1,7 +1,7 @@ import { User, escapeBold, type Snowflake } from "discord.js"; import z from "zod"; -import { renderUsername } from "../../../utils"; -import { automodTrigger } from "../helpers"; +import { renderUsername } from "../../../utils.js"; +import { automodTrigger } from "../helpers.js"; interface ThreadUnarchiveResult { matchedThreadId: Snowflake; diff --git a/backend/src/plugins/Automod/triggers/unban.ts b/backend/src/plugins/Automod/triggers/unban.ts index 25f24ec9..fd52aef6 100644 --- a/backend/src/plugins/Automod/triggers/unban.ts +++ b/backend/src/plugins/Automod/triggers/unban.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; // tslint:disable-next-line:no-empty-interface interface UnbanTriggerResultType {} diff --git a/backend/src/plugins/Automod/triggers/unmute.ts b/backend/src/plugins/Automod/triggers/unmute.ts index f9695ef0..59d47030 100644 --- a/backend/src/plugins/Automod/triggers/unmute.ts +++ b/backend/src/plugins/Automod/triggers/unmute.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; // tslint:disable-next-line:no-empty-interface interface UnmuteTriggerResultType {} diff --git a/backend/src/plugins/Automod/triggers/warn.ts b/backend/src/plugins/Automod/triggers/warn.ts index 3586e82d..9d94235f 100644 --- a/backend/src/plugins/Automod/triggers/warn.ts +++ b/backend/src/plugins/Automod/triggers/warn.ts @@ -1,5 +1,5 @@ import z from "zod"; -import { automodTrigger } from "../helpers"; +import { automodTrigger } from "../helpers.js"; // tslint:disable-next-line:no-empty-interface interface WarnTriggerResultType {} diff --git a/backend/src/plugins/Automod/types.ts b/backend/src/plugins/Automod/types.ts index 5028a377..7ed30832 100644 --- a/backend/src/plugins/Automod/types.ts +++ b/backend/src/plugins/Automod/types.ts @@ -1,21 +1,21 @@ import { GuildMember, GuildTextBasedChannel, PartialGuildMember, ThreadChannel, User } from "discord.js"; import { BasePluginType, CooldownManager, pluginUtils } from "knub"; import z from "zod"; -import { Queue } from "../../Queue"; -import { RegExpRunner } from "../../RegExpRunner"; -import { GuildAntiraidLevels } from "../../data/GuildAntiraidLevels"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { SavedMessage } from "../../data/entities/SavedMessage"; -import { entries, zBoundedRecord, zDelayString } from "../../utils"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { CounterEvents } from "../Counters/types"; -import { ModActionType, ModActionsEvents } from "../ModActions/types"; -import { MutesEvents } from "../Mutes/types"; -import { availableActions } from "./actions/availableActions"; -import { RecentActionType } from "./constants"; -import { availableTriggers } from "./triggers/availableTriggers"; +import { Queue } from "../../Queue.js"; +import { RegExpRunner } from "../../RegExpRunner.js"; +import { GuildAntiraidLevels } from "../../data/GuildAntiraidLevels.js"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { SavedMessage } from "../../data/entities/SavedMessage.js"; +import { entries, zBoundedRecord, zDelayString } from "../../utils.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { CounterEvents } from "../Counters/types.js"; +import { ModActionType, ModActionsEvents } from "../ModActions/types.js"; +import { MutesEvents } from "../Mutes/types.js"; +import { availableActions } from "./actions/availableActions.js"; +import { RecentActionType } from "./constants.js"; +import { availableTriggers } from "./triggers/availableTriggers.js"; import Timeout = NodeJS.Timeout; diff --git a/backend/src/plugins/BotControl/BotControlPlugin.ts b/backend/src/plugins/BotControl/BotControlPlugin.ts index c1a94888..2c504751 100644 --- a/backend/src/plugins/BotControl/BotControlPlugin.ts +++ b/backend/src/plugins/BotControl/BotControlPlugin.ts @@ -1,27 +1,27 @@ import { Snowflake, TextChannel } from "discord.js"; import { globalPlugin } from "knub"; -import { AllowedGuilds } from "../../data/AllowedGuilds"; -import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; -import { Configs } from "../../data/Configs"; -import { GuildArchives } from "../../data/GuildArchives"; -import { getActiveReload, resetActiveReload } from "./activeReload"; -import { AddDashboardUserCmd } from "./commands/AddDashboardUserCmd"; -import { AddServerFromInviteCmd } from "./commands/AddServerFromInviteCmd"; -import { AllowServerCmd } from "./commands/AllowServerCmd"; -import { ChannelToServerCmd } from "./commands/ChannelToServerCmd"; -import { DisallowServerCmd } from "./commands/DisallowServerCmd"; -import { EligibleCmd } from "./commands/EligibleCmd"; -import { LeaveServerCmd } from "./commands/LeaveServerCmd"; -import { ListDashboardPermsCmd } from "./commands/ListDashboardPermsCmd"; -import { ListDashboardUsersCmd } from "./commands/ListDashboardUsersCmd"; -import { ProfilerDataCmd } from "./commands/ProfilerDataCmd"; -import { RateLimitPerformanceCmd } from "./commands/RateLimitPerformanceCmd"; -import { ReloadGlobalPluginsCmd } from "./commands/ReloadGlobalPluginsCmd"; -import { ReloadServerCmd } from "./commands/ReloadServerCmd"; -import { RemoveDashboardUserCmd } from "./commands/RemoveDashboardUserCmd"; -import { RestPerformanceCmd } from "./commands/RestPerformanceCmd"; -import { ServersCmd } from "./commands/ServersCmd"; -import { BotControlPluginType, zBotControlConfig } from "./types"; +import { AllowedGuilds } from "../../data/AllowedGuilds.js"; +import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments.js"; +import { Configs } from "../../data/Configs.js"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { getActiveReload, resetActiveReload } from "./activeReload.js"; +import { AddDashboardUserCmd } from "./commands/AddDashboardUserCmd.js"; +import { AddServerFromInviteCmd } from "./commands/AddServerFromInviteCmd.js"; +import { AllowServerCmd } from "./commands/AllowServerCmd.js"; +import { ChannelToServerCmd } from "./commands/ChannelToServerCmd.js"; +import { DisallowServerCmd } from "./commands/DisallowServerCmd.js"; +import { EligibleCmd } from "./commands/EligibleCmd.js"; +import { LeaveServerCmd } from "./commands/LeaveServerCmd.js"; +import { ListDashboardPermsCmd } from "./commands/ListDashboardPermsCmd.js"; +import { ListDashboardUsersCmd } from "./commands/ListDashboardUsersCmd.js"; +import { ProfilerDataCmd } from "./commands/ProfilerDataCmd.js"; +import { RateLimitPerformanceCmd } from "./commands/RateLimitPerformanceCmd.js"; +import { ReloadGlobalPluginsCmd } from "./commands/ReloadGlobalPluginsCmd.js"; +import { ReloadServerCmd } from "./commands/ReloadServerCmd.js"; +import { RemoveDashboardUserCmd } from "./commands/RemoveDashboardUserCmd.js"; +import { RestPerformanceCmd } from "./commands/RestPerformanceCmd.js"; +import { ServersCmd } from "./commands/ServersCmd.js"; +import { BotControlPluginType, zBotControlConfig } from "./types.js"; const defaultOptions = { config: { diff --git a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts index abe73595..c3734ac4 100644 --- a/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddDashboardUserCmd.ts @@ -1,8 +1,8 @@ -import { ApiPermissions } from "@zeppelinbot/shared"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter } from "../../../pluginUtils"; -import { renderUsername } from "../../../utils"; -import { botControlCmd } from "../types"; +import { ApiPermissions } from "@zeppelinbot/shared.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isStaffPreFilter } from "../../../pluginUtils.js"; +import { renderUsername } from "../../../utils.js"; +import { botControlCmd } from "../types.js"; export const AddDashboardUserCmd = botControlCmd({ trigger: ["add_dashboard_user"], diff --git a/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts b/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts index 3dfdaf81..410cf7f5 100644 --- a/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts +++ b/backend/src/plugins/BotControl/commands/AddServerFromInviteCmd.ts @@ -1,9 +1,9 @@ -import { ApiPermissions } from "@zeppelinbot/shared"; +import { ApiPermissions } from "@zeppelinbot/shared.js"; import moment from "moment-timezone"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { DBDateFormat, isGuildInvite, resolveInvite } from "../../../utils"; -import { isEligible } from "../functions/isEligible"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { DBDateFormat, isGuildInvite, resolveInvite } from "../../../utils.js"; +import { isEligible } from "../functions/isEligible.js"; +import { botControlCmd } from "../types.js"; export const AddServerFromInviteCmd = botControlCmd({ trigger: ["add_server_from_invite", "allow_server_from_invite", "adv"], diff --git a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts index 9580e7e2..2b48dff2 100644 --- a/backend/src/plugins/BotControl/commands/AllowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/AllowServerCmd.ts @@ -1,9 +1,9 @@ -import { ApiPermissions } from "@zeppelinbot/shared"; +import { ApiPermissions } from "@zeppelinbot/shared.js"; import moment from "moment-timezone"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter } from "../../../pluginUtils"; -import { DBDateFormat, isSnowflake } from "../../../utils"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isStaffPreFilter } from "../../../pluginUtils.js"; +import { DBDateFormat, isSnowflake } from "../../../utils.js"; +import { botControlCmd } from "../types.js"; export const AllowServerCmd = botControlCmd({ trigger: ["allow_server", "allowserver", "add_server", "addserver"], diff --git a/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts b/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts index f2a62213..a4f53675 100644 --- a/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ChannelToServerCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter } from "../../../pluginUtils"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isStaffPreFilter } from "../../../pluginUtils.js"; +import { botControlCmd } from "../types.js"; export const ChannelToServerCmd = botControlCmd({ trigger: ["channel_to_server", "channel2server"], diff --git a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts index 43033341..8a753392 100644 --- a/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/DisallowServerCmd.ts @@ -1,8 +1,8 @@ import { Snowflake } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter } from "../../../pluginUtils"; -import { noop } from "../../../utils"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isStaffPreFilter } from "../../../pluginUtils.js"; +import { noop } from "../../../utils.js"; +import { botControlCmd } from "../types.js"; export const DisallowServerCmd = botControlCmd({ trigger: ["disallow_server", "disallowserver", "remove_server", "removeserver"], diff --git a/backend/src/plugins/BotControl/commands/EligibleCmd.ts b/backend/src/plugins/BotControl/commands/EligibleCmd.ts index f934037f..0f753f7b 100644 --- a/backend/src/plugins/BotControl/commands/EligibleCmd.ts +++ b/backend/src/plugins/BotControl/commands/EligibleCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isGuildInvite, resolveInvite } from "../../../utils"; -import { isEligible } from "../functions/isEligible"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isGuildInvite, resolveInvite } from "../../../utils.js"; +import { isEligible } from "../functions/isEligible.js"; +import { botControlCmd } from "../types.js"; export const EligibleCmd = botControlCmd({ trigger: ["eligible", "is_eligible", "iseligible"], diff --git a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts index 652c049d..7f3a3578 100644 --- a/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/LeaveServerCmd.ts @@ -1,7 +1,7 @@ import { Snowflake } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter } from "../../../pluginUtils"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isStaffPreFilter } from "../../../pluginUtils.js"; +import { botControlCmd } from "../types.js"; export const LeaveServerCmd = botControlCmd({ trigger: ["leave_server", "leave_guild"], diff --git a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts index ea237ef2..c75e520a 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts @@ -1,8 +1,8 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { AllowedGuild } from "../../../data/entities/AllowedGuild"; -import { ApiPermissionAssignment } from "../../../data/entities/ApiPermissionAssignment"; -import { renderUsername, resolveUser } from "../../../utils"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { AllowedGuild } from "../../../data/entities/AllowedGuild.js"; +import { ApiPermissionAssignment } from "../../../data/entities/ApiPermissionAssignment.js"; +import { renderUsername, resolveUser } from "../../../utils.js"; +import { botControlCmd } from "../types.js"; export const ListDashboardPermsCmd = botControlCmd({ trigger: ["list_dashboard_permissions", "list_dashboard_perms", "list_dash_permissions", "list_dash_perms"], diff --git a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts index 34c98dd2..59171660 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardUsersCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { renderUsername, resolveUser } from "../../../utils"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { renderUsername, resolveUser } from "../../../utils.js"; +import { botControlCmd } from "../types.js"; export const ListDashboardUsersCmd = botControlCmd({ trigger: ["list_dashboard_users"], diff --git a/backend/src/plugins/BotControl/commands/ProfilerDataCmd.ts b/backend/src/plugins/BotControl/commands/ProfilerDataCmd.ts index 3b5a177f..c83c0d72 100644 --- a/backend/src/plugins/BotControl/commands/ProfilerDataCmd.ts +++ b/backend/src/plugins/BotControl/commands/ProfilerDataCmd.ts @@ -1,9 +1,9 @@ import moment from "moment-timezone"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { GuildArchives } from "../../../data/GuildArchives"; -import { getBaseUrl } from "../../../pluginUtils"; -import { sorter } from "../../../utils"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { GuildArchives } from "../../../data/GuildArchives.js"; +import { getBaseUrl } from "../../../pluginUtils.js"; +import { sorter } from "../../../utils.js"; +import { botControlCmd } from "../types.js"; const sortProps = { totalTime: "TOTAL TIME", diff --git a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts index 6114c681..39675bb9 100644 --- a/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts +++ b/backend/src/plugins/BotControl/commands/RateLimitPerformanceCmd.ts @@ -1,8 +1,8 @@ import moment from "moment-timezone"; -import { GuildArchives } from "../../../data/GuildArchives"; -import { getBaseUrl } from "../../../pluginUtils"; -import { getRateLimitStats } from "../../../rateLimitStats"; -import { botControlCmd } from "../types"; +import { GuildArchives } from "../../../data/GuildArchives.js"; +import { getBaseUrl } from "../../../pluginUtils.js"; +import { getRateLimitStats } from "../../../rateLimitStats.js"; +import { botControlCmd } from "../types.js"; export const RateLimitPerformanceCmd = botControlCmd({ trigger: ["rate_limit_performance"], diff --git a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts index dc13a45e..c95ea1dd 100644 --- a/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadGlobalPluginsCmd.ts @@ -1,6 +1,6 @@ -import { isStaffPreFilter } from "../../../pluginUtils"; -import { getActiveReload, setActiveReload } from "../activeReload"; -import { botControlCmd } from "../types"; +import { isStaffPreFilter } from "../../../pluginUtils.js"; +import { getActiveReload, setActiveReload } from "../activeReload.js"; +import { botControlCmd } from "../types.js"; export const ReloadGlobalPluginsCmd = botControlCmd({ trigger: "bot_reload_global_plugins", diff --git a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts index 0ea4f59d..b7c94bb3 100644 --- a/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts +++ b/backend/src/plugins/BotControl/commands/ReloadServerCmd.ts @@ -1,7 +1,7 @@ import { Snowflake } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter } from "../../../pluginUtils"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isStaffPreFilter } from "../../../pluginUtils.js"; +import { botControlCmd } from "../types.js"; export const ReloadServerCmd = botControlCmd({ trigger: ["reload_server", "reload_guild"], diff --git a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts index 4c0ed1d8..8b5ad44e 100644 --- a/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts +++ b/backend/src/plugins/BotControl/commands/RemoveDashboardUserCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter } from "../../../pluginUtils"; -import { renderUsername } from "../../../utils"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isStaffPreFilter } from "../../../pluginUtils.js"; +import { renderUsername } from "../../../utils.js"; +import { botControlCmd } from "../types.js"; export const RemoveDashboardUserCmd = botControlCmd({ trigger: ["remove_dashboard_user"], diff --git a/backend/src/plugins/BotControl/commands/RestPerformanceCmd.ts b/backend/src/plugins/BotControl/commands/RestPerformanceCmd.ts index 0c8c6e8e..2f07ff80 100644 --- a/backend/src/plugins/BotControl/commands/RestPerformanceCmd.ts +++ b/backend/src/plugins/BotControl/commands/RestPerformanceCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getTopRestCallStats } from "../../../restCallStats"; -import { createChunkedMessage } from "../../../utils"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { getTopRestCallStats } from "../../../restCallStats.js"; +import { createChunkedMessage } from "../../../utils.js"; +import { botControlCmd } from "../types.js"; const leadingPathRegex = /(?<=\().+\/backend\//g; diff --git a/backend/src/plugins/BotControl/commands/ServersCmd.ts b/backend/src/plugins/BotControl/commands/ServersCmd.ts index 5b2cf9c7..af7bfeca 100644 --- a/backend/src/plugins/BotControl/commands/ServersCmd.ts +++ b/backend/src/plugins/BotControl/commands/ServersCmd.ts @@ -1,8 +1,8 @@ import escapeStringRegexp from "escape-string-regexp"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isStaffPreFilter } from "../../../pluginUtils"; -import { createChunkedMessage, getUser, renderUsername, sorter } from "../../../utils"; -import { botControlCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isStaffPreFilter } from "../../../pluginUtils.js"; +import { createChunkedMessage, getUser, renderUsername, sorter } from "../../../utils.js"; +import { botControlCmd } from "../types.js"; export const ServersCmd = botControlCmd({ trigger: ["servers", "guilds"], diff --git a/backend/src/plugins/BotControl/functions/isEligible.ts b/backend/src/plugins/BotControl/functions/isEligible.ts index ba4dd31f..ccc6689d 100644 --- a/backend/src/plugins/BotControl/functions/isEligible.ts +++ b/backend/src/plugins/BotControl/functions/isEligible.ts @@ -1,7 +1,7 @@ import { User } from "discord.js"; import { GlobalPluginData } from "knub"; -import { GuildInvite } from "../../../utils"; -import { BotControlPluginType } from "../types"; +import { GuildInvite } from "../../../utils.js"; +import { BotControlPluginType } from "../types.js"; const REQUIRED_MEMBER_COUNT = 5000; diff --git a/backend/src/plugins/BotControl/types.ts b/backend/src/plugins/BotControl/types.ts index 1c1ccea6..05f8fb31 100644 --- a/backend/src/plugins/BotControl/types.ts +++ b/backend/src/plugins/BotControl/types.ts @@ -1,10 +1,10 @@ import { BasePluginType, globalPluginEventListener, globalPluginMessageCommand } from "knub"; import z from "zod"; -import { AllowedGuilds } from "../../data/AllowedGuilds"; -import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; -import { Configs } from "../../data/Configs"; -import { GuildArchives } from "../../data/GuildArchives"; -import { zBoundedCharacters } from "../../utils"; +import { AllowedGuilds } from "../../data/AllowedGuilds.js"; +import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments.js"; +import { Configs } from "../../data/Configs.js"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { zBoundedCharacters } from "../../utils.js"; export const zBotControlConfig = z.strictObject({ can_use: z.boolean(), diff --git a/backend/src/plugins/Cases/CasesPlugin.ts b/backend/src/plugins/Cases/CasesPlugin.ts index b9f9d872..8e5e66f3 100644 --- a/backend/src/plugins/Cases/CasesPlugin.ts +++ b/backend/src/plugins/Cases/CasesPlugin.ts @@ -1,19 +1,19 @@ import { guildPlugin } from "knub"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildCases } from "../../data/GuildCases"; -import { GuildLogs } from "../../data/GuildLogs"; -import { makePublicFn } from "../../pluginUtils"; -import { InternalPosterPlugin } from "../InternalPoster/InternalPosterPlugin"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { createCase } from "./functions/createCase"; -import { createCaseNote } from "./functions/createCaseNote"; -import { getCaseEmbed } from "./functions/getCaseEmbed"; -import { getCaseSummary } from "./functions/getCaseSummary"; -import { getCaseTypeAmountForUserId } from "./functions/getCaseTypeAmountForUserId"; -import { getRecentCasesByMod } from "./functions/getRecentCasesByMod"; -import { getTotalCasesByMod } from "./functions/getTotalCasesByMod"; -import { postCaseToCaseLogChannel } from "./functions/postToCaseLogChannel"; -import { CasesPluginType, zCasesConfig } from "./types"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildCases } from "../../data/GuildCases.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { makePublicFn } from "../../pluginUtils.js"; +import { InternalPosterPlugin } from "../InternalPoster/InternalPosterPlugin.js"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin.js"; +import { createCase } from "./functions/createCase.js"; +import { createCaseNote } from "./functions/createCaseNote.js"; +import { getCaseEmbed } from "./functions/getCaseEmbed.js"; +import { getCaseSummary } from "./functions/getCaseSummary.js"; +import { getCaseTypeAmountForUserId } from "./functions/getCaseTypeAmountForUserId.js"; +import { getRecentCasesByMod } from "./functions/getRecentCasesByMod.js"; +import { getTotalCasesByMod } from "./functions/getTotalCasesByMod.js"; +import { postCaseToCaseLogChannel } from "./functions/postToCaseLogChannel.js"; +import { CasesPluginType, zCasesConfig } from "./types.js"; // The `any` cast here is to prevent TypeScript from locking up from the circular dependency function getLogsPlugin(): Promise { diff --git a/backend/src/plugins/Cases/caseAbbreviations.ts b/backend/src/plugins/Cases/caseAbbreviations.ts index 91ef6c76..518d1c71 100644 --- a/backend/src/plugins/Cases/caseAbbreviations.ts +++ b/backend/src/plugins/Cases/caseAbbreviations.ts @@ -1,4 +1,4 @@ -import { CaseTypes } from "../../data/CaseTypes"; +import { CaseTypes } from "../../data/CaseTypes.js"; export const caseAbbreviations = { [CaseTypes.Ban]: "BAN", diff --git a/backend/src/plugins/Cases/caseColors.ts b/backend/src/plugins/Cases/caseColors.ts index 3284010f..c4954bde 100644 --- a/backend/src/plugins/Cases/caseColors.ts +++ b/backend/src/plugins/Cases/caseColors.ts @@ -1,4 +1,4 @@ -import { CaseTypes } from "../../data/CaseTypes"; +import { CaseTypes } from "../../data/CaseTypes.js"; export const caseColors: Record = { [CaseTypes.Ban]: 0xcb4314, diff --git a/backend/src/plugins/Cases/caseIcons.ts b/backend/src/plugins/Cases/caseIcons.ts index 3d18cd12..874350af 100644 --- a/backend/src/plugins/Cases/caseIcons.ts +++ b/backend/src/plugins/Cases/caseIcons.ts @@ -1,4 +1,4 @@ -import { CaseTypes } from "../../data/CaseTypes"; +import { CaseTypes } from "../../data/CaseTypes.js"; // These emoji icons are hosted on the Hangar server // If you'd like your self-hosted instance to use these icons, check #add-your-bot on that server diff --git a/backend/src/plugins/Cases/functions/createCase.ts b/backend/src/plugins/Cases/functions/createCase.ts index c68b899f..b10a71a0 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.js"; import { GuildPluginData } from "knub"; -import { logger } from "../../../logger"; -import { renderUsername, resolveUser } from "../../../utils"; -import { CaseArgs, CasesPluginType } from "../types"; -import { createCaseNote } from "./createCaseNote"; -import { postCaseToCaseLogChannel } from "./postToCaseLogChannel"; +import { logger } from "../../../logger.js"; +import { renderUsername, resolveUser } from "../../../utils.js"; +import { CaseArgs, CasesPluginType } from "../types.js"; +import { createCaseNote } from "./createCaseNote.js"; +import { postCaseToCaseLogChannel } from "./postToCaseLogChannel.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/createCaseNote.ts b/backend/src/plugins/Cases/functions/createCaseNote.ts index 71b11302..635c1b5e 100644 --- a/backend/src/plugins/Cases/functions/createCaseNote.ts +++ b/backend/src/plugins/Cases/functions/createCaseNote.ts @@ -1,9 +1,9 @@ import { GuildPluginData } from "knub"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { UnknownUser, renderUsername, resolveUser } from "../../../utils"; -import { CaseNoteArgs, CasesPluginType } from "../types"; -import { postCaseToCaseLogChannel } from "./postToCaseLogChannel"; -import { resolveCaseId } from "./resolveCaseId"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError.js"; +import { UnknownUser, renderUsername, resolveUser } from "../../../utils.js"; +import { CaseNoteArgs, CasesPluginType } from "../types.js"; +import { postCaseToCaseLogChannel } from "./postToCaseLogChannel.js"; +import { resolveCaseId } from "./resolveCaseId.js"; export async function createCaseNote(pluginData: GuildPluginData, args: CaseNoteArgs): Promise { const theCase = await pluginData.state.cases.find(resolveCaseId(args.caseId)); diff --git a/backend/src/plugins/Cases/functions/getCaseColor.ts b/backend/src/plugins/Cases/functions/getCaseColor.ts index 379b171d..10c9b00f 100644 --- a/backend/src/plugins/Cases/functions/getCaseColor.ts +++ b/backend/src/plugins/Cases/functions/getCaseColor.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { CaseTypes, CaseTypeToName } from "../../../data/CaseTypes"; -import { caseColors } from "../caseColors"; -import { CasesPluginType } from "../types"; +import { CaseTypes, CaseTypeToName } from "../../../data/CaseTypes.js"; +import { caseColors } from "../caseColors.js"; +import { CasesPluginType } from "../types.js"; export function getCaseColor(pluginData: GuildPluginData, caseType: CaseTypes) { return pluginData.config.get().case_colors?.[CaseTypeToName[caseType]] ?? caseColors[caseType]; diff --git a/backend/src/plugins/Cases/functions/getCaseEmbed.ts b/backend/src/plugins/Cases/functions/getCaseEmbed.ts index 3ce1f590..38a09285 100644 --- a/backend/src/plugins/Cases/functions/getCaseEmbed.ts +++ b/backend/src/plugins/Cases/functions/getCaseEmbed.ts @@ -1,13 +1,13 @@ import { escapeCodeBlock, MessageCreateOptions, MessageEditOptions } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { Case } from "../../../data/entities/Case"; -import { chunkMessageLines, emptyEmbedValue, messageLink } from "../../../utils"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { CasesPluginType } from "../types"; -import { getCaseColor } from "./getCaseColor"; -import { resolveCaseId } from "./resolveCaseId"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { Case } from "../../../data/entities/Case.js"; +import { chunkMessageLines, emptyEmbedValue, messageLink } from "../../../utils.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js"; +import { CasesPluginType } from "../types.js"; +import { getCaseColor } from "./getCaseColor.js"; +import { resolveCaseId } from "./resolveCaseId.js"; export async function getCaseEmbed( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Cases/functions/getCaseIcon.ts b/backend/src/plugins/Cases/functions/getCaseIcon.ts index 6748a7ef..50126e77 100644 --- a/backend/src/plugins/Cases/functions/getCaseIcon.ts +++ b/backend/src/plugins/Cases/functions/getCaseIcon.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { CaseTypes, CaseTypeToName } from "../../../data/CaseTypes"; -import { caseIcons } from "../caseIcons"; -import { CasesPluginType } from "../types"; +import { CaseTypes, CaseTypeToName } from "../../../data/CaseTypes.js"; +import { caseIcons } from "../caseIcons.js"; +import { CasesPluginType } from "../types.js"; export function getCaseIcon(pluginData: GuildPluginData, caseType: CaseTypes) { return pluginData.config.get().case_icons?.[CaseTypeToName[caseType]] ?? caseIcons[caseType]; diff --git a/backend/src/plugins/Cases/functions/getCaseSummary.ts b/backend/src/plugins/Cases/functions/getCaseSummary.ts index 2f317e22..ca1a37ad 100644 --- a/backend/src/plugins/Cases/functions/getCaseSummary.ts +++ b/backend/src/plugins/Cases/functions/getCaseSummary.ts @@ -1,12 +1,12 @@ import { GuildPluginData } from "knub"; import { splitMessageIntoChunks } from "knub/helpers"; import moment from "moment-timezone"; -import { Case } from "../../../data/entities/Case"; -import { convertDelayStringToMS, DBDateFormat, disableLinkPreviews, messageLink } from "../../../utils"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { caseAbbreviations } from "../caseAbbreviations"; -import { CasesPluginType } from "../types"; -import { getCaseIcon } from "./getCaseIcon"; +import { Case } from "../../../data/entities/Case.js"; +import { convertDelayStringToMS, DBDateFormat, disableLinkPreviews, messageLink } from "../../../utils.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js"; +import { caseAbbreviations } from "../caseAbbreviations.js"; +import { CasesPluginType } from "../types.js"; +import { getCaseIcon } from "./getCaseIcon.js"; const CASE_SUMMARY_REASON_MAX_LENGTH = 300; const INCLUDE_MORE_NOTES_THRESHOLD = 20; diff --git a/backend/src/plugins/Cases/functions/getCaseTypeAmountForUserId.ts b/backend/src/plugins/Cases/functions/getCaseTypeAmountForUserId.ts index eb28584d..cc5046db 100644 --- a/backend/src/plugins/Cases/functions/getCaseTypeAmountForUserId.ts +++ b/backend/src/plugins/Cases/functions/getCaseTypeAmountForUserId.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { CasesPluginType } from "../types"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { CasesPluginType } from "../types.js"; export async function getCaseTypeAmountForUserId( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts b/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts index e482fbd6..80edd822 100644 --- a/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts +++ b/backend/src/plugins/Cases/functions/getRecentCasesByMod.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; import { FindOptionsWhere } from "typeorm/find-options/FindOptionsWhere"; -import { Case } from "../../../data/entities/Case"; -import { CasesPluginType } from "../types"; +import { Case } from "../../../data/entities/Case.js"; +import { CasesPluginType } from "../types.js"; export function getRecentCasesByMod( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Cases/functions/getTotalCasesByMod.ts b/backend/src/plugins/Cases/functions/getTotalCasesByMod.ts index 235f2d8a..ca58c10d 100644 --- a/backend/src/plugins/Cases/functions/getTotalCasesByMod.ts +++ b/backend/src/plugins/Cases/functions/getTotalCasesByMod.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; import { FindOptionsWhere } from "typeorm/find-options/FindOptionsWhere"; -import { Case } from "../../../data/entities/Case"; -import { CasesPluginType } from "../types"; +import { Case } from "../../../data/entities/Case.js"; +import { CasesPluginType } from "../types.js"; export function getTotalCasesByMod( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts index 211d1844..f6ba3709 100644 --- a/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts +++ b/backend/src/plugins/Cases/functions/postToCaseLogChannel.ts @@ -1,13 +1,13 @@ import { MessageCreateOptions, NewsChannel, RESTJSONErrorCodes, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { Case } from "../../../data/entities/Case"; -import { isDiscordAPIError } from "../../../utils"; -import { InternalPosterPlugin } from "../../InternalPoster/InternalPosterPlugin"; -import { InternalPosterMessageResult } from "../../InternalPoster/functions/sendMessage"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { CasesPluginType } from "../types"; -import { getCaseEmbed } from "./getCaseEmbed"; -import { resolveCaseId } from "./resolveCaseId"; +import { Case } from "../../../data/entities/Case.js"; +import { isDiscordAPIError } from "../../../utils.js"; +import { InternalPosterPlugin } from "../../InternalPoster/InternalPosterPlugin.js"; +import { InternalPosterMessageResult } from "../../InternalPoster/functions/sendMessage.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { CasesPluginType } from "../types.js"; +import { getCaseEmbed } from "./getCaseEmbed.js"; +import { resolveCaseId } from "./resolveCaseId.js"; export async function postToCaseLogChannel( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Cases/functions/resolveCaseId.ts b/backend/src/plugins/Cases/functions/resolveCaseId.ts index 8d5ca13d..f2becaae 100644 --- a/backend/src/plugins/Cases/functions/resolveCaseId.ts +++ b/backend/src/plugins/Cases/functions/resolveCaseId.ts @@ -1,4 +1,4 @@ -import { Case } from "../../../data/entities/Case"; +import { Case } from "../../../data/entities/Case.js"; export function resolveCaseId(caseOrCaseId: Case | number): number { return caseOrCaseId instanceof Case ? caseOrCaseId.id : caseOrCaseId; diff --git a/backend/src/plugins/Cases/info.ts b/backend/src/plugins/Cases/info.ts index efa5d17e..fa446a24 100644 --- a/backend/src/plugins/Cases/info.ts +++ b/backend/src/plugins/Cases/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; export const casesPluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/Cases/types.ts b/backend/src/plugins/Cases/types.ts index bcc50eed..cb8ec139 100644 --- a/backend/src/plugins/Cases/types.ts +++ b/backend/src/plugins/Cases/types.ts @@ -1,12 +1,12 @@ import { BasePluginType } from "knub"; import { U } from "ts-toolbelt"; import z from "zod"; -import { CaseNameToType, CaseTypes } from "../../data/CaseTypes"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildCases } from "../../data/GuildCases"; -import { GuildLogs } from "../../data/GuildLogs"; -import { keys, zBoundedCharacters, zDelayString, zSnowflake } from "../../utils"; -import { zColor } from "../../utils/zColor"; +import { CaseNameToType, CaseTypes } from "../../data/CaseTypes.js"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildCases } from "../../data/GuildCases.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { keys, zBoundedCharacters, zDelayString, zSnowflake } from "../../utils.js"; +import { zColor } from "../../utils/zColor.js"; const caseKeys = keys(CaseNameToType) as U.ListOf; diff --git a/backend/src/plugins/Censor/CensorPlugin.ts b/backend/src/plugins/Censor/CensorPlugin.ts index 45e7a52e..c9503690 100644 --- a/backend/src/plugins/Censor/CensorPlugin.ts +++ b/backend/src/plugins/Censor/CensorPlugin.ts @@ -1,11 +1,11 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { CensorPluginType, zCensorConfig } from "./types"; -import { onMessageCreate } from "./util/onMessageCreate"; -import { onMessageUpdate } from "./util/onMessageUpdate"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { CensorPluginType, zCensorConfig } from "./types.js"; +import { onMessageCreate } from "./util/onMessageCreate.js"; +import { onMessageUpdate } from "./util/onMessageUpdate.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Censor/info.ts b/backend/src/plugins/Censor/info.ts index 1c8fe33a..888cea1d 100644 --- a/backend/src/plugins/Censor/info.ts +++ b/backend/src/plugins/Censor/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; export const censorPluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/Censor/types.ts b/backend/src/plugins/Censor/types.ts index c1fcd8df..62ed3816 100644 --- a/backend/src/plugins/Censor/types.ts +++ b/backend/src/plugins/Censor/types.ts @@ -1,9 +1,9 @@ import { BasePluginType } from "knub"; import z from "zod"; -import { RegExpRunner } from "../../RegExpRunner"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { zBoundedCharacters, zRegex, zSnowflake } from "../../utils"; +import { RegExpRunner } from "../../RegExpRunner.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { zBoundedCharacters, zRegex, zSnowflake } from "../../utils.js"; export const zCensorConfig = z.strictObject({ filter_zalgo: z.boolean(), diff --git a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts index 65ad62ed..d65785c8 100644 --- a/backend/src/plugins/Censor/util/applyFiltersToMsg.ts +++ b/backend/src/plugins/Censor/util/applyFiltersToMsg.ts @@ -2,12 +2,12 @@ import { Embed, Invite } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; import { GuildPluginData } from "knub"; import cloneDeep from "lodash.clonedeep"; -import { allowTimeout } from "../../../RegExpRunner"; -import { ZalgoRegex } from "../../../data/Zalgo"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { getInviteCodesInString, getUrlsInString, isGuildInvite, resolveInvite, resolveMember } from "../../../utils"; -import { CensorPluginType } from "../types"; -import { censorMessage } from "./censorMessage"; +import { allowTimeout } from "../../../RegExpRunner.js"; +import { ZalgoRegex } from "../../../data/Zalgo.js"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { getInviteCodesInString, getUrlsInString, isGuildInvite, resolveInvite, resolveMember } from "../../../utils.js"; +import { CensorPluginType } from "../types.js"; +import { censorMessage } from "./censorMessage.js"; export async function applyFiltersToMsg( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Censor/util/censorMessage.ts b/backend/src/plugins/Censor/util/censorMessage.ts index 93889c83..65308672 100644 --- a/backend/src/plugins/Censor/util/censorMessage.ts +++ b/backend/src/plugins/Censor/util/censorMessage.ts @@ -1,10 +1,10 @@ import { GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { resolveUser } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { CensorPluginType } from "../types"; +import { LogType } from "../../../data/LogType.js"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { resolveUser } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { CensorPluginType } from "../types.js"; export async function censorMessage( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Censor/util/onMessageCreate.ts b/backend/src/plugins/Censor/util/onMessageCreate.ts index 482e9cff..fa1c3212 100644 --- a/backend/src/plugins/Censor/util/onMessageCreate.ts +++ b/backend/src/plugins/Censor/util/onMessageCreate.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { messageLock } from "../../../utils/lockNameHelpers"; -import { CensorPluginType } from "../types"; -import { applyFiltersToMsg } from "./applyFiltersToMsg"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { messageLock } from "../../../utils/lockNameHelpers.js"; +import { CensorPluginType } from "../types.js"; +import { applyFiltersToMsg } from "./applyFiltersToMsg.js"; export async function onMessageCreate(pluginData: GuildPluginData, savedMessage: SavedMessage) { if (savedMessage.is_bot) return; diff --git a/backend/src/plugins/Censor/util/onMessageUpdate.ts b/backend/src/plugins/Censor/util/onMessageUpdate.ts index d17bf6b0..5e927c7d 100644 --- a/backend/src/plugins/Censor/util/onMessageUpdate.ts +++ b/backend/src/plugins/Censor/util/onMessageUpdate.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { messageLock } from "../../../utils/lockNameHelpers"; -import { CensorPluginType } from "../types"; -import { applyFiltersToMsg } from "./applyFiltersToMsg"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { messageLock } from "../../../utils/lockNameHelpers.js"; +import { CensorPluginType } from "../types.js"; +import { applyFiltersToMsg } from "./applyFiltersToMsg.js"; export async function onMessageUpdate(pluginData: GuildPluginData, savedMessage: SavedMessage) { if (savedMessage.is_bot) return; diff --git a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts index 79937321..d3885f24 100644 --- a/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts +++ b/backend/src/plugins/ChannelArchiver/ChannelArchiverPlugin.ts @@ -1,9 +1,9 @@ import { guildPlugin } from "knub"; import z from "zod"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { ArchiveChannelCmd } from "./commands/ArchiveChannelCmd"; -import { ChannelArchiverPluginType } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin.js"; +import { ArchiveChannelCmd } from "./commands/ArchiveChannelCmd.js"; +import { ChannelArchiverPluginType } from "./types.js"; export const ChannelArchiverPlugin = guildPlugin()({ name: "channel_archiver", diff --git a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts index 5e0235a4..138a3da9 100644 --- a/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts +++ b/backend/src/plugins/ChannelArchiver/commands/ArchiveChannelCmd.ts @@ -1,11 +1,11 @@ import { Snowflake } from "discord.js"; import moment from "moment-timezone"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isOwner } from "../../../pluginUtils"; -import { SECONDS, confirm, noop, renderUsername } from "../../../utils"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { rehostAttachment } from "../rehostAttachment"; -import { channelArchiverCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isOwner } from "../../../pluginUtils.js"; +import { SECONDS, confirm, noop, renderUsername } from "../../../utils.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js"; +import { rehostAttachment } from "../rehostAttachment.js"; +import { channelArchiverCmd } from "../types.js"; const MAX_ARCHIVED_MESSAGES = 5000; const MAX_MESSAGES_PER_FETCH = 100; diff --git a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts index 8159ddb2..18c73fa2 100644 --- a/backend/src/plugins/ChannelArchiver/rehostAttachment.ts +++ b/backend/src/plugins/ChannelArchiver/rehostAttachment.ts @@ -1,6 +1,6 @@ import { Attachment, GuildTextBasedChannel, MessageCreateOptions } from "discord.js"; import fs from "fs"; -import { downloadFile } from "../../utils"; +import { downloadFile } from "../../utils.js"; const fsp = fs.promises; const MAX_ATTACHMENT_REHOST_SIZE = 1024 * 1024 * 8; diff --git a/backend/src/plugins/ChannelArchiver/types.ts b/backend/src/plugins/ChannelArchiver/types.ts index 5dffc8d7..bf264775 100644 --- a/backend/src/plugins/ChannelArchiver/types.ts +++ b/backend/src/plugins/ChannelArchiver/types.ts @@ -1,5 +1,5 @@ import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export interface ChannelArchiverPluginType extends BasePluginType { state: { diff --git a/backend/src/plugins/Common/CommonPlugin.ts b/backend/src/plugins/Common/CommonPlugin.ts index 6482272e..042a72e0 100644 --- a/backend/src/plugins/Common/CommonPlugin.ts +++ b/backend/src/plugins/Common/CommonPlugin.ts @@ -9,11 +9,11 @@ import { User, } from "discord.js"; import { PluginOptions, guildPlugin } from "knub"; -import { logger } from "../../logger"; -import { isContextInteraction, sendContextResponse } from "../../pluginUtils"; -import { errorMessage, successMessage } from "../../utils"; -import { getErrorEmoji, getSuccessEmoji } from "./functions/getEmoji"; -import { CommonPluginType, zCommonConfig } from "./types"; +import { logger } from "../../logger.js"; +import { isContextInteraction, sendContextResponse } from "../../pluginUtils.js"; +import { errorMessage, successMessage } from "../../utils.js"; +import { getErrorEmoji, getSuccessEmoji } from "./functions/getEmoji.js"; +import { CommonPluginType, zCommonConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Common/functions/getEmoji.ts b/backend/src/plugins/Common/functions/getEmoji.ts index c1910250..809d787b 100644 --- a/backend/src/plugins/Common/functions/getEmoji.ts +++ b/backend/src/plugins/Common/functions/getEmoji.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { CommonPluginType } from "../types"; +import { CommonPluginType } from "../types.js"; export function getSuccessEmoji(pluginData: GuildPluginData) { return pluginData.config.get().success_emoji ?? "✅"; diff --git a/backend/src/plugins/Common/info.ts b/backend/src/plugins/Common/info.ts index 666ac502..9343af3e 100644 --- a/backend/src/plugins/Common/info.ts +++ b/backend/src/plugins/Common/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { zCommonConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { zCommonConfig } from "./types.js"; export const contextMenuPluginInfo: ZeppelinPluginInfo = { showInDocs: false, diff --git a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts index 6ff22711..fd6fe3f7 100644 --- a/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts +++ b/backend/src/plugins/CompanionChannels/CompanionChannelsPlugin.ts @@ -1,8 +1,8 @@ import { CooldownManager, guildPlugin } from "knub"; -import { GuildLogs } from "../../data/GuildLogs"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { VoiceStateUpdateEvt } from "./events/VoiceStateUpdateEvt"; -import { CompanionChannelsPluginType, zCompanionChannelsConfig } from "./types"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { VoiceStateUpdateEvt } from "./events/VoiceStateUpdateEvt.js"; +import { CompanionChannelsPluginType, zCompanionChannelsConfig } from "./types.js"; const defaultOptions = { config: { diff --git a/backend/src/plugins/CompanionChannels/events/VoiceStateUpdateEvt.ts b/backend/src/plugins/CompanionChannels/events/VoiceStateUpdateEvt.ts index 0e73570e..3f8b32b7 100644 --- a/backend/src/plugins/CompanionChannels/events/VoiceStateUpdateEvt.ts +++ b/backend/src/plugins/CompanionChannels/events/VoiceStateUpdateEvt.ts @@ -1,5 +1,5 @@ -import { handleCompanionPermissions } from "../functions/handleCompanionPermissions"; -import { companionChannelsEvt } from "../types"; +import { handleCompanionPermissions } from "../functions/handleCompanionPermissions.js"; +import { companionChannelsEvt } from "../types.js"; export const VoiceStateUpdateEvt = companionChannelsEvt({ event: "voiceStateUpdate", diff --git a/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts b/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts index 8ecde5e7..3f4e9972 100644 --- a/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts +++ b/backend/src/plugins/CompanionChannels/functions/getCompanionChannelOptsForVoiceChannelId.ts @@ -1,6 +1,6 @@ import { StageChannel, VoiceChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types"; +import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types.js"; const defaultCompanionChannelOpts: Partial = { enabled: true, diff --git a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts index 6be8ffe1..3e4f0889 100644 --- a/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts +++ b/backend/src/plugins/CompanionChannels/functions/handleCompanionPermissions.ts @@ -1,11 +1,11 @@ import { PermissionsBitField, Snowflake, StageChannel, TextChannel, VoiceChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { MINUTES, isDiscordAPIError } from "../../../utils"; -import { filterObject } from "../../../utils/filterObject"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types"; -import { getCompanionChannelOptsForVoiceChannelId } from "./getCompanionChannelOptsForVoiceChannelId"; +import { LogType } from "../../../data/LogType.js"; +import { MINUTES, isDiscordAPIError } from "../../../utils.js"; +import { filterObject } from "../../../utils/filterObject.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { CompanionChannelsPluginType, TCompanionChannelOpts } from "../types.js"; +import { getCompanionChannelOptsForVoiceChannelId } from "./getCompanionChannelOptsForVoiceChannelId.js"; const ERROR_COOLDOWN_KEY = "errorCooldown"; const ERROR_COOLDOWN = 5 * MINUTES; diff --git a/backend/src/plugins/CompanionChannels/info.ts b/backend/src/plugins/CompanionChannels/info.ts index 4dcd8362..c482618b 100644 --- a/backend/src/plugins/CompanionChannels/info.ts +++ b/backend/src/plugins/CompanionChannels/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; export const companionChannelsPluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/CompanionChannels/types.ts b/backend/src/plugins/CompanionChannels/types.ts index 7cee4b3a..e009f560 100644 --- a/backend/src/plugins/CompanionChannels/types.ts +++ b/backend/src/plugins/CompanionChannels/types.ts @@ -1,7 +1,7 @@ import { BasePluginType, CooldownManager, guildPluginEventListener } from "knub"; import z from "zod"; -import { GuildLogs } from "../../data/GuildLogs"; -import { zBoundedCharacters, zSnowflake } from "../../utils"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { zBoundedCharacters, zSnowflake } from "../../utils.js"; export const zCompanionChannelOpts = z.strictObject({ voice_channel_ids: z.array(zSnowflake), diff --git a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts index 110ad620..a8739785 100644 --- a/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts +++ b/backend/src/plugins/ContextMenus/ContextMenuPlugin.ts @@ -1,17 +1,17 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildCases } from "../../data/GuildCases"; -import { CasesPlugin } from "../Cases/CasesPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { ModActionsPlugin } from "../ModActions/ModActionsPlugin"; -import { MutesPlugin } from "../Mutes/MutesPlugin"; -import { UtilityPlugin } from "../Utility/UtilityPlugin"; -import { BanCmd } from "./commands/BanUserCtxCmd"; -import { CleanCmd } from "./commands/CleanMessageCtxCmd"; -import { ModMenuCmd } from "./commands/ModMenuUserCtxCmd"; -import { MuteCmd } from "./commands/MuteUserCtxCmd"; -import { NoteCmd } from "./commands/NoteUserCtxCmd"; -import { WarnCmd } from "./commands/WarnUserCtxCmd"; -import { ContextMenuPluginType, zContextMenusConfig } from "./types"; +import { GuildCases } from "../../data/GuildCases.js"; +import { CasesPlugin } from "../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { ModActionsPlugin } from "../ModActions/ModActionsPlugin.js"; +import { MutesPlugin } from "../Mutes/MutesPlugin.js"; +import { UtilityPlugin } from "../Utility/UtilityPlugin.js"; +import { BanCmd } from "./commands/BanUserCtxCmd.js"; +import { CleanCmd } from "./commands/CleanMessageCtxCmd.js"; +import { ModMenuCmd } from "./commands/ModMenuUserCtxCmd.js"; +import { MuteCmd } from "./commands/MuteUserCtxCmd.js"; +import { NoteCmd } from "./commands/NoteUserCtxCmd.js"; +import { WarnCmd } from "./commands/WarnUserCtxCmd.js"; +import { ContextMenuPluginType, zContextMenusConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/ContextMenus/actions/ban.ts b/backend/src/plugins/ContextMenus/actions/ban.ts index ab5951b5..644a293b 100644 --- a/backend/src/plugins/ContextMenus/actions/ban.ts +++ b/backend/src/plugins/ContextMenus/actions/ban.ts @@ -9,14 +9,14 @@ import { } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { logger } from "../../../logger"; -import { canActOn } from "../../../pluginUtils"; -import { convertDelayStringToMS, renderUserUsername } from "../../../utils"; -import { CaseArgs } from "../../Cases/types"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; -import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType, ModMenuActionType } from "../types"; -import { updateAction } from "./update"; +import { logger } from "../../../logger.js"; +import { canActOn } from "../../../pluginUtils.js"; +import { convertDelayStringToMS, renderUserUsername } from "../../../utils.js"; +import { CaseArgs } from "../../Cases/types.js"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin.js"; +import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd.js"; +import { ContextMenuPluginType, ModMenuActionType } from "../types.js"; +import { updateAction } from "./update.js"; async function banAction( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ContextMenus/actions/clean.ts b/backend/src/plugins/ContextMenus/actions/clean.ts index 8dee27b1..da29018a 100644 --- a/backend/src/plugins/ContextMenus/actions/clean.ts +++ b/backend/src/plugins/ContextMenus/actions/clean.ts @@ -8,10 +8,10 @@ import { TextInputStyle, } from "discord.js"; import { GuildPluginData } from "knub"; -import { logger } from "../../../logger"; -import { UtilityPlugin } from "../../../plugins/Utility/UtilityPlugin"; -import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType, ModMenuActionType } from "../types"; +import { logger } from "../../../logger.js"; +import { UtilityPlugin } from "../../../plugins/Utility/UtilityPlugin.js"; +import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd.js"; +import { ContextMenuPluginType, ModMenuActionType } from "../types.js"; export async function cleanAction( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ContextMenus/actions/mute.ts b/backend/src/plugins/ContextMenus/actions/mute.ts index 6d7ec1e1..380f5e3a 100644 --- a/backend/src/plugins/ContextMenus/actions/mute.ts +++ b/backend/src/plugins/ContextMenus/actions/mute.ts @@ -9,17 +9,17 @@ import { } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { logger } from "../../../logger"; -import { canActOn } from "../../../pluginUtils"; -import { convertDelayStringToMS } from "../../../utils"; -import { CaseArgs } from "../../Cases/types"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; -import { MutesPlugin } from "../../Mutes/MutesPlugin"; -import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType, ModMenuActionType } from "../types"; -import { updateAction } from "./update"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError.js"; +import { logger } from "../../../logger.js"; +import { canActOn } from "../../../pluginUtils.js"; +import { convertDelayStringToMS } from "../../../utils.js"; +import { CaseArgs } from "../../Cases/types.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin.js"; +import { MutesPlugin } from "../../Mutes/MutesPlugin.js"; +import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd.js"; +import { ContextMenuPluginType, ModMenuActionType } from "../types.js"; +import { updateAction } from "./update.js"; async function muteAction( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ContextMenus/actions/note.ts b/backend/src/plugins/ContextMenus/actions/note.ts index 1065639d..566d44ad 100644 --- a/backend/src/plugins/ContextMenus/actions/note.ts +++ b/backend/src/plugins/ContextMenus/actions/note.ts @@ -8,15 +8,15 @@ import { TextInputStyle, } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { logger } from "../../../logger"; -import { canActOn } from "../../../pluginUtils"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { renderUserUsername } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; -import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType, ModMenuActionType } from "../types"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { logger } from "../../../logger.js"; +import { canActOn } from "../../../pluginUtils.js"; +import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin.js"; +import { renderUserUsername } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin.js"; +import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd.js"; +import { ContextMenuPluginType, ModMenuActionType } from "../types.js"; async function noteAction( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ContextMenus/actions/update.ts b/backend/src/plugins/ContextMenus/actions/update.ts index d534930d..841b406b 100644 --- a/backend/src/plugins/ContextMenus/actions/update.ts +++ b/backend/src/plugins/ContextMenus/actions/update.ts @@ -1,10 +1,10 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { Case } from "../../../data/entities/Case"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { ContextMenuPluginType } from "../types"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { Case } from "../../../data/entities/Case.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { ContextMenuPluginType } from "../types.js"; export async function updateAction( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ContextMenus/actions/warn.ts b/backend/src/plugins/ContextMenus/actions/warn.ts index 94c094ef..e0e34707 100644 --- a/backend/src/plugins/ContextMenus/actions/warn.ts +++ b/backend/src/plugins/ContextMenus/actions/warn.ts @@ -8,14 +8,14 @@ import { TextInputStyle, } from "discord.js"; import { GuildPluginData } from "knub"; -import { logger } from "../../../logger"; -import { canActOn } from "../../../pluginUtils"; -import { renderUserUsername } from "../../../utils"; -import { CaseArgs } from "../../Cases/types"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; -import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd"; -import { ContextMenuPluginType, ModMenuActionType } from "../types"; -import { updateAction } from "./update"; +import { logger } from "../../../logger.js"; +import { canActOn } from "../../../pluginUtils.js"; +import { renderUserUsername } from "../../../utils.js"; +import { CaseArgs } from "../../Cases/types.js"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin.js"; +import { MODAL_TIMEOUT } from "../commands/ModMenuUserCtxCmd.js"; +import { ContextMenuPluginType, ModMenuActionType } from "../types.js"; +import { updateAction } from "./update.js"; async function warnAction( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ContextMenus/commands/BanUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/BanUserCtxCmd.ts index 741c8f74..dfff9088 100644 --- a/backend/src/plugins/ContextMenus/commands/BanUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/BanUserCtxCmd.ts @@ -1,6 +1,6 @@ import { PermissionFlagsBits } from "discord.js"; import { guildPluginUserContextMenuCommand } from "knub"; -import { launchBanActionModal } from "../actions/ban"; +import { launchBanActionModal } from "../actions/ban.js"; export const BanCmd = guildPluginUserContextMenuCommand({ name: "Ban", diff --git a/backend/src/plugins/ContextMenus/commands/CleanMessageCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/CleanMessageCtxCmd.ts index 0902ab00..83508ae3 100644 --- a/backend/src/plugins/ContextMenus/commands/CleanMessageCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/CleanMessageCtxCmd.ts @@ -1,6 +1,6 @@ import { PermissionFlagsBits } from "discord.js"; import { guildPluginMessageContextMenuCommand } from "knub"; -import { launchCleanActionModal } from "../actions/clean"; +import { launchCleanActionModal } from "../actions/clean.js"; export const CleanCmd = guildPluginMessageContextMenuCommand({ name: "Clean", diff --git a/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts index dab9f87d..e3091ca8 100644 --- a/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/ModMenuUserCtxCmd.ts @@ -10,26 +10,26 @@ import { User, } from "discord.js"; import { GuildPluginData, guildPluginUserContextMenuCommand } from "knub"; -import { Case } from "../../../data/entities/Case"; -import { logger } from "../../../logger"; -import { SECONDS, UnknownUser, emptyEmbedValue, renderUserUsername, resolveUser, trimLines } from "../../../utils"; -import { asyncMap } from "../../../utils/async"; -import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields"; -import { getGuildPrefix } from "../../../utils/getGuildPrefix"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; -import { getUserInfoEmbed } from "../../Utility/functions/getUserInfoEmbed"; -import { launchBanActionModal } from "../actions/ban"; -import { launchMuteActionModal } from "../actions/mute"; -import { launchNoteActionModal } from "../actions/note"; -import { launchWarnActionModal } from "../actions/warn"; +import { Case } from "../../../data/entities/Case.js"; +import { logger } from "../../../logger.js"; +import { SECONDS, UnknownUser, emptyEmbedValue, renderUserUsername, resolveUser, trimLines } from "../../../utils.js"; +import { asyncMap } from "../../../utils/async.js"; +import { getChunkedEmbedFields } from "../../../utils/getChunkedEmbedFields.js"; +import { getGuildPrefix } from "../../../utils/getGuildPrefix.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin.js"; +import { getUserInfoEmbed } from "../../Utility/functions/getUserInfoEmbed.js"; +import { launchBanActionModal } from "../actions/ban.js"; +import { launchMuteActionModal } from "../actions/mute.js"; +import { launchNoteActionModal } from "../actions/note.js"; +import { launchWarnActionModal } from "../actions/warn.js"; import { ContextMenuPluginType, LoadModMenuPageFn, ModMenuActionOpts, ModMenuActionType, ModMenuNavigationType, -} from "../types"; +} from "../types.js"; export const MODAL_TIMEOUT = 60 * SECONDS; const MOD_MENU_TIMEOUT = 60 * SECONDS; diff --git a/backend/src/plugins/ContextMenus/commands/MuteUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/MuteUserCtxCmd.ts index 55123597..559f6e70 100644 --- a/backend/src/plugins/ContextMenus/commands/MuteUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/MuteUserCtxCmd.ts @@ -1,6 +1,6 @@ import { PermissionFlagsBits } from "discord.js"; import { guildPluginUserContextMenuCommand } from "knub"; -import { launchMuteActionModal } from "../actions/mute"; +import { launchMuteActionModal } from "../actions/mute.js"; export const MuteCmd = guildPluginUserContextMenuCommand({ name: "Mute", diff --git a/backend/src/plugins/ContextMenus/commands/NoteUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/NoteUserCtxCmd.ts index d1163383..0e3807f3 100644 --- a/backend/src/plugins/ContextMenus/commands/NoteUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/NoteUserCtxCmd.ts @@ -1,6 +1,6 @@ import { PermissionFlagsBits } from "discord.js"; import { guildPluginUserContextMenuCommand } from "knub"; -import { launchNoteActionModal } from "../actions/note"; +import { launchNoteActionModal } from "../actions/note.js"; export const NoteCmd = guildPluginUserContextMenuCommand({ name: "Note", diff --git a/backend/src/plugins/ContextMenus/commands/WarnUserCtxCmd.ts b/backend/src/plugins/ContextMenus/commands/WarnUserCtxCmd.ts index b3e6a545..4721544a 100644 --- a/backend/src/plugins/ContextMenus/commands/WarnUserCtxCmd.ts +++ b/backend/src/plugins/ContextMenus/commands/WarnUserCtxCmd.ts @@ -1,6 +1,6 @@ import { PermissionFlagsBits } from "discord.js"; import { guildPluginUserContextMenuCommand } from "knub"; -import { launchWarnActionModal } from "../actions/warn"; +import { launchWarnActionModal } from "../actions/warn.js"; export const WarnCmd = guildPluginUserContextMenuCommand({ name: "Warn", diff --git a/backend/src/plugins/ContextMenus/info.ts b/backend/src/plugins/ContextMenus/info.ts index 53652cdc..fed63d26 100644 --- a/backend/src/plugins/ContextMenus/info.ts +++ b/backend/src/plugins/ContextMenus/info.ts @@ -1,6 +1,6 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; -import { zContextMenusConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; +import { zContextMenusConfig } from "./types.js"; export const contextMenuPluginInfo: ZeppelinPluginInfo = { showInDocs: false, diff --git a/backend/src/plugins/ContextMenus/types.ts b/backend/src/plugins/ContextMenus/types.ts index cdd9c3f7..69276b52 100644 --- a/backend/src/plugins/ContextMenus/types.ts +++ b/backend/src/plugins/ContextMenus/types.ts @@ -1,7 +1,7 @@ import { APIEmbed, Awaitable } from "discord.js"; import { BasePluginType } from "knub"; import z from "zod"; -import { GuildCases } from "../../data/GuildCases"; +import { GuildCases } from "../../data/GuildCases.js"; export const zContextMenusConfig = z.strictObject({ can_use: z.boolean(), diff --git a/backend/src/plugins/Counters/CountersPlugin.ts b/backend/src/plugins/Counters/CountersPlugin.ts index edee10be..fd1f85bb 100644 --- a/backend/src/plugins/Counters/CountersPlugin.ts +++ b/backend/src/plugins/Counters/CountersPlugin.ts @@ -1,25 +1,25 @@ import { EventEmitter } from "events"; import { PluginOptions, guildPlugin } from "knub"; -import { GuildCounters } from "../../data/GuildCounters"; -import { CounterTrigger, parseCounterConditionString } from "../../data/entities/CounterTrigger"; -import { makePublicFn } from "../../pluginUtils"; -import { MINUTES, convertDelayStringToMS, values } from "../../utils"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { AddCounterCmd } from "./commands/AddCounterCmd"; -import { CountersListCmd } from "./commands/CountersListCmd"; -import { ResetAllCounterValuesCmd } from "./commands/ResetAllCounterValuesCmd"; -import { ResetCounterCmd } from "./commands/ResetCounterCmd"; -import { SetCounterCmd } from "./commands/SetCounterCmd"; -import { ViewCounterCmd } from "./commands/ViewCounterCmd"; -import { changeCounterValue } from "./functions/changeCounterValue"; -import { counterExists } from "./functions/counterExists"; -import { decayCounter } from "./functions/decayCounter"; -import { getPrettyNameForCounter } from "./functions/getPrettyNameForCounter"; -import { getPrettyNameForCounterTrigger } from "./functions/getPrettyNameForCounterTrigger"; -import { offCounterEvent } from "./functions/offCounterEvent"; -import { onCounterEvent } from "./functions/onCounterEvent"; -import { setCounterValue } from "./functions/setCounterValue"; -import { CountersPluginType, zCountersConfig } from "./types"; +import { GuildCounters } from "../../data/GuildCounters.js"; +import { CounterTrigger, parseCounterConditionString } from "../../data/entities/CounterTrigger.js"; +import { makePublicFn } from "../../pluginUtils.js"; +import { MINUTES, convertDelayStringToMS, values } from "../../utils.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { AddCounterCmd } from "./commands/AddCounterCmd.js"; +import { CountersListCmd } from "./commands/CountersListCmd.js"; +import { ResetAllCounterValuesCmd } from "./commands/ResetAllCounterValuesCmd.js"; +import { ResetCounterCmd } from "./commands/ResetCounterCmd.js"; +import { SetCounterCmd } from "./commands/SetCounterCmd.js"; +import { ViewCounterCmd } from "./commands/ViewCounterCmd.js"; +import { changeCounterValue } from "./functions/changeCounterValue.js"; +import { counterExists } from "./functions/counterExists.js"; +import { decayCounter } from "./functions/decayCounter.js"; +import { getPrettyNameForCounter } from "./functions/getPrettyNameForCounter.js"; +import { getPrettyNameForCounterTrigger } from "./functions/getPrettyNameForCounterTrigger.js"; +import { offCounterEvent } from "./functions/offCounterEvent.js"; +import { onCounterEvent } from "./functions/onCounterEvent.js"; +import { setCounterValue } from "./functions/setCounterValue.js"; +import { CountersPluginType, zCountersConfig } from "./types.js"; const DECAY_APPLY_INTERVAL = 5 * MINUTES; diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index 9df3ea34..1c463132 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -1,10 +1,10 @@ import { Snowflake, TextChannel } from "discord.js"; import { guildPluginMessageCommand } from "knub"; import { waitForReply } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { UnknownUser, resolveUser } from "../../../utils"; -import { changeCounterValue } from "../functions/changeCounterValue"; -import { CountersPluginType } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { UnknownUser, resolveUser } from "../../../utils.js"; +import { changeCounterValue } from "../functions/changeCounterValue.js"; +import { CountersPluginType } from "../types.js"; export const AddCounterCmd = guildPluginMessageCommand()({ trigger: ["counters add", "counter add", "addcounter"], diff --git a/backend/src/plugins/Counters/commands/CountersListCmd.ts b/backend/src/plugins/Counters/commands/CountersListCmd.ts index 70ecb810..c92849fd 100644 --- a/backend/src/plugins/Counters/commands/CountersListCmd.ts +++ b/backend/src/plugins/Counters/commands/CountersListCmd.ts @@ -1,7 +1,7 @@ import { guildPluginMessageCommand } from "knub"; -import { trimMultilineString, ucfirst } from "../../../utils"; -import { getGuildPrefix } from "../../../utils/getGuildPrefix"; -import { CountersPluginType } from "../types"; +import { trimMultilineString, ucfirst } from "../../../utils.js"; +import { getGuildPrefix } from "../../../utils/getGuildPrefix.js"; +import { CountersPluginType } from "../types.js"; export const CountersListCmd = guildPluginMessageCommand()({ trigger: ["counters list", "counter list", "counters"], diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index 45b46006..7925511d 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -1,8 +1,8 @@ import { guildPluginMessageCommand } from "knub"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { confirm, noop, trimMultilineString } from "../../../utils"; -import { resetAllCounterValues } from "../functions/resetAllCounterValues"; -import { CountersPluginType } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { confirm, noop, trimMultilineString } from "../../../utils.js"; +import { resetAllCounterValues } from "../functions/resetAllCounterValues.js"; +import { CountersPluginType } from "../types.js"; export const ResetAllCounterValuesCmd = guildPluginMessageCommand()({ trigger: ["counters reset_all"], diff --git a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts index dd82166c..10ef3f2d 100644 --- a/backend/src/plugins/Counters/commands/ResetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetCounterCmd.ts @@ -1,10 +1,10 @@ import { Snowflake, TextChannel } from "discord.js"; import { guildPluginMessageCommand } from "knub"; import { waitForReply } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { UnknownUser, resolveUser } from "../../../utils"; -import { setCounterValue } from "../functions/setCounterValue"; -import { CountersPluginType } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { UnknownUser, resolveUser } from "../../../utils.js"; +import { setCounterValue } from "../functions/setCounterValue.js"; +import { CountersPluginType } from "../types.js"; export const ResetCounterCmd = guildPluginMessageCommand()({ trigger: ["counters reset", "counter reset", "resetcounter"], diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index faccde41..0be13b7e 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -1,10 +1,10 @@ import { Snowflake, TextChannel } from "discord.js"; import { guildPluginMessageCommand } from "knub"; import { waitForReply } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { UnknownUser, resolveUser } from "../../../utils"; -import { setCounterValue } from "../functions/setCounterValue"; -import { CountersPluginType } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { UnknownUser, resolveUser } from "../../../utils.js"; +import { setCounterValue } from "../functions/setCounterValue.js"; +import { CountersPluginType } from "../types.js"; export const SetCounterCmd = guildPluginMessageCommand()({ trigger: ["counters set", "counter set", "setcounter"], diff --git a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts index aa3d6218..3691d53f 100644 --- a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts @@ -1,9 +1,9 @@ import { Snowflake } from "discord.js"; import { guildPluginMessageCommand } from "knub"; import { waitForReply } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { resolveUser, UnknownUser } from "../../../utils"; -import { CountersPluginType } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { resolveUser, UnknownUser } from "../../../utils.js"; +import { CountersPluginType } from "../types.js"; export const ViewCounterCmd = guildPluginMessageCommand()({ trigger: ["counters view", "counter view", "viewcounter", "counter"], diff --git a/backend/src/plugins/Counters/functions/changeCounterValue.ts b/backend/src/plugins/Counters/functions/changeCounterValue.ts index 74a295f9..6892ce65 100644 --- a/backend/src/plugins/Counters/functions/changeCounterValue.ts +++ b/backend/src/plugins/Counters/functions/changeCounterValue.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { counterIdLock } from "../../../utils/lockNameHelpers"; -import { CountersPluginType } from "../types"; -import { checkCounterTrigger } from "./checkCounterTrigger"; -import { checkReverseCounterTrigger } from "./checkReverseCounterTrigger"; +import { counterIdLock } from "../../../utils/lockNameHelpers.js"; +import { CountersPluginType } from "../types.js"; +import { checkCounterTrigger } from "./checkCounterTrigger.js"; +import { checkReverseCounterTrigger } from "./checkReverseCounterTrigger.js"; export async function changeCounterValue( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/checkAllValuesForReverseTrigger.ts b/backend/src/plugins/Counters/functions/checkAllValuesForReverseTrigger.ts index 263855dc..8772e225 100644 --- a/backend/src/plugins/Counters/functions/checkAllValuesForReverseTrigger.ts +++ b/backend/src/plugins/Counters/functions/checkAllValuesForReverseTrigger.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { CounterTrigger } from "../../../data/entities/CounterTrigger"; -import { CountersPluginType } from "../types"; -import { emitCounterEvent } from "./emitCounterEvent"; +import { CounterTrigger } from "../../../data/entities/CounterTrigger.js"; +import { CountersPluginType } from "../types.js"; +import { emitCounterEvent } from "./emitCounterEvent.js"; export async function checkAllValuesForReverseTrigger( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/checkAllValuesForTrigger.ts b/backend/src/plugins/Counters/functions/checkAllValuesForTrigger.ts index 0a42673f..dedc6489 100644 --- a/backend/src/plugins/Counters/functions/checkAllValuesForTrigger.ts +++ b/backend/src/plugins/Counters/functions/checkAllValuesForTrigger.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { CounterTrigger } from "../../../data/entities/CounterTrigger"; -import { CountersPluginType } from "../types"; -import { emitCounterEvent } from "./emitCounterEvent"; +import { CounterTrigger } from "../../../data/entities/CounterTrigger.js"; +import { CountersPluginType } from "../types.js"; +import { emitCounterEvent } from "./emitCounterEvent.js"; export async function checkAllValuesForTrigger( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/checkCounterTrigger.ts b/backend/src/plugins/Counters/functions/checkCounterTrigger.ts index 8923abf5..a123c8be 100644 --- a/backend/src/plugins/Counters/functions/checkCounterTrigger.ts +++ b/backend/src/plugins/Counters/functions/checkCounterTrigger.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { CounterTrigger } from "../../../data/entities/CounterTrigger"; -import { CountersPluginType } from "../types"; -import { emitCounterEvent } from "./emitCounterEvent"; +import { CounterTrigger } from "../../../data/entities/CounterTrigger.js"; +import { CountersPluginType } from "../types.js"; +import { emitCounterEvent } from "./emitCounterEvent.js"; export async function checkCounterTrigger( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/checkReverseCounterTrigger.ts b/backend/src/plugins/Counters/functions/checkReverseCounterTrigger.ts index 544d4066..6803d4f3 100644 --- a/backend/src/plugins/Counters/functions/checkReverseCounterTrigger.ts +++ b/backend/src/plugins/Counters/functions/checkReverseCounterTrigger.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { CounterTrigger } from "../../../data/entities/CounterTrigger"; -import { CountersPluginType } from "../types"; -import { emitCounterEvent } from "./emitCounterEvent"; +import { CounterTrigger } from "../../../data/entities/CounterTrigger.js"; +import { CountersPluginType } from "../types.js"; +import { emitCounterEvent } from "./emitCounterEvent.js"; export async function checkReverseCounterTrigger( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/counterExists.ts b/backend/src/plugins/Counters/functions/counterExists.ts index 2da10460..c2824e4d 100644 --- a/backend/src/plugins/Counters/functions/counterExists.ts +++ b/backend/src/plugins/Counters/functions/counterExists.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { CountersPluginType } from "../types"; +import { CountersPluginType } from "../types.js"; export function counterExists(pluginData: GuildPluginData, counterName: string) { const config = pluginData.config.get(); diff --git a/backend/src/plugins/Counters/functions/decayCounter.ts b/backend/src/plugins/Counters/functions/decayCounter.ts index 0317ee8c..880c5e2c 100644 --- a/backend/src/plugins/Counters/functions/decayCounter.ts +++ b/backend/src/plugins/Counters/functions/decayCounter.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { counterIdLock } from "../../../utils/lockNameHelpers"; -import { CountersPluginType } from "../types"; -import { checkAllValuesForReverseTrigger } from "./checkAllValuesForReverseTrigger"; -import { checkAllValuesForTrigger } from "./checkAllValuesForTrigger"; +import { counterIdLock } from "../../../utils/lockNameHelpers.js"; +import { CountersPluginType } from "../types.js"; +import { checkAllValuesForReverseTrigger } from "./checkAllValuesForReverseTrigger.js"; +import { checkAllValuesForTrigger } from "./checkAllValuesForTrigger.js"; export async function decayCounter( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/emitCounterEvent.ts b/backend/src/plugins/Counters/functions/emitCounterEvent.ts index 30e4bfea..df575b1f 100644 --- a/backend/src/plugins/Counters/functions/emitCounterEvent.ts +++ b/backend/src/plugins/Counters/functions/emitCounterEvent.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { CounterEvents, CountersPluginType } from "../types"; +import { CounterEvents, CountersPluginType } from "../types.js"; export function emitCounterEvent( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/getPrettyNameForCounter.ts b/backend/src/plugins/Counters/functions/getPrettyNameForCounter.ts index c9fd0342..1da14282 100644 --- a/backend/src/plugins/Counters/functions/getPrettyNameForCounter.ts +++ b/backend/src/plugins/Counters/functions/getPrettyNameForCounter.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { CountersPluginType } from "../types"; +import { CountersPluginType } from "../types.js"; export function getPrettyNameForCounter(pluginData: GuildPluginData, counterName: string) { const config = pluginData.config.get(); diff --git a/backend/src/plugins/Counters/functions/getPrettyNameForCounterTrigger.ts b/backend/src/plugins/Counters/functions/getPrettyNameForCounterTrigger.ts index 5e891c18..00a2be7d 100644 --- a/backend/src/plugins/Counters/functions/getPrettyNameForCounterTrigger.ts +++ b/backend/src/plugins/Counters/functions/getPrettyNameForCounterTrigger.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { CountersPluginType } from "../types"; +import { CountersPluginType } from "../types.js"; export function getPrettyNameForCounterTrigger( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/offCounterEvent.ts b/backend/src/plugins/Counters/functions/offCounterEvent.ts index 08c28cff..108c5cbc 100644 --- a/backend/src/plugins/Counters/functions/offCounterEvent.ts +++ b/backend/src/plugins/Counters/functions/offCounterEvent.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { CounterEventEmitter, CountersPluginType } from "../types"; +import { CounterEventEmitter, CountersPluginType } from "../types.js"; export function offCounterEvent( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/onCounterEvent.ts b/backend/src/plugins/Counters/functions/onCounterEvent.ts index 1789571b..fb4a3e01 100644 --- a/backend/src/plugins/Counters/functions/onCounterEvent.ts +++ b/backend/src/plugins/Counters/functions/onCounterEvent.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { CounterEvents, CountersPluginType } from "../types"; +import { CounterEvents, CountersPluginType } from "../types.js"; export function onCounterEvent( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/functions/resetAllCounterValues.ts b/backend/src/plugins/Counters/functions/resetAllCounterValues.ts index c145a876..e3eaed22 100644 --- a/backend/src/plugins/Counters/functions/resetAllCounterValues.ts +++ b/backend/src/plugins/Counters/functions/resetAllCounterValues.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { counterIdLock } from "../../../utils/lockNameHelpers"; -import { CountersPluginType } from "../types"; +import { counterIdLock } from "../../../utils/lockNameHelpers.js"; +import { CountersPluginType } from "../types.js"; export async function resetAllCounterValues(pluginData: GuildPluginData, counterName: string) { const config = pluginData.config.get(); diff --git a/backend/src/plugins/Counters/functions/setCounterValue.ts b/backend/src/plugins/Counters/functions/setCounterValue.ts index 55b6f78f..23130ab0 100644 --- a/backend/src/plugins/Counters/functions/setCounterValue.ts +++ b/backend/src/plugins/Counters/functions/setCounterValue.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { counterIdLock } from "../../../utils/lockNameHelpers"; -import { CountersPluginType } from "../types"; -import { checkCounterTrigger } from "./checkCounterTrigger"; -import { checkReverseCounterTrigger } from "./checkReverseCounterTrigger"; +import { counterIdLock } from "../../../utils/lockNameHelpers.js"; +import { CountersPluginType } from "../types.js"; +import { checkCounterTrigger } from "./checkCounterTrigger.js"; +import { checkReverseCounterTrigger } from "./checkReverseCounterTrigger.js"; export async function setCounterValue( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Counters/info.ts b/backend/src/plugins/Counters/info.ts index f45e1a0c..abf07c70 100644 --- a/backend/src/plugins/Counters/info.ts +++ b/backend/src/plugins/Counters/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { zCountersConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { zCountersConfig } from "./types.js"; export const countersPluginInfo: ZeppelinPluginInfo = { prettyName: "Counters", diff --git a/backend/src/plugins/Counters/types.ts b/backend/src/plugins/Counters/types.ts index a323abf4..647a752e 100644 --- a/backend/src/plugins/Counters/types.ts +++ b/backend/src/plugins/Counters/types.ts @@ -1,15 +1,15 @@ import { EventEmitter } from "events"; import { BasePluginType, pluginUtils } from "knub"; import z from "zod"; -import { GuildCounters, MAX_COUNTER_VALUE, MIN_COUNTER_VALUE } from "../../data/GuildCounters"; +import { GuildCounters, MAX_COUNTER_VALUE, MIN_COUNTER_VALUE } from "../../data/GuildCounters.js"; import { CounterTrigger, buildCounterConditionString, getReverseCounterComparisonOp, parseCounterConditionString, -} from "../../data/entities/CounterTrigger"; -import { zBoundedCharacters, zBoundedRecord, zDelayString } from "../../utils"; -import { CommonPlugin } from "../Common/CommonPlugin"; +} from "../../data/entities/CounterTrigger.js"; +import { zBoundedCharacters, zBoundedRecord, zDelayString } from "../../utils.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; import Timeout = NodeJS.Timeout; const MAX_COUNTERS = 5; diff --git a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts index 41d8c1f2..c61d66f4 100644 --- a/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts +++ b/backend/src/plugins/CustomEvents/CustomEventsPlugin.ts @@ -1,20 +1,20 @@ import { GuildChannel, GuildMember, User } from "discord.js"; import { guildPlugin, guildPluginMessageCommand, parseSignature } from "knub"; import { TSignature } from "knub-command-manager"; -import { commandTypes } from "../../commandTypes"; -import { TemplateSafeValueContainer, createTypedTemplateSafeValueContainer } from "../../templateFormatter"; -import { UnknownUser } from "../../utils"; -import { isScalar } from "../../utils/isScalar"; +import { commandTypes } from "../../commandTypes.js"; +import { TemplateSafeValueContainer, createTypedTemplateSafeValueContainer } from "../../templateFormatter.js"; +import { UnknownUser } from "../../utils.js"; +import { isScalar } from "../../utils/isScalar.js"; import { channelToTemplateSafeChannel, memberToTemplateSafeMember, messageToTemplateSafeMessage, userToTemplateSafeUser, -} from "../../utils/templateSafeObjects"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { runEvent } from "./functions/runEvent"; -import { CustomEventsPluginType, zCustomEventsConfig } from "./types"; +} from "../../utils/templateSafeObjects.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { runEvent } from "./functions/runEvent.js"; +import { CustomEventsPluginType, zCustomEventsConfig } from "./types.js"; const defaultOptions = { config: { diff --git a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts index cd647687..8a3fa477 100644 --- a/backend/src/plugins/CustomEvents/actions/addRoleAction.ts +++ b/backend/src/plugins/CustomEvents/actions/addRoleAction.ts @@ -1,11 +1,11 @@ import { GuildPluginData } from "knub"; import z from "zod"; -import { canActOn } from "../../../pluginUtils"; -import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveMember, zSnowflake } from "../../../utils"; -import { ActionError } from "../ActionError"; -import { catchTemplateError } from "../catchTemplateError"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; +import { canActOn } from "../../../pluginUtils.js"; +import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveMember, zSnowflake } from "../../../utils.js"; +import { ActionError } from "../ActionError.js"; +import { catchTemplateError } from "../catchTemplateError.js"; +import { CustomEventsPluginType, TCustomEvent } from "../types.js"; export const zAddRoleAction = z.strictObject({ type: z.literal("add_role"), diff --git a/backend/src/plugins/CustomEvents/actions/createCaseAction.ts b/backend/src/plugins/CustomEvents/actions/createCaseAction.ts index a5e624fa..29c4bc4d 100644 --- a/backend/src/plugins/CustomEvents/actions/createCaseAction.ts +++ b/backend/src/plugins/CustomEvents/actions/createCaseAction.ts @@ -1,12 +1,12 @@ import { GuildPluginData } from "knub"; import z from "zod"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter"; -import { zBoundedCharacters, zSnowflake } from "../../../utils"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { ActionError } from "../ActionError"; -import { catchTemplateError } from "../catchTemplateError"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { zBoundedCharacters, zSnowflake } from "../../../utils.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { ActionError } from "../ActionError.js"; +import { catchTemplateError } from "../catchTemplateError.js"; +import { CustomEventsPluginType, TCustomEvent } from "../types.js"; export const zCreateCaseAction = z.strictObject({ type: z.literal("create_case"), diff --git a/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts b/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts index 7727e339..39984bf2 100644 --- a/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts +++ b/backend/src/plugins/CustomEvents/actions/makeRoleMentionableAction.ts @@ -1,10 +1,10 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import z from "zod"; -import { TemplateSafeValueContainer } from "../../../templateFormatter"; -import { convertDelayStringToMS, noop, zDelayString, zSnowflake } from "../../../utils"; -import { ActionError } from "../ActionError"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; +import { TemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { convertDelayStringToMS, noop, zDelayString, zSnowflake } from "../../../utils.js"; +import { ActionError } from "../ActionError.js"; +import { CustomEventsPluginType, TCustomEvent } from "../types.js"; export const zMakeRoleMentionableAction = z.strictObject({ type: z.literal("make_role_mentionable"), diff --git a/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts b/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts index 8dca7323..d1fefd11 100644 --- a/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts +++ b/backend/src/plugins/CustomEvents/actions/makeRoleUnmentionableAction.ts @@ -1,10 +1,10 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import z from "zod"; -import { TemplateSafeValueContainer } from "../../../templateFormatter"; -import { zSnowflake } from "../../../utils"; -import { ActionError } from "../ActionError"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; +import { TemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { zSnowflake } from "../../../utils.js"; +import { ActionError } from "../ActionError.js"; +import { CustomEventsPluginType, TCustomEvent } from "../types.js"; export const zMakeRoleUnmentionableAction = z.strictObject({ type: z.literal("make_role_unmentionable"), diff --git a/backend/src/plugins/CustomEvents/actions/messageAction.ts b/backend/src/plugins/CustomEvents/actions/messageAction.ts index 27780265..0e17c19f 100644 --- a/backend/src/plugins/CustomEvents/actions/messageAction.ts +++ b/backend/src/plugins/CustomEvents/actions/messageAction.ts @@ -1,11 +1,11 @@ import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import z from "zod"; -import { TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; -import { zBoundedCharacters, zSnowflake } from "../../../utils"; -import { ActionError } from "../ActionError"; -import { catchTemplateError } from "../catchTemplateError"; -import { CustomEventsPluginType } from "../types"; +import { TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter.js"; +import { zBoundedCharacters, zSnowflake } from "../../../utils.js"; +import { ActionError } from "../ActionError.js"; +import { catchTemplateError } from "../catchTemplateError.js"; +import { CustomEventsPluginType } from "../types.js"; export const zMessageAction = z.strictObject({ type: z.literal("message"), diff --git a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts index 40adcb58..c7d25bca 100644 --- a/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts +++ b/backend/src/plugins/CustomEvents/actions/moveToVoiceChannelAction.ts @@ -1,12 +1,12 @@ import { Snowflake, VoiceChannel } from "discord.js"; import { GuildPluginData } from "knub"; import z from "zod"; -import { canActOn } from "../../../pluginUtils"; -import { TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; -import { resolveMember, zSnowflake } from "../../../utils"; -import { ActionError } from "../ActionError"; -import { catchTemplateError } from "../catchTemplateError"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; +import { canActOn } from "../../../pluginUtils.js"; +import { TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter.js"; +import { resolveMember, zSnowflake } from "../../../utils.js"; +import { ActionError } from "../ActionError.js"; +import { catchTemplateError } from "../catchTemplateError.js"; +import { CustomEventsPluginType, TCustomEvent } from "../types.js"; export const zMoveToVoiceChannelAction = z.strictObject({ type: z.literal("move_to_vc"), diff --git a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts index b2e44d93..4c6af376 100644 --- a/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts +++ b/backend/src/plugins/CustomEvents/actions/setChannelPermissionOverrides.ts @@ -1,10 +1,10 @@ import { PermissionsBitField, PermissionsString, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import z from "zod"; -import { TemplateSafeValueContainer } from "../../../templateFormatter"; -import { zSnowflake } from "../../../utils"; -import { ActionError } from "../ActionError"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; +import { TemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { zSnowflake } from "../../../utils.js"; +import { ActionError } from "../ActionError.js"; +import { CustomEventsPluginType, TCustomEvent } from "../types.js"; export const zSetChannelPermissionOverridesAction = z.strictObject({ type: z.literal("set_channel_permission_overrides"), diff --git a/backend/src/plugins/CustomEvents/catchTemplateError.ts b/backend/src/plugins/CustomEvents/catchTemplateError.ts index 015a4298..1eef8fae 100644 --- a/backend/src/plugins/CustomEvents/catchTemplateError.ts +++ b/backend/src/plugins/CustomEvents/catchTemplateError.ts @@ -1,5 +1,5 @@ -import { TemplateParseError } from "../../templateFormatter"; -import { ActionError } from "./ActionError"; +import { TemplateParseError } from "../../templateFormatter.js"; +import { ActionError } from "./ActionError.js"; export function catchTemplateError(fn: () => Promise, errorText: string): Promise { try { diff --git a/backend/src/plugins/CustomEvents/functions/runEvent.ts b/backend/src/plugins/CustomEvents/functions/runEvent.ts index a2bf0d57..c0247950 100644 --- a/backend/src/plugins/CustomEvents/functions/runEvent.ts +++ b/backend/src/plugins/CustomEvents/functions/runEvent.ts @@ -1,15 +1,15 @@ import { Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { TemplateSafeValueContainer } from "../../../templateFormatter"; -import { ActionError } from "../ActionError"; -import { addRoleAction } from "../actions/addRoleAction"; -import { createCaseAction } from "../actions/createCaseAction"; -import { makeRoleMentionableAction } from "../actions/makeRoleMentionableAction"; -import { makeRoleUnmentionableAction } from "../actions/makeRoleUnmentionableAction"; -import { messageAction } from "../actions/messageAction"; -import { moveToVoiceChannelAction } from "../actions/moveToVoiceChannelAction"; -import { setChannelPermissionOverridesAction } from "../actions/setChannelPermissionOverrides"; -import { CustomEventsPluginType, TCustomEvent } from "../types"; +import { TemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { ActionError } from "../ActionError.js"; +import { addRoleAction } from "../actions/addRoleAction.js"; +import { createCaseAction } from "../actions/createCaseAction.js"; +import { makeRoleMentionableAction } from "../actions/makeRoleMentionableAction.js"; +import { makeRoleUnmentionableAction } from "../actions/makeRoleUnmentionableAction.js"; +import { messageAction } from "../actions/messageAction.js"; +import { moveToVoiceChannelAction } from "../actions/moveToVoiceChannelAction.js"; +import { setChannelPermissionOverridesAction } from "../actions/setChannelPermissionOverrides.js"; +import { CustomEventsPluginType, TCustomEvent } from "../types.js"; export async function runEvent( pluginData: GuildPluginData, diff --git a/backend/src/plugins/CustomEvents/info.ts b/backend/src/plugins/CustomEvents/info.ts index 32db1bee..4825cc36 100644 --- a/backend/src/plugins/CustomEvents/info.ts +++ b/backend/src/plugins/CustomEvents/info.ts @@ -1,4 +1,4 @@ -import { ZeppelinPluginInfo } from "../../types"; +import { ZeppelinPluginInfo } from "../../types.js"; export const customEventsPluginInfo: ZeppelinPluginInfo = { prettyName: "Custom events", diff --git a/backend/src/plugins/CustomEvents/types.ts b/backend/src/plugins/CustomEvents/types.ts index df325b98..b9f31f64 100644 --- a/backend/src/plugins/CustomEvents/types.ts +++ b/backend/src/plugins/CustomEvents/types.ts @@ -1,14 +1,14 @@ import { BasePluginType, pluginUtils } from "knub"; import z from "zod"; -import { zBoundedCharacters, zBoundedRecord } from "../../utils"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { zAddRoleAction } from "./actions/addRoleAction"; -import { zCreateCaseAction } from "./actions/createCaseAction"; -import { zMakeRoleMentionableAction } from "./actions/makeRoleMentionableAction"; -import { zMakeRoleUnmentionableAction } from "./actions/makeRoleUnmentionableAction"; -import { zMessageAction } from "./actions/messageAction"; -import { zMoveToVoiceChannelAction } from "./actions/moveToVoiceChannelAction"; -import { zSetChannelPermissionOverridesAction } from "./actions/setChannelPermissionOverrides"; +import { zBoundedCharacters, zBoundedRecord } from "../../utils.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { zAddRoleAction } from "./actions/addRoleAction.js"; +import { zCreateCaseAction } from "./actions/createCaseAction.js"; +import { zMakeRoleMentionableAction } from "./actions/makeRoleMentionableAction.js"; +import { zMakeRoleUnmentionableAction } from "./actions/makeRoleUnmentionableAction.js"; +import { zMessageAction } from "./actions/messageAction.js"; +import { zMoveToVoiceChannelAction } from "./actions/moveToVoiceChannelAction.js"; +import { zSetChannelPermissionOverridesAction } from "./actions/setChannelPermissionOverrides.js"; const zCommandTrigger = z.strictObject({ type: z.literal("command"), diff --git a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts index c0319b55..7be3ca96 100644 --- a/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts +++ b/backend/src/plugins/GuildAccessMonitor/GuildAccessMonitorPlugin.ts @@ -1,9 +1,9 @@ import { Guild } from "discord.js"; import { BasePluginType, GlobalPluginData, globalPlugin, globalPluginEventListener } from "knub"; import z from "zod"; -import { AllowedGuilds } from "../../data/AllowedGuilds"; -import { Configs } from "../../data/Configs"; -import { env } from "../../env"; +import { AllowedGuilds } from "../../data/AllowedGuilds.js"; +import { Configs } from "../../data/Configs.js"; +import { env } from "../../env.js"; interface GuildAccessMonitorPluginType extends BasePluginType { state: { diff --git a/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts b/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts index 4c7954a1..f1f69d59 100644 --- a/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts +++ b/backend/src/plugins/GuildConfigReloader/GuildConfigReloaderPlugin.ts @@ -1,8 +1,8 @@ import { globalPlugin } from "knub"; import z from "zod"; -import { Configs } from "../../data/Configs"; -import { reloadChangedGuilds } from "./functions/reloadChangedGuilds"; -import { GuildConfigReloaderPluginType } from "./types"; +import { Configs } from "../../data/Configs.js"; +import { reloadChangedGuilds } from "./functions/reloadChangedGuilds.js"; +import { GuildConfigReloaderPluginType } from "./types.js"; export const GuildConfigReloaderPlugin = globalPlugin()({ name: "guild_config_reloader", diff --git a/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts b/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts index f18d3c45..0f0bef79 100644 --- a/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts +++ b/backend/src/plugins/GuildConfigReloader/functions/reloadChangedGuilds.ts @@ -1,7 +1,7 @@ import { Snowflake } from "discord.js"; import { GlobalPluginData } from "knub"; -import { SECONDS } from "../../../utils"; -import { GuildConfigReloaderPluginType } from "../types"; +import { SECONDS } from "../../../utils.js"; +import { GuildConfigReloaderPluginType } from "../types.js"; const CHECK_INTERVAL = 1 * SECONDS; diff --git a/backend/src/plugins/GuildConfigReloader/info.ts b/backend/src/plugins/GuildConfigReloader/info.ts index ac7c8c0f..2aa6cacd 100644 --- a/backend/src/plugins/GuildConfigReloader/info.ts +++ b/backend/src/plugins/GuildConfigReloader/info.ts @@ -1,4 +1,4 @@ -import { ZeppelinPluginInfo } from "../../types"; +import { ZeppelinPluginInfo } from "../../types.js"; export const guildConfigReloaderPluginInfo: ZeppelinPluginInfo = { prettyName: "Guild config reloader", diff --git a/backend/src/plugins/GuildConfigReloader/types.ts b/backend/src/plugins/GuildConfigReloader/types.ts index 8477d60d..58b439c4 100644 --- a/backend/src/plugins/GuildConfigReloader/types.ts +++ b/backend/src/plugins/GuildConfigReloader/types.ts @@ -1,5 +1,5 @@ import { BasePluginType } from "knub"; -import { Configs } from "../../data/Configs"; +import { Configs } from "../../data/Configs.js"; import Timeout = NodeJS.Timeout; export interface GuildConfigReloaderPluginType extends BasePluginType { diff --git a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts index 724cd2fe..e6d2b54d 100644 --- a/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts +++ b/backend/src/plugins/GuildInfoSaver/GuildInfoSaverPlugin.ts @@ -1,10 +1,10 @@ import { Guild } from "discord.js"; import { guildPlugin, guildPluginEventListener } from "knub"; import z from "zod"; -import { AllowedGuilds } from "../../data/AllowedGuilds"; -import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments"; -import { MINUTES } from "../../utils"; -import { GuildInfoSaverPluginType } from "./types"; +import { AllowedGuilds } from "../../data/AllowedGuilds.js"; +import { ApiPermissionAssignments } from "../../data/ApiPermissionAssignments.js"; +import { MINUTES } from "../../utils.js"; +import { GuildInfoSaverPluginType } from "./types.js"; export const GuildInfoSaverPlugin = guildPlugin()({ name: "guild_info_saver", diff --git a/backend/src/plugins/GuildInfoSaver/info.ts b/backend/src/plugins/GuildInfoSaver/info.ts index 411e7891..362873c1 100644 --- a/backend/src/plugins/GuildInfoSaver/info.ts +++ b/backend/src/plugins/GuildInfoSaver/info.ts @@ -1,4 +1,4 @@ -import { ZeppelinPluginInfo } from "../../types"; +import { ZeppelinPluginInfo } from "../../types.js"; export const guildInfoSaverPluginInfo: ZeppelinPluginInfo = { prettyName: "Guild info saver", diff --git a/backend/src/plugins/GuildMemberCache/GuildMemberCachePlugin.ts b/backend/src/plugins/GuildMemberCache/GuildMemberCachePlugin.ts index cd24c0b8..cf521083 100644 --- a/backend/src/plugins/GuildMemberCache/GuildMemberCachePlugin.ts +++ b/backend/src/plugins/GuildMemberCache/GuildMemberCachePlugin.ts @@ -1,16 +1,16 @@ import { guildPlugin } from "knub"; import z from "zod"; -import { GuildMemberCache } from "../../data/GuildMemberCache"; -import { makePublicFn } from "../../pluginUtils"; -import { SECONDS } from "../../utils"; -import { cancelDeletionOnMemberJoin } from "./events/cancelDeletionOnMemberJoin"; -import { removeMemberCacheOnMemberLeave } from "./events/removeMemberCacheOnMemberLeave"; -import { updateMemberCacheOnMemberUpdate } from "./events/updateMemberCacheOnMemberUpdate"; -import { updateMemberCacheOnMessage } from "./events/updateMemberCacheOnMessage"; -import { updateMemberCacheOnRoleChange } from "./events/updateMemberCacheOnRoleChange"; -import { updateMemberCacheOnVoiceStateUpdate } from "./events/updateMemberCacheOnVoiceStateUpdate"; -import { getCachedMemberData } from "./functions/getCachedMemberData"; -import { GuildMemberCachePluginType } from "./types"; +import { GuildMemberCache } from "../../data/GuildMemberCache.js"; +import { makePublicFn } from "../../pluginUtils.js"; +import { SECONDS } from "../../utils.js"; +import { cancelDeletionOnMemberJoin } from "./events/cancelDeletionOnMemberJoin.js"; +import { removeMemberCacheOnMemberLeave } from "./events/removeMemberCacheOnMemberLeave.js"; +import { updateMemberCacheOnMemberUpdate } from "./events/updateMemberCacheOnMemberUpdate.js"; +import { updateMemberCacheOnMessage } from "./events/updateMemberCacheOnMessage.js"; +import { updateMemberCacheOnRoleChange } from "./events/updateMemberCacheOnRoleChange.js"; +import { updateMemberCacheOnVoiceStateUpdate } from "./events/updateMemberCacheOnVoiceStateUpdate.js"; +import { getCachedMemberData } from "./functions/getCachedMemberData.js"; +import { GuildMemberCachePluginType } from "./types.js"; const PENDING_SAVE_INTERVAL = 30 * SECONDS; diff --git a/backend/src/plugins/GuildMemberCache/events/cancelDeletionOnMemberJoin.ts b/backend/src/plugins/GuildMemberCache/events/cancelDeletionOnMemberJoin.ts index 158922d3..d15e4940 100644 --- a/backend/src/plugins/GuildMemberCache/events/cancelDeletionOnMemberJoin.ts +++ b/backend/src/plugins/GuildMemberCache/events/cancelDeletionOnMemberJoin.ts @@ -1,5 +1,5 @@ import { guildPluginEventListener } from "knub"; -import { GuildMemberCachePluginType } from "../types"; +import { GuildMemberCachePluginType } from "../types.js"; export const cancelDeletionOnMemberJoin = guildPluginEventListener()({ event: "guildMemberAdd", diff --git a/backend/src/plugins/GuildMemberCache/events/removeMemberCacheOnMemberLeave.ts b/backend/src/plugins/GuildMemberCache/events/removeMemberCacheOnMemberLeave.ts index 8015aa9d..08d23ccd 100644 --- a/backend/src/plugins/GuildMemberCache/events/removeMemberCacheOnMemberLeave.ts +++ b/backend/src/plugins/GuildMemberCache/events/removeMemberCacheOnMemberLeave.ts @@ -1,5 +1,5 @@ import { guildPluginEventListener } from "knub"; -import { GuildMemberCachePluginType } from "../types"; +import { GuildMemberCachePluginType } from "../types.js"; export const removeMemberCacheOnMemberLeave = guildPluginEventListener()({ event: "guildMemberRemove", diff --git a/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnMemberUpdate.ts b/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnMemberUpdate.ts index 9340495c..7709902c 100644 --- a/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnMemberUpdate.ts +++ b/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnMemberUpdate.ts @@ -1,6 +1,6 @@ import { guildPluginEventListener } from "knub"; -import { updateMemberCacheForMember } from "../functions/updateMemberCacheForMember"; -import { GuildMemberCachePluginType } from "../types"; +import { updateMemberCacheForMember } from "../functions/updateMemberCacheForMember.js"; +import { GuildMemberCachePluginType } from "../types.js"; export const updateMemberCacheOnMemberUpdate = guildPluginEventListener()({ event: "guildMemberUpdate", diff --git a/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnMessage.ts b/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnMessage.ts index 9277620d..e7777c53 100644 --- a/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnMessage.ts +++ b/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnMessage.ts @@ -1,6 +1,6 @@ import { guildPluginEventListener } from "knub"; -import { updateMemberCacheForMember } from "../functions/updateMemberCacheForMember"; -import { GuildMemberCachePluginType } from "../types"; +import { updateMemberCacheForMember } from "../functions/updateMemberCacheForMember.js"; +import { GuildMemberCachePluginType } from "../types.js"; export const updateMemberCacheOnMessage = guildPluginEventListener()({ event: "messageCreate", diff --git a/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnRoleChange.ts b/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnRoleChange.ts index 147cb9ab..8f8f2abb 100644 --- a/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnRoleChange.ts +++ b/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnRoleChange.ts @@ -1,7 +1,7 @@ import { AuditLogEvent } from "discord.js"; import { guildPluginEventListener } from "knub"; -import { updateMemberCacheForMember } from "../functions/updateMemberCacheForMember"; -import { GuildMemberCachePluginType } from "../types"; +import { updateMemberCacheForMember } from "../functions/updateMemberCacheForMember.js"; +import { GuildMemberCachePluginType } from "../types.js"; export const updateMemberCacheOnRoleChange = guildPluginEventListener()({ event: "guildAuditLogEntryCreate", diff --git a/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnVoiceStateUpdate.ts b/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnVoiceStateUpdate.ts index 377d46e6..0e7bc212 100644 --- a/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnVoiceStateUpdate.ts +++ b/backend/src/plugins/GuildMemberCache/events/updateMemberCacheOnVoiceStateUpdate.ts @@ -1,6 +1,6 @@ import { guildPluginEventListener } from "knub"; -import { updateMemberCacheForMember } from "../functions/updateMemberCacheForMember"; -import { GuildMemberCachePluginType } from "../types"; +import { updateMemberCacheForMember } from "../functions/updateMemberCacheForMember.js"; +import { GuildMemberCachePluginType } from "../types.js"; export const updateMemberCacheOnVoiceStateUpdate = guildPluginEventListener()({ event: "voiceStateUpdate", diff --git a/backend/src/plugins/GuildMemberCache/functions/getCachedMemberData.ts b/backend/src/plugins/GuildMemberCache/functions/getCachedMemberData.ts index add7cae1..340eae91 100644 --- a/backend/src/plugins/GuildMemberCache/functions/getCachedMemberData.ts +++ b/backend/src/plugins/GuildMemberCache/functions/getCachedMemberData.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { MemberCacheItem } from "../../../data/entities/MemberCacheItem"; -import { GuildMemberCachePluginType } from "../types"; +import { MemberCacheItem } from "../../../data/entities/MemberCacheItem.js"; +import { GuildMemberCachePluginType } from "../types.js"; export function getCachedMemberData( pluginData: GuildPluginData, diff --git a/backend/src/plugins/GuildMemberCache/functions/updateMemberCacheForMember.ts b/backend/src/plugins/GuildMemberCache/functions/updateMemberCacheForMember.ts index 242ff406..384af1a8 100644 --- a/backend/src/plugins/GuildMemberCache/functions/updateMemberCacheForMember.ts +++ b/backend/src/plugins/GuildMemberCache/functions/updateMemberCacheForMember.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { GuildMemberCachePluginType } from "../types"; +import { GuildMemberCachePluginType } from "../types.js"; export async function updateMemberCacheForMember( pluginData: GuildPluginData, diff --git a/backend/src/plugins/GuildMemberCache/info.ts b/backend/src/plugins/GuildMemberCache/info.ts index 7980a788..290a6921 100644 --- a/backend/src/plugins/GuildMemberCache/info.ts +++ b/backend/src/plugins/GuildMemberCache/info.ts @@ -1,4 +1,4 @@ -import { ZeppelinPluginInfo } from "../../types"; +import { ZeppelinPluginInfo } from "../../types.js"; export const guildMemberCachePluginInfo: ZeppelinPluginInfo = { prettyName: "Guild member cache", diff --git a/backend/src/plugins/GuildMemberCache/types.ts b/backend/src/plugins/GuildMemberCache/types.ts index 03f75147..e38eb6fb 100644 --- a/backend/src/plugins/GuildMemberCache/types.ts +++ b/backend/src/plugins/GuildMemberCache/types.ts @@ -1,5 +1,5 @@ import { BasePluginType } from "knub"; -import { GuildMemberCache } from "../../data/GuildMemberCache"; +import { GuildMemberCache } from "../../data/GuildMemberCache.js"; export interface GuildMemberCachePluginType extends BasePluginType { state: { diff --git a/backend/src/plugins/InternalPoster/InternalPosterPlugin.ts b/backend/src/plugins/InternalPoster/InternalPosterPlugin.ts index ae01bb64..985608c6 100644 --- a/backend/src/plugins/InternalPoster/InternalPosterPlugin.ts +++ b/backend/src/plugins/InternalPoster/InternalPosterPlugin.ts @@ -1,11 +1,11 @@ import { PluginOptions, guildPlugin } from "knub"; import z from "zod"; -import { Queue } from "../../Queue"; -import { Webhooks } from "../../data/Webhooks"; -import { makePublicFn } from "../../pluginUtils"; -import { editMessage } from "./functions/editMessage"; -import { sendMessage } from "./functions/sendMessage"; -import { InternalPosterPluginType } from "./types"; +import { Queue } from "../../Queue.js"; +import { Webhooks } from "../../data/Webhooks.js"; +import { makePublicFn } from "../../pluginUtils.js"; +import { editMessage } from "./functions/editMessage.js"; +import { sendMessage } from "./functions/sendMessage.js"; +import { InternalPosterPluginType } from "./types.js"; const defaultOptions: PluginOptions = { config: {}, diff --git a/backend/src/plugins/InternalPoster/functions/editMessage.ts b/backend/src/plugins/InternalPoster/functions/editMessage.ts index ce250df0..7f785817 100644 --- a/backend/src/plugins/InternalPoster/functions/editMessage.ts +++ b/backend/src/plugins/InternalPoster/functions/editMessage.ts @@ -1,7 +1,7 @@ import { Message, MessageEditOptions, WebhookClient, WebhookMessageEditOptions } from "discord.js"; import { GuildPluginData } from "knub"; -import { isDiscordAPIError, noop } from "../../../utils"; -import { InternalPosterPluginType } from "../types"; +import { isDiscordAPIError, noop } from "../../../utils.js"; +import { InternalPosterPluginType } from "../types.js"; /** * Sends a message using a webhook or direct API requests, preferring webhooks when possible. diff --git a/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookClientForChannel.ts b/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookClientForChannel.ts index b97e2cde..02d2e5e3 100644 --- a/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookClientForChannel.ts +++ b/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookClientForChannel.ts @@ -1,7 +1,7 @@ import { WebhookClient } from "discord.js"; import { GuildPluginData } from "knub"; -import { InternalPosterPluginType } from "../types"; -import { getOrCreateWebhookForChannel, WebhookableChannel } from "./getOrCreateWebhookForChannel"; +import { InternalPosterPluginType } from "../types.js"; +import { getOrCreateWebhookForChannel, WebhookableChannel } from "./getOrCreateWebhookForChannel.js"; export async function getOrCreateWebhookClientForChannel( pluginData: GuildPluginData, diff --git a/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookForChannel.ts b/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookForChannel.ts index d5784212..1cceafd4 100644 --- a/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookForChannel.ts +++ b/backend/src/plugins/InternalPoster/functions/getOrCreateWebhookForChannel.ts @@ -1,7 +1,7 @@ import { GuildBasedChannel, PermissionsBitField } from "discord.js"; import { GuildPluginData } from "knub"; -import { isDiscordAPIError } from "../../../utils"; -import { InternalPosterPluginType } from "../types"; +import { isDiscordAPIError } from "../../../utils.js"; +import { InternalPosterPluginType } from "../types.js"; type WebhookInfo = [id: string, token: string]; diff --git a/backend/src/plugins/InternalPoster/functions/sendMessage.ts b/backend/src/plugins/InternalPoster/functions/sendMessage.ts index 3d4d6424..4d8576c4 100644 --- a/backend/src/plugins/InternalPoster/functions/sendMessage.ts +++ b/backend/src/plugins/InternalPoster/functions/sendMessage.ts @@ -1,9 +1,9 @@ import { GuildTextBasedChannel, MessageCreateOptions, WebhookClient } from "discord.js"; import { GuildPluginData } from "knub"; -import { isDiscordAPIError } from "../../../utils"; -import { InternalPosterPluginType } from "../types"; -import { getOrCreateWebhookClientForChannel } from "./getOrCreateWebhookClientForChannel"; -import { channelIsWebhookable } from "./getOrCreateWebhookForChannel"; +import { isDiscordAPIError } from "../../../utils.js"; +import { InternalPosterPluginType } from "../types.js"; +import { getOrCreateWebhookClientForChannel } from "./getOrCreateWebhookClientForChannel.js"; +import { channelIsWebhookable } from "./getOrCreateWebhookForChannel.js"; export type InternalPosterMessageResult = { id: string; diff --git a/backend/src/plugins/InternalPoster/info.ts b/backend/src/plugins/InternalPoster/info.ts index 948bbbc8..37bab5f0 100644 --- a/backend/src/plugins/InternalPoster/info.ts +++ b/backend/src/plugins/InternalPoster/info.ts @@ -1,4 +1,4 @@ -import { ZeppelinPluginInfo } from "../../types"; +import { ZeppelinPluginInfo } from "../../types.js"; export const internalPosterPluginInfo: ZeppelinPluginInfo = { prettyName: "Internal poster", diff --git a/backend/src/plugins/InternalPoster/types.ts b/backend/src/plugins/InternalPoster/types.ts index 78dabd42..cf747353 100644 --- a/backend/src/plugins/InternalPoster/types.ts +++ b/backend/src/plugins/InternalPoster/types.ts @@ -1,7 +1,7 @@ import { WebhookClient } from "discord.js"; import { BasePluginType } from "knub"; -import { Queue } from "../../Queue"; -import { Webhooks } from "../../data/Webhooks"; +import { Queue } from "../../Queue.js"; +import { Webhooks } from "../../data/Webhooks.js"; export interface InternalPosterPluginType extends BasePluginType { state: { diff --git a/backend/src/plugins/LocateUser/LocateUserPlugin.ts b/backend/src/plugins/LocateUser/LocateUserPlugin.ts index 0730919c..b16a29a9 100644 --- a/backend/src/plugins/LocateUser/LocateUserPlugin.ts +++ b/backend/src/plugins/LocateUser/LocateUserPlugin.ts @@ -1,15 +1,15 @@ import { PluginOptions, guildPlugin } from "knub"; -import { onGuildEvent } from "../../data/GuildEvents"; -import { GuildVCAlerts } from "../../data/GuildVCAlerts"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { FollowCmd } from "./commands/FollowCmd"; -import { DeleteFollowCmd, ListFollowCmd } from "./commands/ListFollowCmd"; -import { WhereCmd } from "./commands/WhereCmd"; -import { GuildBanRemoveAlertsEvt } from "./events/BanRemoveAlertsEvt"; -import { VoiceStateUpdateAlertEvt } from "./events/SendAlertsEvts"; -import { LocateUserPluginType, zLocateUserConfig } from "./types"; -import { clearExpiredAlert } from "./utils/clearExpiredAlert"; -import { fillActiveAlertsList } from "./utils/fillAlertsList"; +import { onGuildEvent } from "../../data/GuildEvents.js"; +import { GuildVCAlerts } from "../../data/GuildVCAlerts.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { FollowCmd } from "./commands/FollowCmd.js"; +import { DeleteFollowCmd, ListFollowCmd } from "./commands/ListFollowCmd.js"; +import { WhereCmd } from "./commands/WhereCmd.js"; +import { GuildBanRemoveAlertsEvt } from "./events/BanRemoveAlertsEvt.js"; +import { VoiceStateUpdateAlertEvt } from "./events/SendAlertsEvts.js"; +import { LocateUserPluginType, zLocateUserConfig } from "./types.js"; +import { clearExpiredAlert } from "./utils/clearExpiredAlert.js"; +import { fillActiveAlertsList } from "./utils/fillAlertsList.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/LocateUser/commands/FollowCmd.ts b/backend/src/plugins/LocateUser/commands/FollowCmd.ts index f0debc59..ff18dabc 100644 --- a/backend/src/plugins/LocateUser/commands/FollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/FollowCmd.ts @@ -1,9 +1,9 @@ import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { registerExpiringVCAlert } from "../../../data/loops/expiringVCAlertsLoop"; -import { MINUTES, SECONDS } from "../../../utils"; -import { locateUserCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { registerExpiringVCAlert } from "../../../data/loops/expiringVCAlertsLoop.js"; +import { MINUTES, SECONDS } from "../../../utils.js"; +import { locateUserCmd } from "../types.js"; export const FollowCmd = locateUserCmd({ trigger: ["follow", "f"], diff --git a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts index bbe30513..cd3d6d45 100644 --- a/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts +++ b/backend/src/plugins/LocateUser/commands/ListFollowCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { clearExpiringVCAlert } from "../../../data/loops/expiringVCAlertsLoop"; -import { createChunkedMessage, sorter } from "../../../utils"; -import { locateUserCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { clearExpiringVCAlert } from "../../../data/loops/expiringVCAlertsLoop.js"; +import { createChunkedMessage, sorter } from "../../../utils.js"; +import { locateUserCmd } from "../types.js"; export const ListFollowCmd = locateUserCmd({ trigger: ["follows", "fs"], diff --git a/backend/src/plugins/LocateUser/commands/WhereCmd.ts b/backend/src/plugins/LocateUser/commands/WhereCmd.ts index 0ff00d91..245a128a 100644 --- a/backend/src/plugins/LocateUser/commands/WhereCmd.ts +++ b/backend/src/plugins/LocateUser/commands/WhereCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { locateUserCmd } from "../types"; -import { sendWhere } from "../utils/sendWhere"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { locateUserCmd } from "../types.js"; +import { sendWhere } from "../utils/sendWhere.js"; export const WhereCmd = locateUserCmd({ trigger: ["where", "w"], diff --git a/backend/src/plugins/LocateUser/events/BanRemoveAlertsEvt.ts b/backend/src/plugins/LocateUser/events/BanRemoveAlertsEvt.ts index aead6776..9c00f7d4 100644 --- a/backend/src/plugins/LocateUser/events/BanRemoveAlertsEvt.ts +++ b/backend/src/plugins/LocateUser/events/BanRemoveAlertsEvt.ts @@ -1,5 +1,5 @@ -import { clearExpiringVCAlert } from "../../../data/loops/expiringVCAlertsLoop"; -import { locateUserEvt } from "../types"; +import { clearExpiringVCAlert } from "../../../data/loops/expiringVCAlertsLoop.js"; +import { locateUserEvt } from "../types.js"; export const GuildBanRemoveAlertsEvt = locateUserEvt({ event: "guildBanAdd", diff --git a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts index 691afc3d..0269a57f 100644 --- a/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts +++ b/backend/src/plugins/LocateUser/events/SendAlertsEvts.ts @@ -1,6 +1,6 @@ import { Snowflake } from "discord.js"; -import { locateUserEvt } from "../types"; -import { sendAlerts } from "../utils/sendAlerts"; +import { locateUserEvt } from "../types.js"; +import { sendAlerts } from "../utils/sendAlerts.js"; export const VoiceStateUpdateAlertEvt = locateUserEvt({ event: "voiceStateUpdate", diff --git a/backend/src/plugins/LocateUser/info.ts b/backend/src/plugins/LocateUser/info.ts index 41fcf11b..ee7cc3f7 100644 --- a/backend/src/plugins/LocateUser/info.ts +++ b/backend/src/plugins/LocateUser/info.ts @@ -1,6 +1,6 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; -import { zLocateUserConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; +import { zLocateUserConfig } from "./types.js"; export const locateUserPluginInfo: ZeppelinPluginInfo = { prettyName: "Locate user", diff --git a/backend/src/plugins/LocateUser/types.ts b/backend/src/plugins/LocateUser/types.ts index 90695a6d..bbcb6d88 100644 --- a/backend/src/plugins/LocateUser/types.ts +++ b/backend/src/plugins/LocateUser/types.ts @@ -1,7 +1,7 @@ import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { GuildVCAlerts } from "../../data/GuildVCAlerts"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { GuildVCAlerts } from "../../data/GuildVCAlerts.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zLocateUserConfig = z.strictObject({ can_where: z.boolean(), diff --git a/backend/src/plugins/LocateUser/utils/clearExpiredAlert.ts b/backend/src/plugins/LocateUser/utils/clearExpiredAlert.ts index 9683417b..f09ae9fa 100644 --- a/backend/src/plugins/LocateUser/utils/clearExpiredAlert.ts +++ b/backend/src/plugins/LocateUser/utils/clearExpiredAlert.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { VCAlert } from "../../../data/entities/VCAlert"; -import { LocateUserPluginType } from "../types"; -import { removeUserIdFromActiveAlerts } from "./removeUserIdFromActiveAlerts"; +import { VCAlert } from "../../../data/entities/VCAlert.js"; +import { LocateUserPluginType } from "../types.js"; +import { removeUserIdFromActiveAlerts } from "./removeUserIdFromActiveAlerts.js"; export async function clearExpiredAlert(pluginData: GuildPluginData, alert: VCAlert) { await pluginData.state.alerts.delete(alert.id); diff --git a/backend/src/plugins/LocateUser/utils/fillAlertsList.ts b/backend/src/plugins/LocateUser/utils/fillAlertsList.ts index 56e4315f..d3b56fcf 100644 --- a/backend/src/plugins/LocateUser/utils/fillAlertsList.ts +++ b/backend/src/plugins/LocateUser/utils/fillAlertsList.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { LocateUserPluginType } from "../types"; +import { LocateUserPluginType } from "../types.js"; export async function fillActiveAlertsList(pluginData: GuildPluginData) { const allAlerts = await pluginData.state.alerts.getAllGuildAlerts(); diff --git a/backend/src/plugins/LocateUser/utils/moveMember.ts b/backend/src/plugins/LocateUser/utils/moveMember.ts index 6438bde1..85b068c6 100644 --- a/backend/src/plugins/LocateUser/utils/moveMember.ts +++ b/backend/src/plugins/LocateUser/utils/moveMember.ts @@ -1,6 +1,6 @@ import { GuildMember, GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { LocateUserPluginType } from "../types"; +import { LocateUserPluginType } from "../types.js"; export async function moveMember( pluginData: GuildPluginData, diff --git a/backend/src/plugins/LocateUser/utils/removeUserIdFromActiveAlerts.ts b/backend/src/plugins/LocateUser/utils/removeUserIdFromActiveAlerts.ts index adfffb95..564c682a 100644 --- a/backend/src/plugins/LocateUser/utils/removeUserIdFromActiveAlerts.ts +++ b/backend/src/plugins/LocateUser/utils/removeUserIdFromActiveAlerts.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { LocateUserPluginType } from "../types"; +import { LocateUserPluginType } from "../types.js"; export async function removeUserIdFromActiveAlerts(pluginData: GuildPluginData, userId: string) { const index = pluginData.state.usersWithAlerts.indexOf(userId); diff --git a/backend/src/plugins/LocateUser/utils/sendAlerts.ts b/backend/src/plugins/LocateUser/utils/sendAlerts.ts index 66e6a222..78a58911 100644 --- a/backend/src/plugins/LocateUser/utils/sendAlerts.ts +++ b/backend/src/plugins/LocateUser/utils/sendAlerts.ts @@ -1,9 +1,9 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { resolveMember } from "../../../utils"; -import { LocateUserPluginType } from "../types"; -import { moveMember } from "./moveMember"; -import { sendWhere } from "./sendWhere"; +import { resolveMember } from "../../../utils.js"; +import { LocateUserPluginType } from "../types.js"; +import { moveMember } from "./moveMember.js"; +import { sendWhere } from "./sendWhere.js"; export async function sendAlerts(pluginData: GuildPluginData, userId: string) { const triggeredAlerts = await pluginData.state.alerts.getAlertsByUserId(userId); diff --git a/backend/src/plugins/LocateUser/utils/sendWhere.ts b/backend/src/plugins/LocateUser/utils/sendWhere.ts index 6ce4181f..ef74cbcd 100644 --- a/backend/src/plugins/LocateUser/utils/sendWhere.ts +++ b/backend/src/plugins/LocateUser/utils/sendWhere.ts @@ -1,8 +1,8 @@ import { GuildMember, GuildTextBasedChannel, Invite, VoiceChannel } from "discord.js"; import { GuildPluginData } from "knub"; import { getInviteLink } from "knub/helpers"; -import { LocateUserPluginType } from "../types"; -import { createOrReuseInvite } from "./createOrReuseInvite"; +import { LocateUserPluginType } from "../types.js"; +import { createOrReuseInvite } from "./createOrReuseInvite.js"; export async function sendWhere( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Logs/LogsPlugin.ts b/backend/src/plugins/Logs/LogsPlugin.ts index 62a6de4d..6b393fc4 100644 --- a/backend/src/plugins/Logs/LogsPlugin.ts +++ b/backend/src/plugins/Logs/LogsPlugin.ts @@ -1,16 +1,16 @@ import { CooldownManager, PluginOptions, guildPlugin } from "knub"; -import DefaultLogMessages from "../../data/DefaultLogMessages.json"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildCases } from "../../data/GuildCases"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { LogType } from "../../data/LogType"; -import { logger } from "../../logger"; -import { makePublicFn } from "../../pluginUtils"; -import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; -import { createTypedTemplateSafeValueContainer } from "../../templateFormatter"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { LogsChannelCreateEvt, LogsChannelDeleteEvt, LogsChannelUpdateEvt } from "./events/LogsChannelModifyEvts"; +import DefaultLogMessages from "../../data/DefaultLogMessages.json.js"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildCases } from "../../data/GuildCases.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { LogType } from "../../data/LogType.js"; +import { logger } from "../../logger.js"; +import { makePublicFn } from "../../pluginUtils.js"; +import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners.js"; +import { createTypedTemplateSafeValueContainer } from "../../templateFormatter.js"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin.js"; +import { LogsChannelCreateEvt, LogsChannelDeleteEvt, LogsChannelUpdateEvt } from "./events/LogsChannelModifyEvts.js"; import { LogsEmojiCreateEvt, LogsEmojiDeleteEvt, @@ -18,97 +18,97 @@ import { LogsStickerCreateEvt, LogsStickerDeleteEvt, LogsStickerUpdateEvt, -} from "./events/LogsEmojiAndStickerModifyEvts"; -import { LogsGuildMemberAddEvt } from "./events/LogsGuildMemberAddEvt"; -import { LogsGuildMemberRemoveEvt } from "./events/LogsGuildMemberRemoveEvt"; -import { LogsRoleCreateEvt, LogsRoleDeleteEvt, LogsRoleUpdateEvt } from "./events/LogsRoleModifyEvts"; +} from "./events/LogsEmojiAndStickerModifyEvts.js"; +import { LogsGuildMemberAddEvt } from "./events/LogsGuildMemberAddEvt.js"; +import { LogsGuildMemberRemoveEvt } from "./events/LogsGuildMemberRemoveEvt.js"; +import { LogsRoleCreateEvt, LogsRoleDeleteEvt, LogsRoleUpdateEvt } from "./events/LogsRoleModifyEvts.js"; import { LogsStageInstanceCreateEvt, LogsStageInstanceDeleteEvt, LogsStageInstanceUpdateEvt, -} from "./events/LogsStageInstanceModifyEvts"; -import { LogsThreadCreateEvt, LogsThreadDeleteEvt, LogsThreadUpdateEvt } from "./events/LogsThreadModifyEvts"; -import { LogsGuildMemberUpdateEvt } from "./events/LogsUserUpdateEvts"; -import { LogsVoiceStateUpdateEvt } from "./events/LogsVoiceChannelEvts"; -import { FORMAT_NO_TIMESTAMP, LogsPluginType, zLogsConfig } from "./types"; -import { getLogMessage } from "./util/getLogMessage"; -import { log } from "./util/log"; -import { onMessageDelete } from "./util/onMessageDelete"; -import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk"; -import { onMessageUpdate } from "./util/onMessageUpdate"; +} from "./events/LogsStageInstanceModifyEvts.js"; +import { LogsThreadCreateEvt, LogsThreadDeleteEvt, LogsThreadUpdateEvt } from "./events/LogsThreadModifyEvts.js"; +import { LogsGuildMemberUpdateEvt } from "./events/LogsUserUpdateEvts.js"; +import { LogsVoiceStateUpdateEvt } from "./events/LogsVoiceChannelEvts.js"; +import { FORMAT_NO_TIMESTAMP, LogsPluginType, zLogsConfig } from "./types.js"; +import { getLogMessage } from "./util/getLogMessage.js"; +import { log } from "./util/log.js"; +import { onMessageDelete } from "./util/onMessageDelete.js"; +import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk.js"; +import { onMessageUpdate } from "./util/onMessageUpdate.js"; import { escapeCodeBlock } from "discord.js"; -import { InternalPosterPlugin } from "../InternalPoster/InternalPosterPlugin"; -import { LogsGuildMemberRoleChangeEvt } from "./events/LogsGuildMemberRoleChangeEvt"; -import { logAutomodAction } from "./logFunctions/logAutomodAction"; -import { logBotAlert } from "./logFunctions/logBotAlert"; -import { logCaseCreate } from "./logFunctions/logCaseCreate"; -import { logCaseDelete } from "./logFunctions/logCaseDelete"; -import { logCaseUpdate } from "./logFunctions/logCaseUpdate"; -import { logCensor } from "./logFunctions/logCensor"; -import { logChannelCreate } from "./logFunctions/logChannelCreate"; -import { logChannelDelete } from "./logFunctions/logChannelDelete"; -import { logChannelUpdate } from "./logFunctions/logChannelUpdate"; -import { logClean } from "./logFunctions/logClean"; -import { logDmFailed } from "./logFunctions/logDmFailed"; -import { logEmojiCreate } from "./logFunctions/logEmojiCreate"; -import { logEmojiDelete } from "./logFunctions/logEmojiDelete"; -import { logEmojiUpdate } from "./logFunctions/logEmojiUpdate"; -import { logMassBan } from "./logFunctions/logMassBan"; -import { logMassMute } from "./logFunctions/logMassMute"; -import { logMassUnban } from "./logFunctions/logMassUnban"; -import { logMemberBan } from "./logFunctions/logMemberBan"; -import { logMemberForceban } from "./logFunctions/logMemberForceban"; -import { logMemberJoin } from "./logFunctions/logMemberJoin"; -import { logMemberJoinWithPriorRecords } from "./logFunctions/logMemberJoinWithPriorRecords"; -import { logMemberKick } from "./logFunctions/logMemberKick"; -import { logMemberLeave } from "./logFunctions/logMemberLeave"; -import { logMemberMute } from "./logFunctions/logMemberMute"; -import { logMemberMuteExpired } from "./logFunctions/logMemberMuteExpired"; -import { logMemberMuteRejoin } from "./logFunctions/logMemberMuteRejoin"; -import { logMemberNickChange } from "./logFunctions/logMemberNickChange"; -import { logMemberNote } from "./logFunctions/logMemberNote"; -import { logMemberRestore } from "./logFunctions/logMemberRestore"; -import { logMemberRoleAdd } from "./logFunctions/logMemberRoleAdd"; -import { logMemberRoleChanges } from "./logFunctions/logMemberRoleChanges"; -import { logMemberRoleRemove } from "./logFunctions/logMemberRoleRemove"; -import { logMemberTimedBan } from "./logFunctions/logMemberTimedBan"; -import { logMemberTimedMute } from "./logFunctions/logMemberTimedMute"; -import { logMemberTimedUnban } from "./logFunctions/logMemberTimedUnban"; -import { logMemberTimedUnmute } from "./logFunctions/logMemberTimedUnmute"; -import { logMemberUnban } from "./logFunctions/logMemberUnban"; -import { logMemberUnmute } from "./logFunctions/logMemberUnmute"; -import { logMemberWarn } from "./logFunctions/logMemberWarn"; -import { logMessageDelete } from "./logFunctions/logMessageDelete"; -import { logMessageDeleteAuto } from "./logFunctions/logMessageDeleteAuto"; -import { logMessageDeleteBare } from "./logFunctions/logMessageDeleteBare"; -import { logMessageDeleteBulk } from "./logFunctions/logMessageDeleteBulk"; -import { logMessageEdit } from "./logFunctions/logMessageEdit"; -import { logMessageSpamDetected } from "./logFunctions/logMessageSpamDetected"; -import { logOtherSpamDetected } from "./logFunctions/logOtherSpamDetected"; -import { logPostedScheduledMessage } from "./logFunctions/logPostedScheduledMessage"; -import { logRepeatedMessage } from "./logFunctions/logRepeatedMessage"; -import { logRoleCreate } from "./logFunctions/logRoleCreate"; -import { logRoleDelete } from "./logFunctions/logRoleDelete"; -import { logRoleUpdate } from "./logFunctions/logRoleUpdate"; -import { logScheduledMessage } from "./logFunctions/logScheduledMessage"; -import { logScheduledRepeatedMessage } from "./logFunctions/logScheduledRepeatedMessage"; -import { logSetAntiraidAuto } from "./logFunctions/logSetAntiraidAuto"; -import { logSetAntiraidUser } from "./logFunctions/logSetAntiraidUser"; -import { logStageInstanceCreate } from "./logFunctions/logStageInstanceCreate"; -import { logStageInstanceDelete } from "./logFunctions/logStageInstanceDelete"; -import { logStageInstanceUpdate } from "./logFunctions/logStageInstanceUpdate"; -import { logStickerCreate } from "./logFunctions/logStickerCreate"; -import { logStickerDelete } from "./logFunctions/logStickerDelete"; -import { logStickerUpdate } from "./logFunctions/logStickerUpdate"; -import { logThreadCreate } from "./logFunctions/logThreadCreate"; -import { logThreadDelete } from "./logFunctions/logThreadDelete"; -import { logThreadUpdate } from "./logFunctions/logThreadUpdate"; -import { logVoiceChannelForceDisconnect } from "./logFunctions/logVoiceChannelForceDisconnect"; -import { logVoiceChannelForceMove } from "./logFunctions/logVoiceChannelForceMove"; -import { logVoiceChannelJoin } from "./logFunctions/logVoiceChannelJoin"; -import { logVoiceChannelLeave } from "./logFunctions/logVoiceChannelLeave"; -import { logVoiceChannelMove } from "./logFunctions/logVoiceChannelMove"; +import { InternalPosterPlugin } from "../InternalPoster/InternalPosterPlugin.js"; +import { LogsGuildMemberRoleChangeEvt } from "./events/LogsGuildMemberRoleChangeEvt.js"; +import { logAutomodAction } from "./logFunctions/logAutomodAction.js"; +import { logBotAlert } from "./logFunctions/logBotAlert.js"; +import { logCaseCreate } from "./logFunctions/logCaseCreate.js"; +import { logCaseDelete } from "./logFunctions/logCaseDelete.js"; +import { logCaseUpdate } from "./logFunctions/logCaseUpdate.js"; +import { logCensor } from "./logFunctions/logCensor.js"; +import { logChannelCreate } from "./logFunctions/logChannelCreate.js"; +import { logChannelDelete } from "./logFunctions/logChannelDelete.js"; +import { logChannelUpdate } from "./logFunctions/logChannelUpdate.js"; +import { logClean } from "./logFunctions/logClean.js"; +import { logDmFailed } from "./logFunctions/logDmFailed.js"; +import { logEmojiCreate } from "./logFunctions/logEmojiCreate.js"; +import { logEmojiDelete } from "./logFunctions/logEmojiDelete.js"; +import { logEmojiUpdate } from "./logFunctions/logEmojiUpdate.js"; +import { logMassBan } from "./logFunctions/logMassBan.js"; +import { logMassMute } from "./logFunctions/logMassMute.js"; +import { logMassUnban } from "./logFunctions/logMassUnban.js"; +import { logMemberBan } from "./logFunctions/logMemberBan.js"; +import { logMemberForceban } from "./logFunctions/logMemberForceban.js"; +import { logMemberJoin } from "./logFunctions/logMemberJoin.js"; +import { logMemberJoinWithPriorRecords } from "./logFunctions/logMemberJoinWithPriorRecords.js"; +import { logMemberKick } from "./logFunctions/logMemberKick.js"; +import { logMemberLeave } from "./logFunctions/logMemberLeave.js"; +import { logMemberMute } from "./logFunctions/logMemberMute.js"; +import { logMemberMuteExpired } from "./logFunctions/logMemberMuteExpired.js"; +import { logMemberMuteRejoin } from "./logFunctions/logMemberMuteRejoin.js"; +import { logMemberNickChange } from "./logFunctions/logMemberNickChange.js"; +import { logMemberNote } from "./logFunctions/logMemberNote.js"; +import { logMemberRestore } from "./logFunctions/logMemberRestore.js"; +import { logMemberRoleAdd } from "./logFunctions/logMemberRoleAdd.js"; +import { logMemberRoleChanges } from "./logFunctions/logMemberRoleChanges.js"; +import { logMemberRoleRemove } from "./logFunctions/logMemberRoleRemove.js"; +import { logMemberTimedBan } from "./logFunctions/logMemberTimedBan.js"; +import { logMemberTimedMute } from "./logFunctions/logMemberTimedMute.js"; +import { logMemberTimedUnban } from "./logFunctions/logMemberTimedUnban.js"; +import { logMemberTimedUnmute } from "./logFunctions/logMemberTimedUnmute.js"; +import { logMemberUnban } from "./logFunctions/logMemberUnban.js"; +import { logMemberUnmute } from "./logFunctions/logMemberUnmute.js"; +import { logMemberWarn } from "./logFunctions/logMemberWarn.js"; +import { logMessageDelete } from "./logFunctions/logMessageDelete.js"; +import { logMessageDeleteAuto } from "./logFunctions/logMessageDeleteAuto.js"; +import { logMessageDeleteBare } from "./logFunctions/logMessageDeleteBare.js"; +import { logMessageDeleteBulk } from "./logFunctions/logMessageDeleteBulk.js"; +import { logMessageEdit } from "./logFunctions/logMessageEdit.js"; +import { logMessageSpamDetected } from "./logFunctions/logMessageSpamDetected.js"; +import { logOtherSpamDetected } from "./logFunctions/logOtherSpamDetected.js"; +import { logPostedScheduledMessage } from "./logFunctions/logPostedScheduledMessage.js"; +import { logRepeatedMessage } from "./logFunctions/logRepeatedMessage.js"; +import { logRoleCreate } from "./logFunctions/logRoleCreate.js"; +import { logRoleDelete } from "./logFunctions/logRoleDelete.js"; +import { logRoleUpdate } from "./logFunctions/logRoleUpdate.js"; +import { logScheduledMessage } from "./logFunctions/logScheduledMessage.js"; +import { logScheduledRepeatedMessage } from "./logFunctions/logScheduledRepeatedMessage.js"; +import { logSetAntiraidAuto } from "./logFunctions/logSetAntiraidAuto.js"; +import { logSetAntiraidUser } from "./logFunctions/logSetAntiraidUser.js"; +import { logStageInstanceCreate } from "./logFunctions/logStageInstanceCreate.js"; +import { logStageInstanceDelete } from "./logFunctions/logStageInstanceDelete.js"; +import { logStageInstanceUpdate } from "./logFunctions/logStageInstanceUpdate.js"; +import { logStickerCreate } from "./logFunctions/logStickerCreate.js"; +import { logStickerDelete } from "./logFunctions/logStickerDelete.js"; +import { logStickerUpdate } from "./logFunctions/logStickerUpdate.js"; +import { logThreadCreate } from "./logFunctions/logThreadCreate.js"; +import { logThreadDelete } from "./logFunctions/logThreadDelete.js"; +import { logThreadUpdate } from "./logFunctions/logThreadUpdate.js"; +import { logVoiceChannelForceDisconnect } from "./logFunctions/logVoiceChannelForceDisconnect.js"; +import { logVoiceChannelForceMove } from "./logFunctions/logVoiceChannelForceMove.js"; +import { logVoiceChannelJoin } from "./logFunctions/logVoiceChannelJoin.js"; +import { logVoiceChannelLeave } from "./logFunctions/logVoiceChannelLeave.js"; +import { logVoiceChannelMove } from "./logFunctions/logVoiceChannelMove.js"; // The `any` cast here is to prevent TypeScript from locking up from the circular dependency function getCasesPlugin(): Promise { diff --git a/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts b/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts index 79c06dcf..dfa9b489 100644 --- a/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsChannelModifyEvts.ts @@ -1,10 +1,10 @@ import { TextChannel, VoiceChannel } from "discord.js"; -import { differenceToString, getScalarDifference } from "../../../utils"; -import { filterObject } from "../../../utils/filterObject"; -import { logChannelCreate } from "../logFunctions/logChannelCreate"; -import { logChannelDelete } from "../logFunctions/logChannelDelete"; -import { logChannelUpdate } from "../logFunctions/logChannelUpdate"; -import { logsEvt } from "../types"; +import { differenceToString, getScalarDifference } from "../../../utils.js"; +import { filterObject } from "../../../utils/filterObject.js"; +import { logChannelCreate } from "../logFunctions/logChannelCreate.js"; +import { logChannelDelete } from "../logFunctions/logChannelDelete.js"; +import { logChannelUpdate } from "../logFunctions/logChannelUpdate.js"; +import { logsEvt } from "../types.js"; export const LogsChannelCreateEvt = logsEvt({ event: "channelCreate", diff --git a/backend/src/plugins/Logs/events/LogsEmojiAndStickerModifyEvts.ts b/backend/src/plugins/Logs/events/LogsEmojiAndStickerModifyEvts.ts index 414073cf..61236ed9 100644 --- a/backend/src/plugins/Logs/events/LogsEmojiAndStickerModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsEmojiAndStickerModifyEvts.ts @@ -1,13 +1,13 @@ import { GuildEmoji, Sticker } from "discord.js"; -import { differenceToString, getScalarDifference } from "../../../utils"; -import { filterObject } from "../../../utils/filterObject"; -import { logEmojiCreate } from "../logFunctions/logEmojiCreate"; -import { logEmojiDelete } from "../logFunctions/logEmojiDelete"; -import { logEmojiUpdate } from "../logFunctions/logEmojiUpdate"; -import { logStickerCreate } from "../logFunctions/logStickerCreate"; -import { logStickerDelete } from "../logFunctions/logStickerDelete"; -import { logStickerUpdate } from "../logFunctions/logStickerUpdate"; -import { logsEvt } from "../types"; +import { differenceToString, getScalarDifference } from "../../../utils.js"; +import { filterObject } from "../../../utils/filterObject.js"; +import { logEmojiCreate } from "../logFunctions/logEmojiCreate.js"; +import { logEmojiDelete } from "../logFunctions/logEmojiDelete.js"; +import { logEmojiUpdate } from "../logFunctions/logEmojiUpdate.js"; +import { logStickerCreate } from "../logFunctions/logStickerCreate.js"; +import { logStickerDelete } from "../logFunctions/logStickerDelete.js"; +import { logStickerUpdate } from "../logFunctions/logStickerUpdate.js"; +import { logsEvt } from "../types.js"; export const LogsEmojiCreateEvt = logsEvt({ event: "emojiCreate", diff --git a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts index 1fda8b80..0b6c2558 100644 --- a/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts +++ b/backend/src/plugins/Logs/events/LogsGuildBanEvts.ts @@ -1,10 +1,10 @@ import { AuditLogEvent } from "discord.js"; -import { LogType } from "../../../data/LogType"; -import { findMatchingAuditLogEntry } from "../../../utils/findMatchingAuditLogEntry"; -import { logMemberBan } from "../logFunctions/logMemberBan"; -import { logMemberUnban } from "../logFunctions/logMemberUnban"; -import { logsEvt } from "../types"; -import { isLogIgnored } from "../util/isLogIgnored"; +import { LogType } from "../../../data/LogType.js"; +import { findMatchingAuditLogEntry } from "../../../utils/findMatchingAuditLogEntry.js"; +import { logMemberBan } from "../logFunctions/logMemberBan.js"; +import { logMemberUnban } from "../logFunctions/logMemberUnban.js"; +import { logsEvt } from "../types.js"; +import { isLogIgnored } from "../util/isLogIgnored.js"; export const LogsGuildBanAddEvt = logsEvt({ event: "guildBanAdd", diff --git a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts index 31e3ecd0..d792e060 100644 --- a/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts +++ b/backend/src/plugins/Logs/events/LogsGuildMemberAddEvt.ts @@ -1,5 +1,5 @@ -import { logMemberJoin } from "../logFunctions/logMemberJoin"; -import { logsEvt } from "../types"; +import { logMemberJoin } from "../logFunctions/logMemberJoin.js"; +import { logsEvt } from "../types.js"; 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 5c3fc923..9a4010cb 100644 --- a/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts +++ b/backend/src/plugins/Logs/events/LogsGuildMemberRemoveEvt.ts @@ -1,5 +1,5 @@ -import { logMemberLeave } from "../logFunctions/logMemberLeave"; -import { logsEvt } from "../types"; +import { logMemberLeave } from "../logFunctions/logMemberLeave.js"; +import { logsEvt } from "../types.js"; export const LogsGuildMemberRemoveEvt = logsEvt({ event: "guildMemberRemove", diff --git a/backend/src/plugins/Logs/events/LogsGuildMemberRoleChangeEvt.ts b/backend/src/plugins/Logs/events/LogsGuildMemberRoleChangeEvt.ts index ad1ef2d1..2075c020 100644 --- a/backend/src/plugins/Logs/events/LogsGuildMemberRoleChangeEvt.ts +++ b/backend/src/plugins/Logs/events/LogsGuildMemberRoleChangeEvt.ts @@ -1,9 +1,9 @@ import { APIRole, AuditLogChange, AuditLogEvent } from "discord.js"; import { guildPluginEventListener } from "knub"; -import { resolveRole } from "../../../utils"; -import { logMemberRoleAdd } from "../logFunctions/logMemberRoleAdd"; -import { logMemberRoleRemove } from "../logFunctions/logMemberRoleRemove"; -import { LogsPluginType } from "../types"; +import { resolveRole } from "../../../utils.js"; +import { logMemberRoleAdd } from "../logFunctions/logMemberRoleAdd.js"; +import { logMemberRoleRemove } from "../logFunctions/logMemberRoleRemove.js"; +import { LogsPluginType } from "../types.js"; type RoleAddChange = AuditLogChange & { key: "$add"; diff --git a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts index c44a4894..31bae0f1 100644 --- a/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsRoleModifyEvts.ts @@ -1,10 +1,10 @@ import { Role } from "discord.js"; -import { differenceToString, getScalarDifference } from "../../../utils"; -import { filterObject } from "../../../utils/filterObject"; -import { logRoleCreate } from "../logFunctions/logRoleCreate"; -import { logRoleDelete } from "../logFunctions/logRoleDelete"; -import { logRoleUpdate } from "../logFunctions/logRoleUpdate"; -import { logsEvt } from "../types"; +import { differenceToString, getScalarDifference } from "../../../utils.js"; +import { filterObject } from "../../../utils/filterObject.js"; +import { logRoleCreate } from "../logFunctions/logRoleCreate.js"; +import { logRoleDelete } from "../logFunctions/logRoleDelete.js"; +import { logRoleUpdate } from "../logFunctions/logRoleUpdate.js"; +import { logsEvt } from "../types.js"; export const LogsRoleCreateEvt = logsEvt({ event: "roleCreate", diff --git a/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts b/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts index 202fee0d..10d2960c 100644 --- a/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsStageInstanceModifyEvts.ts @@ -1,10 +1,10 @@ import { StageChannel, StageInstance } from "discord.js"; -import { differenceToString, getScalarDifference } from "../../../utils"; -import { filterObject } from "../../../utils/filterObject"; -import { logStageInstanceCreate } from "../logFunctions/logStageInstanceCreate"; -import { logStageInstanceDelete } from "../logFunctions/logStageInstanceDelete"; -import { logStageInstanceUpdate } from "../logFunctions/logStageInstanceUpdate"; -import { logsEvt } from "../types"; +import { differenceToString, getScalarDifference } from "../../../utils.js"; +import { filterObject } from "../../../utils/filterObject.js"; +import { logStageInstanceCreate } from "../logFunctions/logStageInstanceCreate.js"; +import { logStageInstanceDelete } from "../logFunctions/logStageInstanceDelete.js"; +import { logStageInstanceUpdate } from "../logFunctions/logStageInstanceUpdate.js"; +import { logsEvt } from "../types.js"; export const LogsStageInstanceCreateEvt = logsEvt({ event: "stageInstanceCreate", diff --git a/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts b/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts index 2568a1bc..71327a43 100644 --- a/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts +++ b/backend/src/plugins/Logs/events/LogsThreadModifyEvts.ts @@ -1,10 +1,10 @@ import { ThreadChannel } from "discord.js"; -import { differenceToString, getScalarDifference } from "../../../utils"; -import { filterObject } from "../../../utils/filterObject"; -import { logThreadCreate } from "../logFunctions/logThreadCreate"; -import { logThreadDelete } from "../logFunctions/logThreadDelete"; -import { logThreadUpdate } from "../logFunctions/logThreadUpdate"; -import { logsEvt } from "../types"; +import { differenceToString, getScalarDifference } from "../../../utils.js"; +import { filterObject } from "../../../utils/filterObject.js"; +import { logThreadCreate } from "../logFunctions/logThreadCreate.js"; +import { logThreadDelete } from "../logFunctions/logThreadDelete.js"; +import { logThreadUpdate } from "../logFunctions/logThreadUpdate.js"; +import { logsEvt } from "../types.js"; export const LogsThreadCreateEvt = logsEvt({ event: "threadCreate", diff --git a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts index f5da56fc..849647d7 100644 --- a/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts +++ b/backend/src/plugins/Logs/events/LogsUserUpdateEvts.ts @@ -1,5 +1,5 @@ -import { logMemberNickChange } from "../logFunctions/logMemberNickChange"; -import { logsEvt } from "../types"; +import { logMemberNickChange } from "../logFunctions/logMemberNickChange.js"; +import { logsEvt } from "../types.js"; export const LogsGuildMemberUpdateEvt = logsEvt({ event: "guildMemberUpdate", diff --git a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts index 4b21610e..d06577c9 100644 --- a/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts +++ b/backend/src/plugins/Logs/events/LogsVoiceChannelEvts.ts @@ -1,7 +1,7 @@ -import { logVoiceChannelJoin } from "../logFunctions/logVoiceChannelJoin"; -import { logVoiceChannelLeave } from "../logFunctions/logVoiceChannelLeave"; -import { logVoiceChannelMove } from "../logFunctions/logVoiceChannelMove"; -import { logsEvt } from "../types"; +import { logVoiceChannelJoin } from "../logFunctions/logVoiceChannelJoin.js"; +import { logVoiceChannelLeave } from "../logFunctions/logVoiceChannelLeave.js"; +import { logVoiceChannelMove } from "../logFunctions/logVoiceChannelMove.js"; +import { logsEvt } from "../types.js"; export const LogsVoiceStateUpdateEvt = logsEvt({ event: "voiceStateUpdate", diff --git a/backend/src/plugins/Logs/info.ts b/backend/src/plugins/Logs/info.ts index 10683a03..6d9f200a 100644 --- a/backend/src/plugins/Logs/info.ts +++ b/backend/src/plugins/Logs/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { zLogsConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { zLogsConfig } from "./types.js"; export const logsPluginInfo: ZeppelinPluginInfo = { prettyName: "Logs", diff --git a/backend/src/plugins/Logs/logFunctions/logAutomodAction.ts b/backend/src/plugins/Logs/logFunctions/logAutomodAction.ts index 2a2fd69c..165f192b 100644 --- a/backend/src/plugins/Logs/logFunctions/logAutomodAction.ts +++ b/backend/src/plugins/Logs/logFunctions/logAutomodAction.ts @@ -1,10 +1,10 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogAutomodActionData { rule: string; diff --git a/backend/src/plugins/Logs/logFunctions/logBotAlert.ts b/backend/src/plugins/Logs/logFunctions/logBotAlert.ts index 1438b249..8320799b 100644 --- a/backend/src/plugins/Logs/logFunctions/logBotAlert.ts +++ b/backend/src/plugins/Logs/logFunctions/logBotAlert.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogBotAlertData { body: string; diff --git a/backend/src/plugins/Logs/logFunctions/logCaseCreate.ts b/backend/src/plugins/Logs/logFunctions/logCaseCreate.ts index d2fe96b9..cb62ea43 100644 --- a/backend/src/plugins/Logs/logFunctions/logCaseCreate.ts +++ b/backend/src/plugins/Logs/logFunctions/logCaseCreate.ts @@ -1,10 +1,10 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogCaseCreateData { mod: User; diff --git a/backend/src/plugins/Logs/logFunctions/logCaseDelete.ts b/backend/src/plugins/Logs/logFunctions/logCaseDelete.ts index 8c701cc5..c5393221 100644 --- a/backend/src/plugins/Logs/logFunctions/logCaseDelete.ts +++ b/backend/src/plugins/Logs/logFunctions/logCaseDelete.ts @@ -1,11 +1,11 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { Case } from "../../../data/entities/Case"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { caseToTemplateSafeCase, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { Case } from "../../../data/entities/Case.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { caseToTemplateSafeCase, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogCaseDeleteData { mod: GuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logCaseUpdate.ts b/backend/src/plugins/Logs/logFunctions/logCaseUpdate.ts index 4c8b8fd6..966cabc4 100644 --- a/backend/src/plugins/Logs/logFunctions/logCaseUpdate.ts +++ b/backend/src/plugins/Logs/logFunctions/logCaseUpdate.ts @@ -1,10 +1,10 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogCaseUpdateData { mod: User; diff --git a/backend/src/plugins/Logs/logFunctions/logCensor.ts b/backend/src/plugins/Logs/logFunctions/logCensor.ts index c1853baf..47590196 100644 --- a/backend/src/plugins/Logs/logFunctions/logCensor.ts +++ b/backend/src/plugins/Logs/logFunctions/logCensor.ts @@ -1,18 +1,18 @@ import { GuildTextBasedChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; import { deactivateMentions, disableCodeBlocks } from "knub/helpers"; -import { LogType } from "../../../data/LogType"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; +import { LogType } from "../../../data/LogType.js"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; import { channelToTemplateSafeChannel, savedMessageToTemplateSafeSavedMessage, userToTemplateSafeUser, -} from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +} from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogCensorData { user: User | UnknownUser; diff --git a/backend/src/plugins/Logs/logFunctions/logChannelCreate.ts b/backend/src/plugins/Logs/logFunctions/logChannelCreate.ts index be8adf8c..2f91829d 100644 --- a/backend/src/plugins/Logs/logFunctions/logChannelCreate.ts +++ b/backend/src/plugins/Logs/logFunctions/logChannelCreate.ts @@ -1,11 +1,11 @@ import { GuildBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogChannelCreateData { channel: GuildBasedChannel; diff --git a/backend/src/plugins/Logs/logFunctions/logChannelDelete.ts b/backend/src/plugins/Logs/logFunctions/logChannelDelete.ts index 6078f311..029169c8 100644 --- a/backend/src/plugins/Logs/logFunctions/logChannelDelete.ts +++ b/backend/src/plugins/Logs/logFunctions/logChannelDelete.ts @@ -1,11 +1,11 @@ import { GuildBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogChannelDeleteData { channel: GuildBasedChannel; diff --git a/backend/src/plugins/Logs/logFunctions/logChannelUpdate.ts b/backend/src/plugins/Logs/logFunctions/logChannelUpdate.ts index 2963520a..0e0cb9af 100644 --- a/backend/src/plugins/Logs/logFunctions/logChannelUpdate.ts +++ b/backend/src/plugins/Logs/logFunctions/logChannelUpdate.ts @@ -1,11 +1,11 @@ import { GuildBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogChannelUpdateData { oldChannel: GuildBasedChannel; diff --git a/backend/src/plugins/Logs/logFunctions/logClean.ts b/backend/src/plugins/Logs/logFunctions/logClean.ts index 2a156868..4915811b 100644 --- a/backend/src/plugins/Logs/logFunctions/logClean.ts +++ b/backend/src/plugins/Logs/logFunctions/logClean.ts @@ -1,11 +1,11 @@ import { GuildTextBasedChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogCleanData { mod: User; diff --git a/backend/src/plugins/Logs/logFunctions/logDmFailed.ts b/backend/src/plugins/Logs/logFunctions/logDmFailed.ts index 4b540624..7915a1d1 100644 --- a/backend/src/plugins/Logs/logFunctions/logDmFailed.ts +++ b/backend/src/plugins/Logs/logFunctions/logDmFailed.ts @@ -1,11 +1,11 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogDmFailedData { source: string; diff --git a/backend/src/plugins/Logs/logFunctions/logEmojiCreate.ts b/backend/src/plugins/Logs/logFunctions/logEmojiCreate.ts index 11c6c0d9..c9902dcf 100644 --- a/backend/src/plugins/Logs/logFunctions/logEmojiCreate.ts +++ b/backend/src/plugins/Logs/logFunctions/logEmojiCreate.ts @@ -1,10 +1,10 @@ import { Emoji } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { emojiToTemplateSafeEmoji } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { emojiToTemplateSafeEmoji } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogEmojiCreateData { emoji: Emoji; diff --git a/backend/src/plugins/Logs/logFunctions/logEmojiDelete.ts b/backend/src/plugins/Logs/logFunctions/logEmojiDelete.ts index 4ef31c4e..e00f4d60 100644 --- a/backend/src/plugins/Logs/logFunctions/logEmojiDelete.ts +++ b/backend/src/plugins/Logs/logFunctions/logEmojiDelete.ts @@ -1,10 +1,10 @@ import { Emoji } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { emojiToTemplateSafeEmoji } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { emojiToTemplateSafeEmoji } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogEmojiDeleteData { emoji: Emoji; diff --git a/backend/src/plugins/Logs/logFunctions/logEmojiUpdate.ts b/backend/src/plugins/Logs/logFunctions/logEmojiUpdate.ts index 3d455530..1ce68880 100644 --- a/backend/src/plugins/Logs/logFunctions/logEmojiUpdate.ts +++ b/backend/src/plugins/Logs/logFunctions/logEmojiUpdate.ts @@ -1,10 +1,10 @@ import { Emoji } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { emojiToTemplateSafeEmoji } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { emojiToTemplateSafeEmoji } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogEmojiUpdateData { oldEmoji: Emoji; diff --git a/backend/src/plugins/Logs/logFunctions/logMassBan.ts b/backend/src/plugins/Logs/logFunctions/logMassBan.ts index 6f2695cc..c4694754 100644 --- a/backend/src/plugins/Logs/logFunctions/logMassBan.ts +++ b/backend/src/plugins/Logs/logFunctions/logMassBan.ts @@ -1,10 +1,10 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMassBanData { mod: User; diff --git a/backend/src/plugins/Logs/logFunctions/logMassMute.ts b/backend/src/plugins/Logs/logFunctions/logMassMute.ts index 74c8694b..32e5995b 100644 --- a/backend/src/plugins/Logs/logFunctions/logMassMute.ts +++ b/backend/src/plugins/Logs/logFunctions/logMassMute.ts @@ -1,10 +1,10 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMassMuteData { mod: User; diff --git a/backend/src/plugins/Logs/logFunctions/logMassUnban.ts b/backend/src/plugins/Logs/logFunctions/logMassUnban.ts index 59709bef..ff0fa2e6 100644 --- a/backend/src/plugins/Logs/logFunctions/logMassUnban.ts +++ b/backend/src/plugins/Logs/logFunctions/logMassUnban.ts @@ -1,10 +1,10 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMassUnbanData { mod: User; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberBan.ts b/backend/src/plugins/Logs/logFunctions/logMemberBan.ts index cdeaec62..5759ce50 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberBan.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberBan.ts @@ -1,11 +1,11 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberBanData { mod: User | UnknownUser | null; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberForceban.ts b/backend/src/plugins/Logs/logFunctions/logMemberForceban.ts index dc47736c..d591f99f 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberForceban.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberForceban.ts @@ -1,10 +1,10 @@ import { GuildMember, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberForcebanData { mod: GuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberJoin.ts b/backend/src/plugins/Logs/logFunctions/logMemberJoin.ts index 81771fbd..0ee7ae7f 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberJoin.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberJoin.ts @@ -2,11 +2,11 @@ import { GuildMember } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberJoinData { member: GuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberJoinWithPriorRecords.ts b/backend/src/plugins/Logs/logFunctions/logMemberJoinWithPriorRecords.ts index 01cbd81f..0db96c23 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberJoinWithPriorRecords.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberJoinWithPriorRecords.ts @@ -1,10 +1,10 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberJoinWithPriorRecordsData { member: GuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberKick.ts b/backend/src/plugins/Logs/logFunctions/logMemberKick.ts index e60f1124..f623a45c 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberKick.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberKick.ts @@ -1,11 +1,11 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberKickData { mod: User | UnknownUser | null; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberLeave.ts b/backend/src/plugins/Logs/logFunctions/logMemberLeave.ts index 8753b68b..09a80a62 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberLeave.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberLeave.ts @@ -1,10 +1,10 @@ import { GuildMember, PartialGuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberLeaveData { member: GuildMember | PartialGuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberMute.ts b/backend/src/plugins/Logs/logFunctions/logMemberMute.ts index 76e7f352..3d598ff3 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberMute.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberMute.ts @@ -1,11 +1,11 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberMuteData { mod: User | UnknownUser; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberMuteExpired.ts b/backend/src/plugins/Logs/logFunctions/logMemberMuteExpired.ts index 24e52aba..4cdd3aa5 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberMuteExpired.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberMuteExpired.ts @@ -1,15 +1,15 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; import { memberToTemplateSafeMember, TemplateSafeUnknownMember, TemplateSafeUnknownUser, -} from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +} from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberMuteExpiredData { member: GuildMember | UnknownUser; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberMuteRejoin.ts b/backend/src/plugins/Logs/logFunctions/logMemberMuteRejoin.ts index 455a13d8..2d3eddd0 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberMuteRejoin.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberMuteRejoin.ts @@ -1,10 +1,10 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberMuteRejoinData { member: GuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberNickChange.ts b/backend/src/plugins/Logs/logFunctions/logMemberNickChange.ts index 437dfa02..22e3e693 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberNickChange.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberNickChange.ts @@ -1,10 +1,10 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberNickChangeData { member: GuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberNote.ts b/backend/src/plugins/Logs/logFunctions/logMemberNote.ts index c81ccb7a..8435fd64 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberNote.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberNote.ts @@ -1,11 +1,11 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberNoteData { mod: User; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberRestore.ts b/backend/src/plugins/Logs/logFunctions/logMemberRestore.ts index b93b5558..7cfd70f6 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberRestore.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberRestore.ts @@ -1,10 +1,10 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberRestoreData { member: GuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberRoleAdd.ts b/backend/src/plugins/Logs/logFunctions/logMemberRoleAdd.ts index bb6255df..1e413c53 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberRoleAdd.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberRoleAdd.ts @@ -1,11 +1,11 @@ import { GuildMember, Role, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownRole } from "../../../utils"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownRole } from "../../../utils.js"; +import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberRoleAddData { mod: User | null; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberRoleChanges.ts b/backend/src/plugins/Logs/logFunctions/logMemberRoleChanges.ts index f548fe2d..e6c785b3 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberRoleChanges.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberRoleChanges.ts @@ -1,11 +1,11 @@ import { GuildMember, Role, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberRoleChangesData { mod: User | UnknownUser | null; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberRoleRemove.ts b/backend/src/plugins/Logs/logFunctions/logMemberRoleRemove.ts index 4e620eec..58dbd7d2 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberRoleRemove.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberRoleRemove.ts @@ -1,11 +1,11 @@ import { GuildMember, Role, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownRole } from "../../../utils"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownRole } from "../../../utils.js"; +import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberRoleRemoveData { mod: User | null; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberTimedBan.ts b/backend/src/plugins/Logs/logFunctions/logMemberTimedBan.ts index ecc1d2a2..bcc36ae3 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberTimedBan.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberTimedBan.ts @@ -1,11 +1,11 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberTimedBanData { mod: User | UnknownUser; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberTimedMute.ts b/backend/src/plugins/Logs/logFunctions/logMemberTimedMute.ts index 4ef04bed..efc20363 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberTimedMute.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberTimedMute.ts @@ -1,11 +1,11 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberTimedMuteData { mod: User | UnknownUser; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberTimedUnban.ts b/backend/src/plugins/Logs/logFunctions/logMemberTimedUnban.ts index ada44504..3d80bfae 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberTimedUnban.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberTimedUnban.ts @@ -1,11 +1,11 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberTimedUnbanData { mod: User | UnknownUser; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberTimedUnmute.ts b/backend/src/plugins/Logs/logFunctions/logMemberTimedUnmute.ts index ce036761..947ce9d1 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberTimedUnmute.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberTimedUnmute.ts @@ -1,11 +1,11 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberTimedUnmuteData { mod: User; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberUnban.ts b/backend/src/plugins/Logs/logFunctions/logMemberUnban.ts index 305bbada..d29cb011 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberUnban.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberUnban.ts @@ -1,11 +1,11 @@ import { Snowflake, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberUnbanData { mod: User | UnknownUser | null; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberUnmute.ts b/backend/src/plugins/Logs/logFunctions/logMemberUnmute.ts index 5afbf075..32d57f0a 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberUnmute.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberUnmute.ts @@ -1,11 +1,11 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberUnmuteData { mod: User; diff --git a/backend/src/plugins/Logs/logFunctions/logMemberWarn.ts b/backend/src/plugins/Logs/logFunctions/logMemberWarn.ts index 8cdc533b..1f162c86 100644 --- a/backend/src/plugins/Logs/logFunctions/logMemberWarn.ts +++ b/backend/src/plugins/Logs/logFunctions/logMemberWarn.ts @@ -1,10 +1,10 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMemberWarnData { mod: GuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logMessageDelete.ts b/backend/src/plugins/Logs/logFunctions/logMessageDelete.ts index b56f7410..d9e175b5 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageDelete.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageDelete.ts @@ -1,19 +1,19 @@ import { GuildTextBasedChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { LogType } from "../../../data/LogType"; -import { ISavedMessageAttachmentData, SavedMessage } from "../../../data/entities/SavedMessage"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser, useMediaUrls } from "../../../utils"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; +import { LogType } from "../../../data/LogType.js"; +import { ISavedMessageAttachmentData, SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser, useMediaUrls } from "../../../utils.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; import { channelToTemplateSafeChannel, savedMessageToTemplateSafeSavedMessage, userToTemplateSafeUser, -} from "../../../utils/templateSafeObjects"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types"; -import { log } from "../util/log"; +} from "../../../utils/templateSafeObjects.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js"; +import { FORMAT_NO_TIMESTAMP, LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMessageDeleteData { user: User | UnknownUser; diff --git a/backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts b/backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts index 1b2b1fe3..c4b04bd6 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts @@ -1,17 +1,17 @@ import { GuildBasedChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; +import { LogType } from "../../../data/LogType.js"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; import { channelToTemplateSafeChannel, savedMessageToTemplateSafeSavedMessage, userToTemplateSafeUser, -} from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +} from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMessageDeleteAutoData { message: SavedMessage; diff --git a/backend/src/plugins/Logs/logFunctions/logMessageDeleteBare.ts b/backend/src/plugins/Logs/logFunctions/logMessageDeleteBare.ts index 8e1787ab..14e628d2 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageDeleteBare.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageDeleteBare.ts @@ -1,11 +1,11 @@ import { GuildTextBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMessageDeleteBareData { messageId: string; diff --git a/backend/src/plugins/Logs/logFunctions/logMessageDeleteBulk.ts b/backend/src/plugins/Logs/logFunctions/logMessageDeleteBulk.ts index 46ca1648..2d979f2b 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageDeleteBulk.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageDeleteBulk.ts @@ -1,11 +1,11 @@ import { GuildTextBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMessageDeleteBulkData { count: number; diff --git a/backend/src/plugins/Logs/logFunctions/logMessageEdit.ts b/backend/src/plugins/Logs/logFunctions/logMessageEdit.ts index 6e31605d..4a695ecd 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageEdit.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageEdit.ts @@ -1,17 +1,17 @@ import { GuildTextBasedChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { UnknownUser } from "../../../utils"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; +import { LogType } from "../../../data/LogType.js"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { UnknownUser } from "../../../utils.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; import { channelToTemplateSafeChannel, savedMessageToTemplateSafeSavedMessage, userToTemplateSafeUser, -} from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +} from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMessageEditData { user: User | UnknownUser; diff --git a/backend/src/plugins/Logs/logFunctions/logMessageSpamDetected.ts b/backend/src/plugins/Logs/logFunctions/logMessageSpamDetected.ts index 5a79e5ab..1d00cbe0 100644 --- a/backend/src/plugins/Logs/logFunctions/logMessageSpamDetected.ts +++ b/backend/src/plugins/Logs/logFunctions/logMessageSpamDetected.ts @@ -1,11 +1,11 @@ import { GuildMember, GuildTextBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogMessageSpamDetectedData { member: GuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logOtherSpamDetected.ts b/backend/src/plugins/Logs/logFunctions/logOtherSpamDetected.ts index 9cbd8b25..39b9969f 100644 --- a/backend/src/plugins/Logs/logFunctions/logOtherSpamDetected.ts +++ b/backend/src/plugins/Logs/logFunctions/logOtherSpamDetected.ts @@ -1,10 +1,10 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogOtherSpamDetectedData { member: GuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logPostedScheduledMessage.ts b/backend/src/plugins/Logs/logFunctions/logPostedScheduledMessage.ts index e92d0292..5ffa3b2e 100644 --- a/backend/src/plugins/Logs/logFunctions/logPostedScheduledMessage.ts +++ b/backend/src/plugins/Logs/logFunctions/logPostedScheduledMessage.ts @@ -1,11 +1,11 @@ import { GuildTextBasedChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogPostedScheduledMessageData { author: User; diff --git a/backend/src/plugins/Logs/logFunctions/logRepeatedMessage.ts b/backend/src/plugins/Logs/logFunctions/logRepeatedMessage.ts index 227ca7f7..720bc4fc 100644 --- a/backend/src/plugins/Logs/logFunctions/logRepeatedMessage.ts +++ b/backend/src/plugins/Logs/logFunctions/logRepeatedMessage.ts @@ -1,11 +1,11 @@ import { GuildTextBasedChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogRepeatedMessageData { author: User; diff --git a/backend/src/plugins/Logs/logFunctions/logRoleCreate.ts b/backend/src/plugins/Logs/logFunctions/logRoleCreate.ts index 9bb177d6..146191e9 100644 --- a/backend/src/plugins/Logs/logFunctions/logRoleCreate.ts +++ b/backend/src/plugins/Logs/logFunctions/logRoleCreate.ts @@ -1,10 +1,10 @@ import { Role } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { roleToTemplateSafeRole } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { roleToTemplateSafeRole } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogRoleCreateData { role: Role; diff --git a/backend/src/plugins/Logs/logFunctions/logRoleDelete.ts b/backend/src/plugins/Logs/logFunctions/logRoleDelete.ts index 0ec6e87a..0c22f083 100644 --- a/backend/src/plugins/Logs/logFunctions/logRoleDelete.ts +++ b/backend/src/plugins/Logs/logFunctions/logRoleDelete.ts @@ -1,10 +1,10 @@ import { Role } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { roleToTemplateSafeRole } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { roleToTemplateSafeRole } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogRoleDeleteData { role: Role; diff --git a/backend/src/plugins/Logs/logFunctions/logRoleUpdate.ts b/backend/src/plugins/Logs/logFunctions/logRoleUpdate.ts index caf8b0c5..1371fce3 100644 --- a/backend/src/plugins/Logs/logFunctions/logRoleUpdate.ts +++ b/backend/src/plugins/Logs/logFunctions/logRoleUpdate.ts @@ -1,10 +1,10 @@ import { Role } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { roleToTemplateSafeRole } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { roleToTemplateSafeRole } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogRoleUpdateData { oldRole: Role; diff --git a/backend/src/plugins/Logs/logFunctions/logScheduledMessage.ts b/backend/src/plugins/Logs/logFunctions/logScheduledMessage.ts index 098b7918..18c72486 100644 --- a/backend/src/plugins/Logs/logFunctions/logScheduledMessage.ts +++ b/backend/src/plugins/Logs/logFunctions/logScheduledMessage.ts @@ -1,11 +1,11 @@ import { GuildTextBasedChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogScheduledMessageData { author: User; diff --git a/backend/src/plugins/Logs/logFunctions/logScheduledRepeatedMessage.ts b/backend/src/plugins/Logs/logFunctions/logScheduledRepeatedMessage.ts index dc4c4200..86b416a2 100644 --- a/backend/src/plugins/Logs/logFunctions/logScheduledRepeatedMessage.ts +++ b/backend/src/plugins/Logs/logFunctions/logScheduledRepeatedMessage.ts @@ -1,11 +1,11 @@ import { GuildTextBasedChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogScheduledRepeatedMessageData { author: User; diff --git a/backend/src/plugins/Logs/logFunctions/logSetAntiraidAuto.ts b/backend/src/plugins/Logs/logFunctions/logSetAntiraidAuto.ts index 6c841eeb..69c8e01b 100644 --- a/backend/src/plugins/Logs/logFunctions/logSetAntiraidAuto.ts +++ b/backend/src/plugins/Logs/logFunctions/logSetAntiraidAuto.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogSetAntiraidAutoData { level: string; diff --git a/backend/src/plugins/Logs/logFunctions/logSetAntiraidUser.ts b/backend/src/plugins/Logs/logFunctions/logSetAntiraidUser.ts index 7d43423b..fb9b2fb9 100644 --- a/backend/src/plugins/Logs/logFunctions/logSetAntiraidUser.ts +++ b/backend/src/plugins/Logs/logFunctions/logSetAntiraidUser.ts @@ -1,10 +1,10 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogSetAntiraidUserData { level: string; diff --git a/backend/src/plugins/Logs/logFunctions/logStageInstanceCreate.ts b/backend/src/plugins/Logs/logFunctions/logStageInstanceCreate.ts index 31d900c4..e812c96a 100644 --- a/backend/src/plugins/Logs/logFunctions/logStageInstanceCreate.ts +++ b/backend/src/plugins/Logs/logFunctions/logStageInstanceCreate.ts @@ -1,11 +1,11 @@ import { StageChannel, StageInstance } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel, stageToTemplateSafeStage } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel, stageToTemplateSafeStage } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogStageInstanceCreateData { stageInstance: StageInstance; diff --git a/backend/src/plugins/Logs/logFunctions/logStageInstanceDelete.ts b/backend/src/plugins/Logs/logFunctions/logStageInstanceDelete.ts index ff69b13f..6f4a9453 100644 --- a/backend/src/plugins/Logs/logFunctions/logStageInstanceDelete.ts +++ b/backend/src/plugins/Logs/logFunctions/logStageInstanceDelete.ts @@ -1,11 +1,11 @@ import { StageChannel, StageInstance } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel, stageToTemplateSafeStage } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel, stageToTemplateSafeStage } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogStageInstanceDeleteData { stageInstance: StageInstance; diff --git a/backend/src/plugins/Logs/logFunctions/logStageInstanceUpdate.ts b/backend/src/plugins/Logs/logFunctions/logStageInstanceUpdate.ts index be53b598..1d00ecb4 100644 --- a/backend/src/plugins/Logs/logFunctions/logStageInstanceUpdate.ts +++ b/backend/src/plugins/Logs/logFunctions/logStageInstanceUpdate.ts @@ -1,11 +1,11 @@ import { StageChannel, StageInstance } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel, stageToTemplateSafeStage } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel, stageToTemplateSafeStage } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogStageInstanceUpdateData { oldStageInstance: StageInstance | null; diff --git a/backend/src/plugins/Logs/logFunctions/logStickerCreate.ts b/backend/src/plugins/Logs/logFunctions/logStickerCreate.ts index 6c715235..df9951be 100644 --- a/backend/src/plugins/Logs/logFunctions/logStickerCreate.ts +++ b/backend/src/plugins/Logs/logFunctions/logStickerCreate.ts @@ -1,10 +1,10 @@ import { Sticker } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { stickerToTemplateSafeSticker } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { stickerToTemplateSafeSticker } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogStickerCreateData { sticker: Sticker; diff --git a/backend/src/plugins/Logs/logFunctions/logStickerDelete.ts b/backend/src/plugins/Logs/logFunctions/logStickerDelete.ts index 99c4532f..a789abb8 100644 --- a/backend/src/plugins/Logs/logFunctions/logStickerDelete.ts +++ b/backend/src/plugins/Logs/logFunctions/logStickerDelete.ts @@ -1,10 +1,10 @@ import { Sticker } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { stickerToTemplateSafeSticker } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { stickerToTemplateSafeSticker } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogStickerDeleteData { sticker: Sticker; diff --git a/backend/src/plugins/Logs/logFunctions/logStickerUpdate.ts b/backend/src/plugins/Logs/logFunctions/logStickerUpdate.ts index e1e2e727..59630c95 100644 --- a/backend/src/plugins/Logs/logFunctions/logStickerUpdate.ts +++ b/backend/src/plugins/Logs/logFunctions/logStickerUpdate.ts @@ -1,10 +1,10 @@ import { Sticker } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { stickerToTemplateSafeSticker } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { stickerToTemplateSafeSticker } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogStickerUpdateData { oldSticker: Sticker; diff --git a/backend/src/plugins/Logs/logFunctions/logThreadCreate.ts b/backend/src/plugins/Logs/logFunctions/logThreadCreate.ts index 62f9a47c..f323c94d 100644 --- a/backend/src/plugins/Logs/logFunctions/logThreadCreate.ts +++ b/backend/src/plugins/Logs/logFunctions/logThreadCreate.ts @@ -1,11 +1,11 @@ import { AnyThreadChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogThreadCreateData { thread: AnyThreadChannel; diff --git a/backend/src/plugins/Logs/logFunctions/logThreadDelete.ts b/backend/src/plugins/Logs/logFunctions/logThreadDelete.ts index 52dd4908..fa0171c9 100644 --- a/backend/src/plugins/Logs/logFunctions/logThreadDelete.ts +++ b/backend/src/plugins/Logs/logFunctions/logThreadDelete.ts @@ -1,11 +1,11 @@ import { AnyThreadChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogThreadDeleteData { thread: AnyThreadChannel; diff --git a/backend/src/plugins/Logs/logFunctions/logThreadUpdate.ts b/backend/src/plugins/Logs/logFunctions/logThreadUpdate.ts index f73bab5d..3f44aa5a 100644 --- a/backend/src/plugins/Logs/logFunctions/logThreadUpdate.ts +++ b/backend/src/plugins/Logs/logFunctions/logThreadUpdate.ts @@ -1,11 +1,11 @@ import { AnyThreadChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogThreadUpdateData { oldThread: AnyThreadChannel; diff --git a/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceDisconnect.ts b/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceDisconnect.ts index 79efc844..dc93aa48 100644 --- a/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceDisconnect.ts +++ b/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceDisconnect.ts @@ -1,15 +1,15 @@ import { GuildMember, User, VoiceBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; import { channelToTemplateSafeChannel, memberToTemplateSafeMember, userToTemplateSafeUser, -} from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +} from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogVoiceChannelForceDisconnectData { mod: User; diff --git a/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceMove.ts b/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceMove.ts index 70978304..f601286c 100644 --- a/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceMove.ts +++ b/backend/src/plugins/Logs/logFunctions/logVoiceChannelForceMove.ts @@ -1,15 +1,15 @@ import { GuildMember, User, VoiceBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; import { channelToTemplateSafeChannel, memberToTemplateSafeMember, userToTemplateSafeUser, -} from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +} from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogVoiceChannelForceMoveData { mod: User; diff --git a/backend/src/plugins/Logs/logFunctions/logVoiceChannelJoin.ts b/backend/src/plugins/Logs/logFunctions/logVoiceChannelJoin.ts index f91cf4a2..0bb4a8d0 100644 --- a/backend/src/plugins/Logs/logFunctions/logVoiceChannelJoin.ts +++ b/backend/src/plugins/Logs/logFunctions/logVoiceChannelJoin.ts @@ -1,11 +1,11 @@ import { GuildMember, VoiceBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogVoiceChannelJoinData { member: GuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logVoiceChannelLeave.ts b/backend/src/plugins/Logs/logFunctions/logVoiceChannelLeave.ts index 99b35155..a7f449f2 100644 --- a/backend/src/plugins/Logs/logFunctions/logVoiceChannelLeave.ts +++ b/backend/src/plugins/Logs/logFunctions/logVoiceChannelLeave.ts @@ -1,11 +1,11 @@ import { GuildMember, VoiceBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogVoiceChannelLeaveData { member: GuildMember; diff --git a/backend/src/plugins/Logs/logFunctions/logVoiceChannelMove.ts b/backend/src/plugins/Logs/logFunctions/logVoiceChannelMove.ts index 679c66d3..6ab4b197 100644 --- a/backend/src/plugins/Logs/logFunctions/logVoiceChannelMove.ts +++ b/backend/src/plugins/Logs/logFunctions/logVoiceChannelMove.ts @@ -1,11 +1,11 @@ import { GuildMember, VoiceBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { resolveChannelIds } from "../../../utils/resolveChannelIds"; -import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects"; -import { LogsPluginType } from "../types"; -import { log } from "../util/log"; +import { LogType } from "../../../data/LogType.js"; +import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { resolveChannelIds } from "../../../utils/resolveChannelIds.js"; +import { channelToTemplateSafeChannel, memberToTemplateSafeMember } from "../../../utils/templateSafeObjects.js"; +import { LogsPluginType } from "../types.js"; +import { log } from "../util/log.js"; interface LogVoiceChannelMoveData { member: GuildMember; diff --git a/backend/src/plugins/Logs/types.ts b/backend/src/plugins/Logs/types.ts index 47557514..820aac95 100644 --- a/backend/src/plugins/Logs/types.ts +++ b/backend/src/plugins/Logs/types.ts @@ -1,13 +1,13 @@ import { BasePluginType, CooldownManager, guildPluginEventListener } from "knub"; import { z } from "zod"; -import { RegExpRunner } from "../../RegExpRunner"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildCases } from "../../data/GuildCases"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { LogType } from "../../data/LogType"; -import { keys, zBoundedCharacters, zMessageContent, zRegex, zSnowflake } from "../../utils"; -import { MessageBuffer } from "../../utils/MessageBuffer"; +import { RegExpRunner } from "../../RegExpRunner.js"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildCases } from "../../data/GuildCases.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { LogType } from "../../data/LogType.js"; +import { keys, zBoundedCharacters, zMessageContent, zRegex, zSnowflake } from "../../utils.js"; +import { MessageBuffer } from "../../utils/MessageBuffer.js"; import { TemplateSafeCase, TemplateSafeChannel, @@ -20,7 +20,7 @@ import { TemplateSafeUnknownMember, TemplateSafeUnknownUser, TemplateSafeUser, -} from "../../utils/templateSafeObjects"; +} from "../../utils/templateSafeObjects.js"; const DEFAULT_BATCH_TIME = 1000; const MIN_BATCH_TIME = 250; diff --git a/backend/src/plugins/Logs/util/getLogMessage.ts b/backend/src/plugins/Logs/util/getLogMessage.ts index 4887cb82..99aca3e7 100644 --- a/backend/src/plugins/Logs/util/getLogMessage.ts +++ b/backend/src/plugins/Logs/util/getLogMessage.ts @@ -1,14 +1,14 @@ import { MessageCreateOptions } from "discord.js"; import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { LogType } from "../../../data/LogType"; -import { logger } from "../../../logger"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { LogType } from "../../../data/LogType.js"; +import { logger } from "../../../logger.js"; import { renderTemplate, TemplateParseError, TemplateSafeValueContainer, TypedTemplateSafeValueContainer, -} from "../../../templateFormatter"; +} from "../../../templateFormatter.js"; import { messageSummary, renderRecursively, @@ -17,15 +17,15 @@ import { verboseChannelMention, verboseUserMention, verboseUserName, -} from "../../../utils"; +} from "../../../utils.js"; import { getTemplateSafeMemberLevel, memberToTemplateSafeMember, TemplateSafeMember, TemplateSafeUser, -} from "../../../utils/templateSafeObjects"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { FORMAT_NO_TIMESTAMP, ILogTypeData, LogsPluginType, TLogChannel } from "../types"; +} from "../../../utils/templateSafeObjects.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js"; +import { FORMAT_NO_TIMESTAMP, ILogTypeData, LogsPluginType, TLogChannel } from "../types.js"; export async function getLogMessage( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Logs/util/isLogIgnored.ts b/backend/src/plugins/Logs/util/isLogIgnored.ts index 8d3e15c1..578c33b3 100644 --- a/backend/src/plugins/Logs/util/isLogIgnored.ts +++ b/backend/src/plugins/Logs/util/isLogIgnored.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { LogsPluginType } from "../types"; +import { LogType } from "../../../data/LogType.js"; +import { LogsPluginType } from "../types.js"; export function isLogIgnored( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index 5a9259d6..914dfeaa 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -1,13 +1,13 @@ import { APIEmbed, MessageMentionTypes, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { allowTimeout } from "../../../RegExpRunner"; -import { LogType } from "../../../data/LogType"; -import { TypedTemplateSafeValueContainer } from "../../../templateFormatter"; -import { MINUTES, isDiscordAPIError } from "../../../utils"; -import { MessageBuffer } from "../../../utils/MessageBuffer"; -import { InternalPosterPlugin } from "../../InternalPoster/InternalPosterPlugin"; -import { ILogTypeData, LogsPluginType, TLogChannel, TLogChannelMap } from "../types"; -import { getLogMessage } from "./getLogMessage"; +import { allowTimeout } from "../../../RegExpRunner.js"; +import { LogType } from "../../../data/LogType.js"; +import { TypedTemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { MINUTES, isDiscordAPIError } from "../../../utils.js"; +import { MessageBuffer } from "../../../utils/MessageBuffer.js"; +import { InternalPosterPlugin } from "../../InternalPoster/InternalPosterPlugin.js"; +import { ILogTypeData, LogsPluginType, TLogChannel, TLogChannelMap } from "../types.js"; +import { getLogMessage } from "./getLogMessage.js"; interface ExclusionData { userId?: Snowflake | null; diff --git a/backend/src/plugins/Logs/util/onMessageDelete.ts b/backend/src/plugins/Logs/util/onMessageDelete.ts index 01d91123..2d63e7e1 100644 --- a/backend/src/plugins/Logs/util/onMessageDelete.ts +++ b/backend/src/plugins/Logs/util/onMessageDelete.ts @@ -1,12 +1,12 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { resolveUser } from "../../../utils"; -import { logMessageDelete } from "../logFunctions/logMessageDelete"; -import { logMessageDeleteBare } from "../logFunctions/logMessageDeleteBare"; -import { LogsPluginType } from "../types"; -import { isLogIgnored } from "./isLogIgnored"; +import { LogType } from "../../../data/LogType.js"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { resolveUser } from "../../../utils.js"; +import { logMessageDelete } from "../logFunctions/logMessageDelete.js"; +import { logMessageDeleteBare } from "../logFunctions/logMessageDeleteBare.js"; +import { LogsPluginType } from "../types.js"; +import { isLogIgnored } from "./isLogIgnored.js"; export async function onMessageDelete(pluginData: GuildPluginData, savedMessage: SavedMessage) { const user = await resolveUser(pluginData.client, savedMessage.user_id); diff --git a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts index 5fc79da0..2165eb1c 100644 --- a/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts +++ b/backend/src/plugins/Logs/util/onMessageDeleteBulk.ts @@ -1,11 +1,11 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { getBaseUrl } from "../../../pluginUtils"; -import { logMessageDeleteBulk } from "../logFunctions/logMessageDeleteBulk"; -import { LogsPluginType } from "../types"; -import { isLogIgnored } from "./isLogIgnored"; +import { LogType } from "../../../data/LogType.js"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { getBaseUrl } from "../../../pluginUtils.js"; +import { logMessageDeleteBulk } from "../logFunctions/logMessageDeleteBulk.js"; +import { LogsPluginType } from "../types.js"; +import { isLogIgnored } from "./isLogIgnored.js"; export async function onMessageDeleteBulk(pluginData: GuildPluginData, savedMessages: SavedMessage[]) { if (isLogIgnored(pluginData, LogType.MESSAGE_DELETE, savedMessages[0].id)) { diff --git a/backend/src/plugins/Logs/util/onMessageUpdate.ts b/backend/src/plugins/Logs/util/onMessageUpdate.ts index a94b1fe6..e5e1c019 100644 --- a/backend/src/plugins/Logs/util/onMessageUpdate.ts +++ b/backend/src/plugins/Logs/util/onMessageUpdate.ts @@ -1,10 +1,10 @@ import { EmbedData, GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import cloneDeep from "lodash.clonedeep"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { resolveUser } from "../../../utils"; -import { logMessageEdit } from "../logFunctions/logMessageEdit"; -import { LogsPluginType } from "../types"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { resolveUser } from "../../../utils.js"; +import { logMessageEdit } from "../logFunctions/logMessageEdit.js"; +import { LogsPluginType } from "../types.js"; export async function onMessageUpdate( pluginData: GuildPluginData, diff --git a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts index 9ea040bf..5196ef23 100644 --- a/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts +++ b/backend/src/plugins/MessageSaver/MessageSaverPlugin.ts @@ -1,10 +1,10 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { SaveMessagesToDBCmd } from "./commands/SaveMessagesToDB"; -import { SavePinsToDBCmd } from "./commands/SavePinsToDB"; -import { MessageCreateEvt, MessageDeleteBulkEvt, MessageDeleteEvt, MessageUpdateEvt } from "./events/SaveMessagesEvts"; -import { MessageSaverPluginType, zMessageSaverConfig } from "./types"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { SaveMessagesToDBCmd } from "./commands/SaveMessagesToDB.js"; +import { SavePinsToDBCmd } from "./commands/SavePinsToDB.js"; +import { MessageCreateEvt, MessageDeleteBulkEvt, MessageDeleteEvt, MessageUpdateEvt } from "./events/SaveMessagesEvts.js"; +import { MessageSaverPluginType, zMessageSaverConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts index 6097bf14..87543b02 100644 --- a/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SaveMessagesToDB.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { saveMessagesToDB } from "../saveMessagesToDB"; -import { messageSaverCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { saveMessagesToDB } from "../saveMessagesToDB.js"; +import { messageSaverCmd } from "../types.js"; export const SaveMessagesToDBCmd = messageSaverCmd({ trigger: "save_messages_to_db", diff --git a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts index 29bc2cbb..ab903581 100644 --- a/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts +++ b/backend/src/plugins/MessageSaver/commands/SavePinsToDB.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { saveMessagesToDB } from "../saveMessagesToDB"; -import { messageSaverCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { saveMessagesToDB } from "../saveMessagesToDB.js"; +import { messageSaverCmd } from "../types.js"; export const SavePinsToDBCmd = messageSaverCmd({ trigger: "save_pins_to_db", diff --git a/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts b/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts index 594e2b53..66baac56 100644 --- a/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts +++ b/backend/src/plugins/MessageSaver/events/SaveMessagesEvts.ts @@ -1,5 +1,5 @@ import { Message, MessageType } from "discord.js"; -import { messageSaverEvt } from "../types"; +import { messageSaverEvt } from "../types.js"; const AFFECTED_MESSAGE_TYPES: MessageType[] = [MessageType.Default, MessageType.Reply, MessageType.ChatInputCommand]; diff --git a/backend/src/plugins/MessageSaver/info.ts b/backend/src/plugins/MessageSaver/info.ts index e71c5430..2a9b9bda 100644 --- a/backend/src/plugins/MessageSaver/info.ts +++ b/backend/src/plugins/MessageSaver/info.ts @@ -1,4 +1,4 @@ -import { ZeppelinPluginInfo } from "../../types"; +import { ZeppelinPluginInfo } from "../../types.js"; export const messageSaverPluginInfo: ZeppelinPluginInfo = { prettyName: "Message saver", diff --git a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts index 750ab632..01aa85cb 100644 --- a/backend/src/plugins/MessageSaver/saveMessagesToDB.ts +++ b/backend/src/plugins/MessageSaver/saveMessagesToDB.ts @@ -1,6 +1,6 @@ import { GuildTextBasedChannel, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { MessageSaverPluginType } from "./types"; +import { MessageSaverPluginType } from "./types.js"; export async function saveMessagesToDB( pluginData: GuildPluginData, diff --git a/backend/src/plugins/MessageSaver/types.ts b/backend/src/plugins/MessageSaver/types.ts index 671eb9d9..1102a9ac 100644 --- a/backend/src/plugins/MessageSaver/types.ts +++ b/backend/src/plugins/MessageSaver/types.ts @@ -1,7 +1,7 @@ import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zMessageSaverConfig = z.strictObject({ can_manage: z.boolean(), diff --git a/backend/src/plugins/ModActions/ModActionsPlugin.ts b/backend/src/plugins/ModActions/ModActionsPlugin.ts index a501fbc9..798f2f12 100644 --- a/backend/src/plugins/ModActions/ModActionsPlugin.ts +++ b/backend/src/plugins/ModActions/ModActionsPlugin.ts @@ -1,78 +1,78 @@ import { Message } from "discord.js"; import { EventEmitter } from "events"; import { guildPlugin } from "knub"; -import { Queue } from "../../Queue"; -import { GuildCases } from "../../data/GuildCases"; -import { onGuildEvent } from "../../data/GuildEvents"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildMutes } from "../../data/GuildMutes"; -import { GuildTempbans } from "../../data/GuildTempbans"; -import { makePublicFn, mapToPublicFn } from "../../pluginUtils"; -import { MINUTES } from "../../utils"; -import { CasesPlugin } from "../Cases/CasesPlugin"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { MutesPlugin } from "../Mutes/MutesPlugin"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { AddCaseMsgCmd } from "./commands/addcase/AddCaseMsgCmd"; -import { AddCaseSlashCmd } from "./commands/addcase/AddCaseSlashCmd"; -import { BanMsgCmd } from "./commands/ban/BanMsgCmd"; -import { BanSlashCmd } from "./commands/ban/BanSlashCmd"; -import { CaseMsgCmd } from "./commands/case/CaseMsgCmd"; -import { CaseSlashCmd } from "./commands/case/CaseSlashCmd"; -import { CasesModMsgCmd } from "./commands/cases/CasesModMsgCmd"; -import { CasesSlashCmd } from "./commands/cases/CasesSlashCmd"; -import { CasesUserMsgCmd } from "./commands/cases/CasesUserMsgCmd"; -import { DeleteCaseMsgCmd } from "./commands/deletecase/DeleteCaseMsgCmd"; -import { DeleteCaseSlashCmd } from "./commands/deletecase/DeleteCaseSlashCmd"; -import { ForceBanMsgCmd } from "./commands/forceban/ForceBanMsgCmd"; -import { ForceBanSlashCmd } from "./commands/forceban/ForceBanSlashCmd"; -import { ForceMuteMsgCmd } from "./commands/forcemute/ForceMuteMsgCmd"; -import { ForceMuteSlashCmd } from "./commands/forcemute/ForceMuteSlashCmd"; -import { ForceUnmuteMsgCmd } from "./commands/forceunmute/ForceUnmuteMsgCmd"; -import { ForceUnmuteSlashCmd } from "./commands/forceunmute/ForceUnmuteSlashCmd"; -import { HideCaseMsgCmd } from "./commands/hidecase/HideCaseMsgCmd"; -import { HideCaseSlashCmd } from "./commands/hidecase/HideCaseSlashCmd"; -import { KickMsgCmd } from "./commands/kick/KickMsgCmd"; -import { KickSlashCmd } from "./commands/kick/KickSlashCmd"; -import { MassBanMsgCmd } from "./commands/massban/MassBanMsgCmd"; -import { MassBanSlashCmd } from "./commands/massban/MassBanSlashCmd"; -import { MassMuteMsgCmd } from "./commands/massmute/MassMuteMsgCmd"; -import { MassMuteSlashSlashCmd } from "./commands/massmute/MassMuteSlashCmd"; -import { MassUnbanMsgCmd } from "./commands/massunban/MassUnbanMsgCmd"; -import { MassUnbanSlashCmd } from "./commands/massunban/MassUnbanSlashCmd"; -import { MuteMsgCmd } from "./commands/mute/MuteMsgCmd"; -import { MuteSlashCmd } from "./commands/mute/MuteSlashCmd"; -import { NoteMsgCmd } from "./commands/note/NoteMsgCmd"; -import { NoteSlashCmd } from "./commands/note/NoteSlashCmd"; -import { UnbanMsgCmd } from "./commands/unban/UnbanMsgCmd"; -import { UnbanSlashCmd } from "./commands/unban/UnbanSlashCmd"; -import { UnhideCaseMsgCmd } from "./commands/unhidecase/UnhideCaseMsgCmd"; -import { UnhideCaseSlashCmd } from "./commands/unhidecase/UnhideCaseSlashCmd"; -import { UnmuteMsgCmd } from "./commands/unmute/UnmuteMsgCmd"; -import { UnmuteSlashCmd } from "./commands/unmute/UnmuteSlashCmd"; -import { UpdateMsgCmd } from "./commands/update/UpdateMsgCmd"; -import { UpdateSlashCmd } from "./commands/update/UpdateSlashCmd"; -import { WarnMsgCmd } from "./commands/warn/WarnMsgCmd"; -import { WarnSlashCmd } from "./commands/warn/WarnSlashCmd"; -import { AuditLogEvents } from "./events/AuditLogEvents"; -import { CreateBanCaseOnManualBanEvt } from "./events/CreateBanCaseOnManualBanEvt"; -import { CreateUnbanCaseOnManualUnbanEvt } from "./events/CreateUnbanCaseOnManualUnbanEvt"; -import { PostAlertOnMemberJoinEvt } from "./events/PostAlertOnMemberJoinEvt"; -import { banUserId } from "./functions/banUserId"; -import { clearTempban } from "./functions/clearTempban"; +import { Queue } from "../../Queue.js"; +import { GuildCases } from "../../data/GuildCases.js"; +import { onGuildEvent } from "../../data/GuildEvents.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildMutes } from "../../data/GuildMutes.js"; +import { GuildTempbans } from "../../data/GuildTempbans.js"; +import { makePublicFn, mapToPublicFn } from "../../pluginUtils.js"; +import { MINUTES } from "../../utils.js"; +import { CasesPlugin } from "../Cases/CasesPlugin.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { MutesPlugin } from "../Mutes/MutesPlugin.js"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin.js"; +import { AddCaseMsgCmd } from "./commands/addcase/AddCaseMsgCmd.js"; +import { AddCaseSlashCmd } from "./commands/addcase/AddCaseSlashCmd.js"; +import { BanMsgCmd } from "./commands/ban/BanMsgCmd.js"; +import { BanSlashCmd } from "./commands/ban/BanSlashCmd.js"; +import { CaseMsgCmd } from "./commands/case/CaseMsgCmd.js"; +import { CaseSlashCmd } from "./commands/case/CaseSlashCmd.js"; +import { CasesModMsgCmd } from "./commands/cases/CasesModMsgCmd.js"; +import { CasesSlashCmd } from "./commands/cases/CasesSlashCmd.js"; +import { CasesUserMsgCmd } from "./commands/cases/CasesUserMsgCmd.js"; +import { DeleteCaseMsgCmd } from "./commands/deletecase/DeleteCaseMsgCmd.js"; +import { DeleteCaseSlashCmd } from "./commands/deletecase/DeleteCaseSlashCmd.js"; +import { ForceBanMsgCmd } from "./commands/forceban/ForceBanMsgCmd.js"; +import { ForceBanSlashCmd } from "./commands/forceban/ForceBanSlashCmd.js"; +import { ForceMuteMsgCmd } from "./commands/forcemute/ForceMuteMsgCmd.js"; +import { ForceMuteSlashCmd } from "./commands/forcemute/ForceMuteSlashCmd.js"; +import { ForceUnmuteMsgCmd } from "./commands/forceunmute/ForceUnmuteMsgCmd.js"; +import { ForceUnmuteSlashCmd } from "./commands/forceunmute/ForceUnmuteSlashCmd.js"; +import { HideCaseMsgCmd } from "./commands/hidecase/HideCaseMsgCmd.js"; +import { HideCaseSlashCmd } from "./commands/hidecase/HideCaseSlashCmd.js"; +import { KickMsgCmd } from "./commands/kick/KickMsgCmd.js"; +import { KickSlashCmd } from "./commands/kick/KickSlashCmd.js"; +import { MassBanMsgCmd } from "./commands/massban/MassBanMsgCmd.js"; +import { MassBanSlashCmd } from "./commands/massban/MassBanSlashCmd.js"; +import { MassMuteMsgCmd } from "./commands/massmute/MassMuteMsgCmd.js"; +import { MassMuteSlashSlashCmd } from "./commands/massmute/MassMuteSlashCmd.js"; +import { MassUnbanMsgCmd } from "./commands/massunban/MassUnbanMsgCmd.js"; +import { MassUnbanSlashCmd } from "./commands/massunban/MassUnbanSlashCmd.js"; +import { MuteMsgCmd } from "./commands/mute/MuteMsgCmd.js"; +import { MuteSlashCmd } from "./commands/mute/MuteSlashCmd.js"; +import { NoteMsgCmd } from "./commands/note/NoteMsgCmd.js"; +import { NoteSlashCmd } from "./commands/note/NoteSlashCmd.js"; +import { UnbanMsgCmd } from "./commands/unban/UnbanMsgCmd.js"; +import { UnbanSlashCmd } from "./commands/unban/UnbanSlashCmd.js"; +import { UnhideCaseMsgCmd } from "./commands/unhidecase/UnhideCaseMsgCmd.js"; +import { UnhideCaseSlashCmd } from "./commands/unhidecase/UnhideCaseSlashCmd.js"; +import { UnmuteMsgCmd } from "./commands/unmute/UnmuteMsgCmd.js"; +import { UnmuteSlashCmd } from "./commands/unmute/UnmuteSlashCmd.js"; +import { UpdateMsgCmd } from "./commands/update/UpdateMsgCmd.js"; +import { UpdateSlashCmd } from "./commands/update/UpdateSlashCmd.js"; +import { WarnMsgCmd } from "./commands/warn/WarnMsgCmd.js"; +import { WarnSlashCmd } from "./commands/warn/WarnSlashCmd.js"; +import { AuditLogEvents } from "./events/AuditLogEvents.js"; +import { CreateBanCaseOnManualBanEvt } from "./events/CreateBanCaseOnManualBanEvt.js"; +import { CreateUnbanCaseOnManualUnbanEvt } from "./events/CreateUnbanCaseOnManualUnbanEvt.js"; +import { PostAlertOnMemberJoinEvt } from "./events/PostAlertOnMemberJoinEvt.js"; +import { banUserId } from "./functions/banUserId.js"; +import { clearTempban } from "./functions/clearTempban.js"; import { hasBanPermission, hasMutePermission, hasNotePermission, hasWarnPermission, -} from "./functions/hasModActionPerm"; -import { kickMember } from "./functions/kickMember"; -import { offModActionsEvent } from "./functions/offModActionsEvent"; -import { onModActionsEvent } from "./functions/onModActionsEvent"; -import { updateCase } from "./functions/updateCase"; -import { warnMember } from "./functions/warnMember"; -import { AttachmentLinkReactionType, ModActionsPluginType, modActionsSlashGroup, zModActionsConfig } from "./types"; +} from "./functions/hasModActionPerm.js"; +import { kickMember } from "./functions/kickMember.js"; +import { offModActionsEvent } from "./functions/offModActionsEvent.js"; +import { onModActionsEvent } from "./functions/onModActionsEvent.js"; +import { updateCase } from "./functions/updateCase.js"; +import { warnMember } from "./functions/warnMember.js"; +import { AttachmentLinkReactionType, ModActionsPluginType, modActionsSlashGroup, zModActionsConfig } from "./types.js"; const defaultOptions = { config: { diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts index bd9d85bf..4c69967e 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseMsgCmd.ts @@ -1,9 +1,9 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { CaseTypes } from "../../../../data/CaseTypes"; -import { hasPermission } from "../../../../pluginUtils"; -import { resolveUser } from "../../../../utils"; -import { modActionsMsgCmd } from "../../types"; -import { actualAddCaseCmd } from "./actualAddCaseCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { CaseTypes } from "../../../../data/CaseTypes.js"; +import { hasPermission } from "../../../../pluginUtils.js"; +import { resolveUser } from "../../../../utils.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualAddCaseCmd } from "./actualAddCaseCmd.js"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts index 23bb34a9..e84f609b 100644 --- a/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/AddCaseSlashCmd.ts @@ -1,12 +1,12 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { CaseTypes } from "../../../../data/CaseTypes"; -import { hasPermission } from "../../../../pluginUtils"; -import { resolveMember } from "../../../../utils"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualAddCaseCmd } from "./actualAddCaseCmd"; +import { CaseTypes } from "../../../../data/CaseTypes.js"; +import { hasPermission } from "../../../../pluginUtils.js"; +import { resolveMember } from "../../../../utils.js"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualAddCaseCmd } from "./actualAddCaseCmd.js"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), diff --git a/backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts b/backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts index ef676083..b6ec6a56 100644 --- a/backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/addcase/actualAddCaseCmd.ts @@ -1,14 +1,14 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../../data/CaseTypes"; -import { Case } from "../../../../data/entities/Case"; -import { canActOn } from "../../../../pluginUtils"; -import { UnknownUser, renderUsername, resolveMember } from "../../../../utils"; -import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; -import { ModActionsPluginType } from "../../types"; +import { CaseTypes } from "../../../../data/CaseTypes.js"; +import { Case } from "../../../../data/entities/Case.js"; +import { canActOn } from "../../../../pluginUtils.js"; +import { UnknownUser, renderUsername, resolveMember } from "../../../../utils.js"; +import { CasesPlugin } from "../../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../../Logs/LogsPlugin.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction.js"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments.js"; +import { ModActionsPluginType } from "../../types.js"; export async function actualAddCaseCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts index b218c2e0..c02fe298 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanMsgCmd.ts @@ -1,9 +1,9 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { hasPermission } from "../../../../pluginUtils"; -import { UserNotificationMethod, resolveUser } from "../../../../utils"; -import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; -import { modActionsMsgCmd } from "../../types"; -import { actualBanCmd } from "./actualBanCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { hasPermission } from "../../../../pluginUtils.js"; +import { UserNotificationMethod, resolveUser } from "../../../../utils.js"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualBanCmd } from "./actualBanCmd.js"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts index 12ea3f11..0732d774 100644 --- a/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/BanSlashCmd.ts @@ -1,12 +1,12 @@ import { ChannelType, GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { hasPermission } from "../../../../pluginUtils"; -import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualBanCmd } from "./actualBanCmd"; +import { hasPermission } from "../../../../pluginUtils.js"; +import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils.js"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualBanCmd } from "./actualBanCmd.js"; const opts = [ slashOptions.string({ name: "time", description: "The duration of the ban", required: false }), diff --git a/backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts b/backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts index 95706e6f..60903e44 100644 --- a/backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/ban/actualBanCmd.ts @@ -2,22 +2,22 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message, User } f import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import { getMemberLevel } from "knub/helpers"; -import { CaseTypes } from "../../../../data/CaseTypes"; -import { clearExpiringTempban, registerExpiringTempban } from "../../../../data/loops/expiringTempbansLoop"; -import { canActOn, getContextChannel } from "../../../../pluginUtils"; -import { UnknownUser, UserNotificationMethod, renderUsername, resolveMember } from "../../../../utils"; -import { banLock } from "../../../../utils/lockNameHelpers"; -import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; -import { banUserId } from "../../functions/banUserId"; +import { CaseTypes } from "../../../../data/CaseTypes.js"; +import { clearExpiringTempban, registerExpiringTempban } from "../../../../data/loops/expiringTempbansLoop.js"; +import { canActOn, getContextChannel } from "../../../../pluginUtils.js"; +import { UnknownUser, UserNotificationMethod, renderUsername, resolveMember } from "../../../../utils.js"; +import { banLock } from "../../../../utils/lockNameHelpers.js"; +import { waitForButtonConfirm } from "../../../../utils/waitForInteraction.js"; +import { CasesPlugin } from "../../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../../Logs/LogsPlugin.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction.js"; +import { banUserId } from "../../functions/banUserId.js"; import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments, -} from "../../functions/formatReasonForAttachments"; -import { isBanned } from "../../functions/isBanned"; -import { ModActionsPluginType } from "../../types"; +} from "../../functions/formatReasonForAttachments.js"; +import { isBanned } from "../../functions/isBanned.js"; +import { ModActionsPluginType } from "../../types.js"; export async function actualBanCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts index c2e8d8b5..211e529f 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseMsgCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { modActionsMsgCmd } from "../../types"; -import { actualCaseCmd } from "./actualCaseCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualCaseCmd } from "./actualCaseCmd.js"; const opts = { show: ct.switchOption({ def: false, shortcut: "sh" }), diff --git a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts index 220a9697..c2c7eccc 100644 --- a/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/CaseSlashCmd.ts @@ -1,6 +1,6 @@ import { slashOptions } from "knub"; -import { modActionsSlashCmd } from "../../types"; -import { actualCaseCmd } from "./actualCaseCmd"; +import { modActionsSlashCmd } from "../../types.js"; +import { actualCaseCmd } from "./actualCaseCmd.js"; const opts = [ slashOptions.boolean({ name: "show", description: "To make the result visible to everyone", required: false }), diff --git a/backend/src/plugins/ModActions/commands/case/actualCaseCmd.ts b/backend/src/plugins/ModActions/commands/case/actualCaseCmd.ts index 5be37726..ac4311ec 100644 --- a/backend/src/plugins/ModActions/commands/case/actualCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/case/actualCaseCmd.ts @@ -1,8 +1,8 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { sendContextResponse } from "../../../../pluginUtils"; -import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { ModActionsPluginType } from "../../types"; +import { sendContextResponse } from "../../../../pluginUtils.js"; +import { CasesPlugin } from "../../../Cases/CasesPlugin.js"; +import { ModActionsPluginType } from "../../types.js"; export async function actualCaseCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts index e55f1661..b57da947 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesModMsgCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { modActionsMsgCmd } from "../../types"; -import { actualCasesCmd } from "./actualCasesCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualCasesCmd } from "./actualCasesCmd.js"; const opts = { mod: ct.userId({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts index accb2050..4a9d3e15 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesSlashCmd.ts @@ -1,7 +1,7 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { modActionsSlashCmd } from "../../types"; -import { actualCasesCmd } from "./actualCasesCmd"; +import { modActionsSlashCmd } from "../../types.js"; +import { actualCasesCmd } from "./actualCasesCmd.js"; const opts = [ slashOptions.user({ name: "user", description: "The user to show cases for", required: false }), diff --git a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts index 7d425f2c..29adebd6 100644 --- a/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/CasesUserMsgCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { resolveMember, resolveUser, UnknownUser } from "../../../../utils"; -import { modActionsMsgCmd } from "../../types"; -import { actualCasesCmd } from "./actualCasesCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { resolveMember, resolveUser, UnknownUser } from "../../../../utils.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualCasesCmd } from "./actualCasesCmd.js"; const opts = { mod: ct.userId({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts b/backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts index 3e72303d..4ba1ecdd 100644 --- a/backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts +++ b/backend/src/plugins/ModActions/commands/cases/actualCasesCmd.ts @@ -2,9 +2,9 @@ import { APIEmbed, ChatInputCommandInteraction, GuildMember, Message, User } fro import { GuildPluginData } from "knub"; import { In } from "typeorm"; import { FindOptionsWhere } from "typeorm/find-options/FindOptionsWhere"; -import { CaseTypes } from "../../../../data/CaseTypes"; -import { Case } from "../../../../data/entities/Case"; -import { sendContextResponse } from "../../../../pluginUtils"; +import { CaseTypes } from "../../../../data/CaseTypes.js"; +import { Case } from "../../../../data/entities/Case.js"; +import { sendContextResponse } from "../../../../pluginUtils.js"; import { UnknownUser, chunkArray, @@ -13,12 +13,12 @@ import { resolveMember, resolveUser, trimLines, -} from "../../../../utils"; -import { asyncMap } from "../../../../utils/async"; -import { createPaginatedMessage } from "../../../../utils/createPaginatedMessage"; -import { getGuildPrefix } from "../../../../utils/getGuildPrefix"; -import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { ModActionsPluginType } from "../../types"; +} from "../../../../utils.js"; +import { asyncMap } from "../../../../utils/async.js"; +import { createPaginatedMessage } from "../../../../utils/createPaginatedMessage.js"; +import { getGuildPrefix } from "../../../../utils/getGuildPrefix.js"; +import { CasesPlugin } from "../../../Cases/CasesPlugin.js"; +import { ModActionsPluginType } from "../../types.js"; const casesPerPage = 5; const maxExpandedCases = 8; diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts index 396bd73f..c1449e93 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseMsgCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { trimLines } from "../../../../utils"; -import { modActionsMsgCmd } from "../../types"; -import { actualDeleteCaseCmd } from "./actualDeleteCaseCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { trimLines } from "../../../../utils.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualDeleteCaseCmd } from "./actualDeleteCaseCmd.js"; export const DeleteCaseMsgCmd = modActionsMsgCmd({ trigger: ["delete_case", "deletecase"], diff --git a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts index 932f4cad..b324c6e3 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/DeleteCaseSlashCmd.ts @@ -1,7 +1,7 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { modActionsSlashCmd } from "../../types"; -import { actualDeleteCaseCmd } from "./actualDeleteCaseCmd"; +import { modActionsSlashCmd } from "../../types.js"; +import { actualDeleteCaseCmd } from "./actualDeleteCaseCmd.js"; const opts = [slashOptions.boolean({ name: "force", description: "Whether or not to force delete", required: false })]; diff --git a/backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts b/backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts index 64c146ee..0e57fbf1 100644 --- a/backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/deletecase/actualDeleteCaseCmd.ts @@ -1,12 +1,12 @@ import { ChatInputCommandInteraction, GuildMember, Message } from "discord.js"; import { GuildPluginData, helpers } from "knub"; -import { Case } from "../../../../data/entities/Case"; -import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { SECONDS, renderUsername } from "../../../../utils"; -import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { TimeAndDatePlugin } from "../../../TimeAndDate/TimeAndDatePlugin"; -import { ModActionsPluginType } from "../../types"; +import { Case } from "../../../../data/entities/Case.js"; +import { getContextChannel, sendContextResponse } from "../../../../pluginUtils.js"; +import { SECONDS, renderUsername } from "../../../../utils.js"; +import { CasesPlugin } from "../../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../../Logs/LogsPlugin.js"; +import { TimeAndDatePlugin } from "../../../TimeAndDate/TimeAndDatePlugin.js"; +import { ModActionsPluginType } from "../../types.js"; export async function actualDeleteCaseCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts index 3546ee14..2f2cce21 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanMsgCmd.ts @@ -1,9 +1,9 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { canActOn, hasPermission } from "../../../../pluginUtils"; -import { resolveMember, resolveUser } from "../../../../utils"; -import { isBanned } from "../../functions/isBanned"; -import { modActionsMsgCmd } from "../../types"; -import { actualForceBanCmd } from "./actualForceBanCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { canActOn, hasPermission } from "../../../../pluginUtils.js"; +import { resolveMember, resolveUser } from "../../../../utils.js"; +import { isBanned } from "../../functions/isBanned.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualForceBanCmd } from "./actualForceBanCmd.js"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts index 14e27561..61fc9411 100644 --- a/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/ForceBanSlashCmd.ts @@ -1,11 +1,11 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { hasPermission } from "../../../../pluginUtils"; -import { convertDelayStringToMS, resolveMember } from "../../../../utils"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualForceBanCmd } from "./actualForceBanCmd"; +import { hasPermission } from "../../../../pluginUtils.js"; +import { convertDelayStringToMS, resolveMember } from "../../../../utils.js"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualForceBanCmd } from "./actualForceBanCmd.js"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), diff --git a/backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts b/backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts index 6b84901c..63495c62 100644 --- a/backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceban/actualForceBanCmd.ts @@ -1,17 +1,17 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message, Snowflake, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../../data/CaseTypes"; -import { LogType } from "../../../../data/LogType"; -import { DAYS, MINUTES, UnknownUser } from "../../../../utils"; -import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { CaseTypes } from "../../../../data/CaseTypes.js"; +import { LogType } from "../../../../data/LogType.js"; +import { DAYS, MINUTES, UnknownUser } from "../../../../utils.js"; +import { CasesPlugin } from "../../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../../Logs/LogsPlugin.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction.js"; import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments, -} from "../../functions/formatReasonForAttachments"; -import { ignoreEvent } from "../../functions/ignoreEvent"; -import { IgnoredEventType, ModActionsPluginType } from "../../types"; +} from "../../functions/formatReasonForAttachments.js"; +import { ignoreEvent } from "../../functions/ignoreEvent.js"; +import { IgnoredEventType, ModActionsPluginType } from "../../types.js"; export async function actualForceBanCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts index 384b34e8..1268fbc4 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteMsgCmd.ts @@ -1,9 +1,9 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { canActOn, hasPermission } from "../../../../pluginUtils"; -import { resolveMember, resolveUser } from "../../../../utils"; -import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; -import { modActionsMsgCmd } from "../../types"; -import { actualMuteCmd } from "../mute/actualMuteCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { canActOn, hasPermission } from "../../../../pluginUtils.js"; +import { resolveMember, resolveUser } from "../../../../utils.js"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualMuteCmd } from "../mute/actualMuteCmd.js"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts index 05505bab..fabdd2ab 100644 --- a/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forcemute/ForceMuteSlashCmd.ts @@ -1,12 +1,12 @@ import { ChannelType, GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { hasPermission } from "../../../../pluginUtils"; -import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualMuteCmd } from "../mute/actualMuteCmd"; +import { hasPermission } from "../../../../pluginUtils.js"; +import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils.js"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualMuteCmd } from "../mute/actualMuteCmd.js"; const opts = [ slashOptions.string({ name: "time", description: "The duration of the mute", required: false }), diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts index 439bc877..6194a932 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteMsgCmd.ts @@ -1,8 +1,8 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { canActOn, hasPermission } from "../../../../pluginUtils"; -import { resolveMember, resolveUser } from "../../../../utils"; -import { modActionsMsgCmd } from "../../types"; -import { actualUnmuteCmd } from "../unmute/actualUnmuteCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { canActOn, hasPermission } from "../../../../pluginUtils.js"; +import { resolveMember, resolveUser } from "../../../../utils.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualUnmuteCmd } from "../unmute/actualUnmuteCmd.js"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts index 1ddd4962..1fcd135c 100644 --- a/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/forceunmute/ForceUnmuteSlashCmd.ts @@ -1,11 +1,11 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { hasPermission } from "../../../../pluginUtils"; -import { convertDelayStringToMS, resolveMember } from "../../../../utils"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualUnmuteCmd } from "../unmute/actualUnmuteCmd"; +import { hasPermission } from "../../../../pluginUtils.js"; +import { convertDelayStringToMS, resolveMember } from "../../../../utils.js"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualUnmuteCmd } from "../unmute/actualUnmuteCmd.js"; const opts = [ slashOptions.string({ name: "time", description: "The duration of the unmute", required: false }), diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts index 8b427275..ef5c7e7a 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseMsgCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { modActionsMsgCmd } from "../../types"; -import { actualHideCaseCmd } from "./actualHideCaseCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualHideCaseCmd } from "./actualHideCaseCmd.js"; export const HideCaseMsgCmd = modActionsMsgCmd({ trigger: ["hide", "hidecase", "hide_case"], diff --git a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts index 0485c5de..114120dc 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/HideCaseSlashCmd.ts @@ -1,6 +1,6 @@ import { slashOptions } from "knub"; -import { modActionsSlashCmd } from "../../types"; -import { actualHideCaseCmd } from "./actualHideCaseCmd"; +import { modActionsSlashCmd } from "../../types.js"; +import { actualHideCaseCmd } from "./actualHideCaseCmd.js"; export const HideCaseSlashCmd = modActionsSlashCmd({ name: "hidecase", diff --git a/backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts b/backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts index d38e099c..1c33efc1 100644 --- a/backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/hidecase/actualHideCaseCmd.ts @@ -1,6 +1,6 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { ModActionsPluginType } from "../../types"; +import { ModActionsPluginType } from "../../types.js"; export async function actualHideCaseCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts index d895bba4..ebc165ff 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickMsgCmd.ts @@ -1,9 +1,9 @@ import { hasPermission } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { resolveUser } from "../../../../utils"; -import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; -import { modActionsMsgCmd } from "../../types"; -import { actualKickCmd } from "./actualKickCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { resolveUser } from "../../../../utils.js"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualKickCmd } from "./actualKickCmd.js"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts index 4f9bf392..a020fb5e 100644 --- a/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/KickSlashCmd.ts @@ -1,12 +1,12 @@ import { ChannelType, GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { hasPermission } from "../../../../pluginUtils"; -import { UserNotificationMethod, resolveMember } from "../../../../utils"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualKickCmd } from "./actualKickCmd"; +import { hasPermission } from "../../../../pluginUtils.js"; +import { UserNotificationMethod, resolveMember } from "../../../../utils.js"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualKickCmd } from "./actualKickCmd.js"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), diff --git a/backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts b/backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts index 3ee204cc..08bf6c6c 100644 --- a/backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts +++ b/backend/src/plugins/ModActions/commands/kick/actualKickCmd.ts @@ -1,17 +1,17 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../../data/LogType"; -import { canActOn } from "../../../../pluginUtils"; -import { DAYS, SECONDS, UnknownUser, UserNotificationMethod, renderUsername, resolveMember } from "../../../../utils"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { LogType } from "../../../../data/LogType.js"; +import { canActOn } from "../../../../pluginUtils.js"; +import { DAYS, SECONDS, UnknownUser, UserNotificationMethod, renderUsername, resolveMember } from "../../../../utils.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction.js"; import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments, -} from "../../functions/formatReasonForAttachments"; -import { ignoreEvent } from "../../functions/ignoreEvent"; -import { isBanned } from "../../functions/isBanned"; -import { kickMember } from "../../functions/kickMember"; -import { IgnoredEventType, ModActionsPluginType } from "../../types"; +} from "../../functions/formatReasonForAttachments.js"; +import { ignoreEvent } from "../../functions/ignoreEvent.js"; +import { isBanned } from "../../functions/isBanned.js"; +import { kickMember } from "../../functions/kickMember.js"; +import { IgnoredEventType, ModActionsPluginType } from "../../types.js"; export async function actualKickCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts index 3267bf28..ac5fdb4f 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanMsgCmd.ts @@ -1,8 +1,8 @@ import { waitForReply } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { modActionsMsgCmd } from "../../types"; -import { actualMassBanCmd } from "./actualMassBanCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { getContextChannel, sendContextResponse } from "../../../../pluginUtils.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualMassBanCmd } from "./actualMassBanCmd.js"; export const MassBanMsgCmd = modActionsMsgCmd({ trigger: "massban", diff --git a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts index 805a3d63..df89a726 100644 --- a/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/MassBanSlashCmd.ts @@ -1,9 +1,9 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualMassBanCmd } from "./actualMassBanCmd"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualMassBanCmd } from "./actualMassBanCmd.js"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), diff --git a/backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts b/backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts index 27706105..8ced00c4 100644 --- a/backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts +++ b/backend/src/plugins/ModActions/commands/massban/actualMassBanCmd.ts @@ -1,19 +1,19 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../../data/CaseTypes"; -import { LogType } from "../../../../data/LogType"; -import { humanizeDurationShort } from "../../../../humanizeDurationShort"; -import { canActOn, getContextChannel, isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; -import { DAYS, MINUTES, SECONDS, noop } from "../../../../utils"; -import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { CaseTypes } from "../../../../data/CaseTypes.js"; +import { LogType } from "../../../../data/LogType.js"; +import { humanizeDurationShort } from "../../../../humanizeDurationShort.js"; +import { canActOn, getContextChannel, isContextInteraction, sendContextResponse } from "../../../../pluginUtils.js"; +import { DAYS, MINUTES, SECONDS, noop } from "../../../../utils.js"; +import { CasesPlugin } from "../../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../../Logs/LogsPlugin.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction.js"; import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments, -} from "../../functions/formatReasonForAttachments"; -import { ignoreEvent } from "../../functions/ignoreEvent"; -import { IgnoredEventType, ModActionsPluginType } from "../../types"; +} from "../../functions/formatReasonForAttachments.js"; +import { ignoreEvent } from "../../functions/ignoreEvent.js"; +import { IgnoredEventType, ModActionsPluginType } from "../../types.js"; export async function actualMassBanCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts index 0ff53ab1..1c9c37ae 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteMsgCmd.ts @@ -1,8 +1,8 @@ import { waitForReply } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { modActionsMsgCmd } from "../../types"; -import { actualMassMuteCmd } from "./actualMassMuteCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { getContextChannel, sendContextResponse } from "../../../../pluginUtils.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualMassMuteCmd } from "./actualMassMuteCmd.js"; export const MassMuteMsgCmd = modActionsMsgCmd({ trigger: "massmute", diff --git a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts index cb02ceee..eabab03e 100644 --- a/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/MassMuteSlashCmd.ts @@ -1,9 +1,9 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualMassMuteCmd } from "./actualMassMuteCmd"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualMassMuteCmd } from "./actualMassMuteCmd.js"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), diff --git a/backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts b/backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts index e7615044..f0c8053c 100644 --- a/backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/massmute/actualMassMuteCmd.ts @@ -1,16 +1,16 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../../data/LogType"; -import { logger } from "../../../../logger"; -import { canActOn, isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; -import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { LogType } from "../../../../data/LogType.js"; +import { logger } from "../../../../logger.js"; +import { canActOn, isContextInteraction, sendContextResponse } from "../../../../pluginUtils.js"; +import { LogsPlugin } from "../../../Logs/LogsPlugin.js"; +import { MutesPlugin } from "../../../Mutes/MutesPlugin.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction.js"; import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments, -} from "../../functions/formatReasonForAttachments"; -import { ModActionsPluginType } from "../../types"; +} from "../../functions/formatReasonForAttachments.js"; +import { ModActionsPluginType } from "../../types.js"; export async function actualMassMuteCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts index 2d2dd306..6bfa1f18 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanMsgCmd.ts @@ -1,8 +1,8 @@ import { waitForReply } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { getContextChannel, sendContextResponse } from "../../../../pluginUtils"; -import { modActionsMsgCmd } from "../../types"; -import { actualMassUnbanCmd } from "./actualMassUnbanCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { getContextChannel, sendContextResponse } from "../../../../pluginUtils.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualMassUnbanCmd } from "./actualMassUnbanCmd.js"; export const MassUnbanMsgCmd = modActionsMsgCmd({ trigger: "massunban", diff --git a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts index acf6a975..57e69fad 100644 --- a/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/MassUnbanSlashCmd.ts @@ -1,9 +1,9 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualMassUnbanCmd } from "./actualMassUnbanCmd"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualMassUnbanCmd } from "./actualMassUnbanCmd.js"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), diff --git a/backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts b/backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts index e67e7066..ce973a05 100644 --- a/backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/massunban/actualMassUnbanCmd.ts @@ -1,16 +1,16 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../../data/CaseTypes"; -import { LogType } from "../../../../data/LogType"; -import { isContextInteraction, sendContextResponse } from "../../../../pluginUtils"; -import { MINUTES, noop } from "../../../../utils"; -import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; -import { ignoreEvent } from "../../functions/ignoreEvent"; -import { isBanned } from "../../functions/isBanned"; -import { IgnoredEventType, ModActionsPluginType } from "../../types"; +import { CaseTypes } from "../../../../data/CaseTypes.js"; +import { LogType } from "../../../../data/LogType.js"; +import { isContextInteraction, sendContextResponse } from "../../../../pluginUtils.js"; +import { MINUTES, noop } from "../../../../utils.js"; +import { CasesPlugin } from "../../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../../Logs/LogsPlugin.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction.js"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments.js"; +import { ignoreEvent } from "../../functions/ignoreEvent.js"; +import { isBanned } from "../../functions/isBanned.js"; +import { IgnoredEventType, ModActionsPluginType } from "../../types.js"; export async function actualMassUnbanCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts index 0135b3e3..d31efb0c 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteMsgCmd.ts @@ -1,11 +1,11 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { canActOn, hasPermission } from "../../../../pluginUtils"; -import { resolveMember, resolveUser } from "../../../../utils"; -import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { isBanned } from "../../functions/isBanned"; -import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; -import { modActionsMsgCmd } from "../../types"; -import { actualMuteCmd } from "./actualMuteCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { canActOn, hasPermission } from "../../../../pluginUtils.js"; +import { resolveMember, resolveUser } from "../../../../utils.js"; +import { waitForButtonConfirm } from "../../../../utils/waitForInteraction.js"; +import { isBanned } from "../../functions/isBanned.js"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualMuteCmd } from "./actualMuteCmd.js"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts index d791b9d8..a8378f76 100644 --- a/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/MuteSlashCmd.ts @@ -1,14 +1,14 @@ import { ChannelType, GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { canActOn, hasPermission } from "../../../../pluginUtils"; -import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { isBanned } from "../../functions/isBanned"; -import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualMuteCmd } from "./actualMuteCmd"; +import { canActOn, hasPermission } from "../../../../pluginUtils.js"; +import { UserNotificationMethod, convertDelayStringToMS, resolveMember } from "../../../../utils.js"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { waitForButtonConfirm } from "../../../../utils/waitForInteraction.js"; +import { isBanned } from "../../functions/isBanned.js"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualMuteCmd } from "./actualMuteCmd.js"; const opts = [ slashOptions.string({ name: "time", description: "The duration of the mute", required: false }), diff --git a/backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts b/backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts index 0a938d06..2b30ecd9 100644 --- a/backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/mute/actualMuteCmd.ts @@ -1,23 +1,23 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { ERRORS, RecoverablePluginError } from "../../../../RecoverablePluginError"; -import { logger } from "../../../../logger"; +import { ERRORS, RecoverablePluginError } from "../../../../RecoverablePluginError.js"; +import { logger } from "../../../../logger.js"; import { UnknownUser, UserNotificationMethod, asSingleLine, isDiscordAPIError, renderUsername, -} from "../../../../utils"; -import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { MuteResult } from "../../../Mutes/types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +} from "../../../../utils.js"; +import { MutesPlugin } from "../../../Mutes/MutesPlugin.js"; +import { MuteResult } from "../../../Mutes/types.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction.js"; import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments, -} from "../../functions/formatReasonForAttachments"; -import { ModActionsPluginType } from "../../types"; +} from "../../functions/formatReasonForAttachments.js"; +import { ModActionsPluginType } from "../../types.js"; /** * The actual function run by both !mute and !forcemute. diff --git a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts index 4ef15c2e..9049f981 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteMsgCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { resolveUser } from "../../../../utils"; -import { modActionsMsgCmd } from "../../types"; -import { actualNoteCmd } from "./actualNoteCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { resolveUser } from "../../../../utils.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualNoteCmd } from "./actualNoteCmd.js"; export const NoteMsgCmd = modActionsMsgCmd({ trigger: "note", diff --git a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts index e9069cc8..507df72a 100644 --- a/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/NoteSlashCmd.ts @@ -1,8 +1,8 @@ import { slashOptions } from "knub"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualNoteCmd } from "./actualNoteCmd"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualNoteCmd } from "./actualNoteCmd.js"; const opts = [ slashOptions.string({ name: "note", description: "The note to add to the user", required: false }), diff --git a/backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts b/backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts index b34f8821..8914a524 100644 --- a/backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts +++ b/backend/src/plugins/ModActions/commands/note/actualNoteCmd.ts @@ -1,12 +1,12 @@ import { Attachment, ChatInputCommandInteraction, Message, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../../data/CaseTypes"; -import { UnknownUser, renderUsername } from "../../../../utils"; -import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; -import { ModActionsPluginType } from "../../types"; +import { CaseTypes } from "../../../../data/CaseTypes.js"; +import { UnknownUser, renderUsername } from "../../../../utils.js"; +import { CasesPlugin } from "../../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../../Logs/LogsPlugin.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction.js"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments.js"; +import { ModActionsPluginType } from "../../types.js"; export async function actualNoteCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts index 8720fadc..8cf5d499 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanMsgCmd.ts @@ -1,8 +1,8 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { hasPermission } from "../../../../pluginUtils"; -import { resolveUser } from "../../../../utils"; -import { modActionsMsgCmd } from "../../types"; -import { actualUnbanCmd } from "./actualUnbanCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { hasPermission } from "../../../../pluginUtils.js"; +import { resolveUser } from "../../../../utils.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualUnbanCmd } from "./actualUnbanCmd.js"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts index 8c4ef63a..7c910e53 100644 --- a/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/UnbanSlashCmd.ts @@ -1,11 +1,11 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { hasPermission } from "../../../../pluginUtils"; -import { resolveMember } from "../../../../utils"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualUnbanCmd } from "./actualUnbanCmd"; +import { hasPermission } from "../../../../pluginUtils.js"; +import { resolveMember } from "../../../../utils.js"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualUnbanCmd } from "./actualUnbanCmd.js"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), diff --git a/backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts b/backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts index 5baa31ea..e984a944 100644 --- a/backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts +++ b/backend/src/plugins/ModActions/commands/unban/actualUnbanCmd.ts @@ -1,15 +1,15 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message, Snowflake, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../../data/CaseTypes"; -import { LogType } from "../../../../data/LogType"; -import { clearExpiringTempban } from "../../../../data/loops/expiringTempbansLoop"; -import { UnknownUser } from "../../../../utils"; -import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../../Logs/LogsPlugin"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; -import { ignoreEvent } from "../../functions/ignoreEvent"; -import { IgnoredEventType, ModActionsPluginType } from "../../types"; +import { CaseTypes } from "../../../../data/CaseTypes.js"; +import { LogType } from "../../../../data/LogType.js"; +import { clearExpiringTempban } from "../../../../data/loops/expiringTempbansLoop.js"; +import { UnknownUser } from "../../../../utils.js"; +import { CasesPlugin } from "../../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../../Logs/LogsPlugin.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction.js"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments.js"; +import { ignoreEvent } from "../../functions/ignoreEvent.js"; +import { IgnoredEventType, ModActionsPluginType } from "../../types.js"; export async function actualUnbanCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts index fe573ba1..1fddfeef 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseMsgCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { modActionsMsgCmd } from "../../types"; -import { actualHideCaseCmd } from "../hidecase/actualHideCaseCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualHideCaseCmd } from "../hidecase/actualHideCaseCmd.js"; export const UnhideCaseMsgCmd = modActionsMsgCmd({ trigger: ["unhide", "unhidecase", "unhide_case"], diff --git a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts index 3bf4b61c..1b29fac6 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/UnhideCaseSlashCmd.ts @@ -1,6 +1,6 @@ import { slashOptions } from "knub"; -import { modActionsSlashCmd } from "../../types"; -import { actualUnhideCaseCmd } from "./actualUnhideCaseCmd"; +import { modActionsSlashCmd } from "../../types.js"; +import { actualUnhideCaseCmd } from "./actualUnhideCaseCmd.js"; export const UnhideCaseSlashCmd = modActionsSlashCmd({ name: "unhidecase", diff --git a/backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts b/backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts index b1af7433..d270107a 100644 --- a/backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts +++ b/backend/src/plugins/ModActions/commands/unhidecase/actualUnhideCaseCmd.ts @@ -1,6 +1,6 @@ import { ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { ModActionsPluginType } from "../../types"; +import { ModActionsPluginType } from "../../types.js"; export async function actualUnhideCaseCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts index 925a90a6..638ef2f1 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteMsgCmd.ts @@ -1,11 +1,11 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { canActOn, hasPermission } from "../../../../pluginUtils"; -import { resolveMember, resolveUser } from "../../../../utils"; -import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { isBanned } from "../../functions/isBanned"; -import { modActionsMsgCmd } from "../../types"; -import { actualUnmuteCmd } from "./actualUnmuteCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { canActOn, hasPermission } from "../../../../pluginUtils.js"; +import { resolveMember, resolveUser } from "../../../../utils.js"; +import { waitForButtonConfirm } from "../../../../utils/waitForInteraction.js"; +import { MutesPlugin } from "../../../Mutes/MutesPlugin.js"; +import { isBanned } from "../../functions/isBanned.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualUnmuteCmd } from "./actualUnmuteCmd.js"; const opts = { mod: ct.member({ option: true }), diff --git a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts index 5420892c..6d3be623 100644 --- a/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/UnmuteSlashCmd.ts @@ -1,14 +1,14 @@ import { GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { canActOn, hasPermission } from "../../../../pluginUtils"; -import { convertDelayStringToMS, resolveMember } from "../../../../utils"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { isBanned } from "../../functions/isBanned"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualUnmuteCmd } from "./actualUnmuteCmd"; +import { canActOn, hasPermission } from "../../../../pluginUtils.js"; +import { convertDelayStringToMS, resolveMember } from "../../../../utils.js"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { waitForButtonConfirm } from "../../../../utils/waitForInteraction.js"; +import { MutesPlugin } from "../../../Mutes/MutesPlugin.js"; +import { isBanned } from "../../functions/isBanned.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualUnmuteCmd } from "./actualUnmuteCmd.js"; const opts = [ slashOptions.string({ name: "time", description: "The duration of the unmute", required: false }), diff --git a/backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts b/backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts index da34ed43..a6fc768a 100644 --- a/backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts +++ b/backend/src/plugins/ModActions/commands/unmute/actualUnmuteCmd.ts @@ -1,11 +1,11 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message, User } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { UnknownUser, asSingleLine, renderUsername } from "../../../../utils"; -import { MutesPlugin } from "../../../Mutes/MutesPlugin"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments"; -import { ModActionsPluginType } from "../../types"; +import { UnknownUser, asSingleLine, renderUsername } from "../../../../utils.js"; +import { MutesPlugin } from "../../../Mutes/MutesPlugin.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction.js"; +import { formatReasonWithMessageLinkForAttachments } from "../../functions/formatReasonForAttachments.js"; +import { ModActionsPluginType } from "../../types.js"; export async function actualUnmuteCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/commands/update/UpdateMsgCmd.ts b/backend/src/plugins/ModActions/commands/update/UpdateMsgCmd.ts index c0c186a9..9e84b83f 100644 --- a/backend/src/plugins/ModActions/commands/update/UpdateMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/update/UpdateMsgCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { updateCase } from "../../functions/updateCase"; -import { modActionsMsgCmd } from "../../types"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { updateCase } from "../../functions/updateCase.js"; +import { modActionsMsgCmd } from "../../types.js"; export const UpdateMsgCmd = modActionsMsgCmd({ trigger: ["update", "reason"], diff --git a/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts b/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts index 2316f82d..a5a664a8 100644 --- a/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/update/UpdateSlashCmd.ts @@ -1,8 +1,8 @@ import { slashOptions } from "knub"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { updateCase } from "../../functions/updateCase"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_UPDATE } from "../constants"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { updateCase } from "../../functions/updateCase.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_UPDATE } from "../constants.js"; const opts = [ slashOptions.string({ name: "case-number", description: "The number of the case to update", required: false }), diff --git a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts index 99309c22..7e07b2f9 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnMsgCmd.ts @@ -1,10 +1,10 @@ -import { commandTypeHelpers as ct } from "../../../../commandTypes"; -import { canActOn, hasPermission } from "../../../../pluginUtils"; -import { errorMessage, resolveMember, resolveUser } from "../../../../utils"; -import { isBanned } from "../../functions/isBanned"; -import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; -import { modActionsMsgCmd } from "../../types"; -import { actualWarnCmd } from "./actualWarnCmd"; +import { commandTypeHelpers as ct } from "../../../../commandTypes.js"; +import { canActOn, hasPermission } from "../../../../pluginUtils.js"; +import { errorMessage, resolveMember, resolveUser } from "../../../../utils.js"; +import { isBanned } from "../../functions/isBanned.js"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs.js"; +import { modActionsMsgCmd } from "../../types.js"; +import { actualWarnCmd } from "./actualWarnCmd.js"; export const WarnMsgCmd = modActionsMsgCmd({ trigger: "warn", diff --git a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts index af7449f1..f0f8c197 100644 --- a/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/WarnSlashCmd.ts @@ -1,13 +1,13 @@ import { ChannelType, GuildMember } from "discord.js"; import { slashOptions } from "knub"; -import { canActOn, hasPermission } from "../../../../pluginUtils"; -import { UserNotificationMethod, resolveMember } from "../../../../utils"; -import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions"; -import { isBanned } from "../../functions/isBanned"; -import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs"; -import { modActionsSlashCmd } from "../../types"; -import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants"; -import { actualWarnCmd } from "./actualWarnCmd"; +import { canActOn, hasPermission } from "../../../../pluginUtils.js"; +import { UserNotificationMethod, resolveMember } from "../../../../utils.js"; +import { generateAttachmentSlashOptions, retrieveMultipleOptions } from "../../../../utils/multipleSlashOptions.js"; +import { isBanned } from "../../functions/isBanned.js"; +import { readContactMethodsFromArgs } from "../../functions/readContactMethodsFromArgs.js"; +import { modActionsSlashCmd } from "../../types.js"; +import { NUMBER_ATTACHMENTS_CASE_CREATION } from "../constants.js"; +import { actualWarnCmd } from "./actualWarnCmd.js"; const opts = [ slashOptions.string({ name: "reason", description: "The reason", required: false }), diff --git a/backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts b/backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts index b505434a..2decfd28 100644 --- a/backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts +++ b/backend/src/plugins/ModActions/commands/warn/actualWarnCmd.ts @@ -1,16 +1,16 @@ import { Attachment, ChatInputCommandInteraction, GuildMember, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../../data/CaseTypes"; -import { UserNotificationMethod, renderUsername } from "../../../../utils"; -import { waitForButtonConfirm } from "../../../../utils/waitForInteraction"; -import { CasesPlugin } from "../../../Cases/CasesPlugin"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction"; +import { CaseTypes } from "../../../../data/CaseTypes.js"; +import { UserNotificationMethod, renderUsername } from "../../../../utils.js"; +import { waitForButtonConfirm } from "../../../../utils/waitForInteraction.js"; +import { CasesPlugin } from "../../../Cases/CasesPlugin.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "../../functions/attachmentLinkReaction.js"; import { formatReasonWithAttachments, formatReasonWithMessageLinkForAttachments, -} from "../../functions/formatReasonForAttachments"; -import { warnMember } from "../../functions/warnMember"; -import { ModActionsPluginType } from "../../types"; +} from "../../functions/formatReasonForAttachments.js"; +import { warnMember } from "../../functions/warnMember.js"; +import { ModActionsPluginType } from "../../types.js"; export async function actualWarnCmd( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/events/AuditLogEvents.ts b/backend/src/plugins/ModActions/events/AuditLogEvents.ts index a66328b9..fbade396 100644 --- a/backend/src/plugins/ModActions/events/AuditLogEvents.ts +++ b/backend/src/plugins/ModActions/events/AuditLogEvents.ts @@ -1,9 +1,9 @@ import { AuditLogChange, AuditLogEvent } from "discord.js"; import moment from "moment-timezone"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { resolveUser } from "../../../utils"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { modActionsEvt } from "../types"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { resolveUser } from "../../../utils.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { modActionsEvt } from "../types.js"; export const AuditLogEvents = modActionsEvt({ event: "guildAuditLogEntryCreate", diff --git a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts index 237454ba..8e2ffd45 100644 --- a/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateBanCaseOnManualBanEvt.ts @@ -1,14 +1,14 @@ import { AuditLogEvent, User } from "discord.js"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { Case } from "../../../data/entities/Case"; -import { UnknownUser, resolveUser } from "../../../utils"; -import { findMatchingAuditLogEntry } from "../../../utils/findMatchingAuditLogEntry"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; -import { isEventIgnored } from "../functions/isEventIgnored"; -import { IgnoredEventType, modActionsEvt } from "../types"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { Case } from "../../../data/entities/Case.js"; +import { UnknownUser, resolveUser } from "../../../utils.js"; +import { findMatchingAuditLogEntry } from "../../../utils/findMatchingAuditLogEntry.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { clearIgnoredEvents } from "../functions/clearIgnoredEvents.js"; +import { isEventIgnored } from "../functions/isEventIgnored.js"; +import { IgnoredEventType, modActionsEvt } from "../types.js"; /** * Create a BAN case automatically when a user is banned manually. diff --git a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts index 0f840910..2d698426 100644 --- a/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateKickCaseOnManualKickEvt.ts @@ -1,14 +1,14 @@ import { AuditLogEvent, User } from "discord.js"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { Case } from "../../../data/entities/Case"; -import { logger } from "../../../logger"; -import { UnknownUser, resolveUser } from "../../../utils"; -import { findMatchingAuditLogEntry } from "../../../utils/findMatchingAuditLogEntry"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; -import { isEventIgnored } from "../functions/isEventIgnored"; -import { IgnoredEventType, modActionsEvt } from "../types"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { Case } from "../../../data/entities/Case.js"; +import { logger } from "../../../logger.js"; +import { UnknownUser, resolveUser } from "../../../utils.js"; +import { findMatchingAuditLogEntry } from "../../../utils/findMatchingAuditLogEntry.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { clearIgnoredEvents } from "../functions/clearIgnoredEvents.js"; +import { isEventIgnored } from "../functions/isEventIgnored.js"; +import { IgnoredEventType, modActionsEvt } from "../types.js"; /** * Create a KICK case automatically when a user is kicked manually. diff --git a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts index 9400c732..2ccf0398 100644 --- a/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts +++ b/backend/src/plugins/ModActions/events/CreateUnbanCaseOnManualUnbanEvt.ts @@ -1,13 +1,13 @@ import { AuditLogEvent, User } from "discord.js"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { Case } from "../../../data/entities/Case"; -import { UnknownUser, resolveUser } from "../../../utils"; -import { findMatchingAuditLogEntry } from "../../../utils/findMatchingAuditLogEntry"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { clearIgnoredEvents } from "../functions/clearIgnoredEvents"; -import { isEventIgnored } from "../functions/isEventIgnored"; -import { IgnoredEventType, modActionsEvt } from "../types"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { Case } from "../../../data/entities/Case.js"; +import { UnknownUser, resolveUser } from "../../../utils.js"; +import { findMatchingAuditLogEntry } from "../../../utils/findMatchingAuditLogEntry.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { clearIgnoredEvents } from "../functions/clearIgnoredEvents.js"; +import { isEventIgnored } from "../functions/isEventIgnored.js"; +import { IgnoredEventType, modActionsEvt } from "../types.js"; /** * Create an UNBAN case automatically when a user is unbanned manually. diff --git a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts index 82e39547..37be3a3e 100644 --- a/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts +++ b/backend/src/plugins/ModActions/events/PostAlertOnMemberJoinEvt.ts @@ -1,8 +1,8 @@ import { PermissionsBitField, Snowflake, TextChannel } from "discord.js"; -import { renderUsername, resolveMember } from "../../../utils"; -import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { modActionsEvt } from "../types"; +import { renderUsername, resolveMember } from "../../../utils.js"; +import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { modActionsEvt } from "../types.js"; /** * Show an alert if a member with prior notes joins the server diff --git a/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts b/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts index b10e063e..97d5c8a5 100644 --- a/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts +++ b/backend/src/plugins/ModActions/functions/attachmentLinkReaction.ts @@ -1,6 +1,6 @@ import { ChatInputCommandInteraction, Message, TextBasedChannel } from "discord.js"; import { AnyPluginData, GuildPluginData } from "knub"; -import { ModActionsPluginType } from "../types"; +import { ModActionsPluginType } from "../types.js"; export function shouldReactToAttachmentLink(pluginData: GuildPluginData) { const config = pluginData.config.get(); diff --git a/backend/src/plugins/ModActions/functions/banUserId.ts b/backend/src/plugins/ModActions/functions/banUserId.ts index 729b579d..d432de23 100644 --- a/backend/src/plugins/ModActions/functions/banUserId.ts +++ b/backend/src/plugins/ModActions/functions/banUserId.ts @@ -1,11 +1,11 @@ import { DiscordAPIError, Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; -import { registerExpiringTempban } from "../../../data/loops/expiringTempbansLoop"; -import { logger } from "../../../logger"; -import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { LogType } from "../../../data/LogType.js"; +import { registerExpiringTempban } from "../../../data/loops/expiringTempbansLoop.js"; +import { logger } from "../../../logger.js"; +import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter.js"; import { DAYS, SECONDS, @@ -15,13 +15,13 @@ import { resolveMember, resolveUser, ucfirst, -} from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { BanOptions, BanResult, IgnoredEventType, ModActionsPluginType } from "../types"; -import { getDefaultContactMethods } from "./getDefaultContactMethods"; -import { ignoreEvent } from "./ignoreEvent"; +} from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { BanOptions, BanResult, IgnoredEventType, ModActionsPluginType } from "../types.js"; +import { getDefaultContactMethods } from "./getDefaultContactMethods.js"; +import { ignoreEvent } from "./ignoreEvent.js"; /** * Ban the specified user id, whether or not they're actually on the server at the time. Generates a case. diff --git a/backend/src/plugins/ModActions/functions/clearIgnoredEvents.ts b/backend/src/plugins/ModActions/functions/clearIgnoredEvents.ts index c16dabcf..561d2cc1 100644 --- a/backend/src/plugins/ModActions/functions/clearIgnoredEvents.ts +++ b/backend/src/plugins/ModActions/functions/clearIgnoredEvents.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { IgnoredEventType, ModActionsPluginType } from "../types"; +import { IgnoredEventType, ModActionsPluginType } from "../types.js"; export function clearIgnoredEvents( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/clearTempban.ts b/backend/src/plugins/ModActions/functions/clearTempban.ts index cb3ccddb..b2f80d83 100644 --- a/backend/src/plugins/ModActions/functions/clearTempban.ts +++ b/backend/src/plugins/ModActions/functions/clearTempban.ts @@ -2,16 +2,16 @@ import { Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; -import { Tempban } from "../../../data/entities/Tempban"; -import { logger } from "../../../logger"; -import { resolveUser } from "../../../utils"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { IgnoredEventType, ModActionsPluginType } from "../types"; -import { ignoreEvent } from "./ignoreEvent"; -import { isBanned } from "./isBanned"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { LogType } from "../../../data/LogType.js"; +import { Tempban } from "../../../data/entities/Tempban.js"; +import { logger } from "../../../logger.js"; +import { resolveUser } from "../../../utils.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { IgnoredEventType, ModActionsPluginType } from "../types.js"; +import { ignoreEvent } from "./ignoreEvent.js"; +import { isBanned } from "./isBanned.js"; export async function clearTempban(pluginData: GuildPluginData, tempban: Tempban) { if (!(await isBanned(pluginData, tempban.user_id))) { diff --git a/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts b/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts index 8932aa26..98b43ca3 100644 --- a/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts +++ b/backend/src/plugins/ModActions/functions/formatReasonForAttachments.ts @@ -1,7 +1,7 @@ import { Attachment, ChatInputCommandInteraction, Message } from "discord.js"; import { GuildPluginData } from "knub"; -import { isContextMessage } from "../../../pluginUtils"; -import { ModActionsPluginType } from "../types"; +import { isContextMessage } from "../../../pluginUtils.js"; +import { ModActionsPluginType } from "../types.js"; export async function formatReasonWithMessageLinkForAttachments( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts b/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts index a94a848a..438dba23 100644 --- a/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts +++ b/backend/src/plugins/ModActions/functions/getDefaultContactMethods.ts @@ -1,7 +1,7 @@ import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { UserNotificationMethod } from "../../../utils"; -import { ModActionsPluginType } from "../types"; +import { UserNotificationMethod } from "../../../utils.js"; +import { ModActionsPluginType } from "../types.js"; export function getDefaultContactMethods( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/hasModActionPerm.ts b/backend/src/plugins/ModActions/functions/hasModActionPerm.ts index 6e28768d..501e927d 100644 --- a/backend/src/plugins/ModActions/functions/hasModActionPerm.ts +++ b/backend/src/plugins/ModActions/functions/hasModActionPerm.ts @@ -1,6 +1,6 @@ import { GuildMember, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { ModActionsPluginType } from "../types"; +import { ModActionsPluginType } from "../types.js"; export async function hasNotePermission( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/ignoreEvent.ts b/backend/src/plugins/ModActions/functions/ignoreEvent.ts index 71c25362..c3392eba 100644 --- a/backend/src/plugins/ModActions/functions/ignoreEvent.ts +++ b/backend/src/plugins/ModActions/functions/ignoreEvent.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { SECONDS } from "../../../utils"; -import { IgnoredEventType, ModActionsPluginType } from "../types"; -import { clearIgnoredEvents } from "./clearIgnoredEvents"; +import { SECONDS } from "../../../utils.js"; +import { IgnoredEventType, ModActionsPluginType } from "../types.js"; +import { clearIgnoredEvents } from "./clearIgnoredEvents.js"; const DEFAULT_TIMEOUT = 15 * SECONDS; diff --git a/backend/src/plugins/ModActions/functions/isBanned.ts b/backend/src/plugins/ModActions/functions/isBanned.ts index 50dc4823..5623b959 100644 --- a/backend/src/plugins/ModActions/functions/isBanned.ts +++ b/backend/src/plugins/ModActions/functions/isBanned.ts @@ -1,9 +1,9 @@ import { PermissionsBitField, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { SECONDS, isDiscordAPIError, isDiscordHTTPError, sleep } from "../../../utils"; -import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { ModActionsPluginType } from "../types"; +import { SECONDS, isDiscordAPIError, isDiscordHTTPError, sleep } from "../../../utils.js"; +import { hasDiscordPermissions } from "../../../utils/hasDiscordPermissions.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { ModActionsPluginType } from "../types.js"; export async function isBanned( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/isEventIgnored.ts b/backend/src/plugins/ModActions/functions/isEventIgnored.ts index 8ec27baf..a49c5f11 100644 --- a/backend/src/plugins/ModActions/functions/isEventIgnored.ts +++ b/backend/src/plugins/ModActions/functions/isEventIgnored.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { IgnoredEventType, ModActionsPluginType } from "../types"; +import { IgnoredEventType, ModActionsPluginType } from "../types.js"; export function isEventIgnored( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/kickMember.ts b/backend/src/plugins/ModActions/functions/kickMember.ts index 2a9160b8..c1f2f7d2 100644 --- a/backend/src/plugins/ModActions/functions/kickMember.ts +++ b/backend/src/plugins/ModActions/functions/kickMember.ts @@ -1,15 +1,15 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; -import { renderTemplate, TemplateParseError, TemplateSafeValueContainer } from "../../../templateFormatter"; -import { createUserNotificationError, notifyUser, resolveUser, ucfirst, UserNotificationResult } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { IgnoredEventType, KickOptions, KickResult, ModActionsPluginType } from "../types"; -import { getDefaultContactMethods } from "./getDefaultContactMethods"; -import { ignoreEvent } from "./ignoreEvent"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { LogType } from "../../../data/LogType.js"; +import { renderTemplate, TemplateParseError, TemplateSafeValueContainer } from "../../../templateFormatter.js"; +import { createUserNotificationError, notifyUser, resolveUser, ucfirst, UserNotificationResult } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { IgnoredEventType, KickOptions, KickResult, ModActionsPluginType } from "../types.js"; +import { getDefaultContactMethods } from "./getDefaultContactMethods.js"; +import { ignoreEvent } from "./ignoreEvent.js"; /** * Kick the specified server member. Generates a case. diff --git a/backend/src/plugins/ModActions/functions/offModActionsEvent.ts b/backend/src/plugins/ModActions/functions/offModActionsEvent.ts index 798fa733..845e965f 100644 --- a/backend/src/plugins/ModActions/functions/offModActionsEvent.ts +++ b/backend/src/plugins/ModActions/functions/offModActionsEvent.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { ModActionsEvents, ModActionsPluginType } from "../types"; +import { ModActionsEvents, ModActionsPluginType } from "../types.js"; export function offModActionsEvent( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/onModActionsEvent.ts b/backend/src/plugins/ModActions/functions/onModActionsEvent.ts index e1219bad..7bd5c548 100644 --- a/backend/src/plugins/ModActions/functions/onModActionsEvent.ts +++ b/backend/src/plugins/ModActions/functions/onModActionsEvent.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { ModActionsEvents, ModActionsPluginType } from "../types"; +import { ModActionsEvents, ModActionsPluginType } from "../types.js"; export function onModActionsEvent( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts b/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts index 5ddc222b..47f207f5 100644 --- a/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts +++ b/backend/src/plugins/ModActions/functions/readContactMethodsFromArgs.ts @@ -1,5 +1,5 @@ import { GuildTextBasedChannel } from "discord.js"; -import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils"; +import { disableUserNotificationStrings, UserNotificationMethod } from "../../../utils.js"; export function readContactMethodsFromArgs(args: { notify?: string | null; diff --git a/backend/src/plugins/ModActions/functions/updateCase.ts b/backend/src/plugins/ModActions/functions/updateCase.ts index 8cfffa98..6d78ce8b 100644 --- a/backend/src/plugins/ModActions/functions/updateCase.ts +++ b/backend/src/plugins/ModActions/functions/updateCase.ts @@ -1,12 +1,12 @@ import { Attachment, ChatInputCommandInteraction, Message, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { Case } from "../../../data/entities/Case"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { ModActionsPluginType } from "../types"; -import { handleAttachmentLinkDetectionAndGetRestriction } from "./attachmentLinkReaction"; -import { formatReasonWithMessageLinkForAttachments } from "./formatReasonForAttachments"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { Case } from "../../../data/entities/Case.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { ModActionsPluginType } from "../types.js"; +import { handleAttachmentLinkDetectionAndGetRestriction } from "./attachmentLinkReaction.js"; +import { formatReasonWithMessageLinkForAttachments } from "./formatReasonForAttachments.js"; export async function updateCase( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/functions/warnMember.ts b/backend/src/plugins/ModActions/functions/warnMember.ts index 8ba8ee38..9e077234 100644 --- a/backend/src/plugins/ModActions/functions/warnMember.ts +++ b/backend/src/plugins/ModActions/functions/warnMember.ts @@ -1,14 +1,14 @@ import { GuildMember, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; -import { UserNotificationResult, createUserNotificationError, notifyUser, resolveUser, ucfirst } from "../../../utils"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { waitForButtonConfirm } from "../../../utils/waitForInteraction"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { ModActionsPluginType, WarnOptions, WarnResult } from "../types"; -import { getDefaultContactMethods } from "./getDefaultContactMethods"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter.js"; +import { UserNotificationResult, createUserNotificationError, notifyUser, resolveUser, ucfirst } from "../../../utils.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { waitForButtonConfirm } from "../../../utils/waitForInteraction.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { ModActionsPluginType, WarnOptions, WarnResult } from "../types.js"; +import { getDefaultContactMethods } from "./getDefaultContactMethods.js"; export async function warnMember( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ModActions/info.ts b/backend/src/plugins/ModActions/info.ts index 96e20de6..736de0ce 100644 --- a/backend/src/plugins/ModActions/info.ts +++ b/backend/src/plugins/ModActions/info.ts @@ -1,6 +1,6 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; -import { zModActionsConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; +import { zModActionsConfig } from "./types.js"; export const modActionsPluginInfo: ZeppelinPluginInfo = { prettyName: "Mod actions", diff --git a/backend/src/plugins/ModActions/types.ts b/backend/src/plugins/ModActions/types.ts index 14388ea9..c7dcc6e9 100644 --- a/backend/src/plugins/ModActions/types.ts +++ b/backend/src/plugins/ModActions/types.ts @@ -9,15 +9,15 @@ import { pluginUtils, } from "knub"; import z from "zod"; -import { Queue } from "../../Queue"; -import { GuildCases } from "../../data/GuildCases"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildMutes } from "../../data/GuildMutes"; -import { GuildTempbans } from "../../data/GuildTempbans"; -import { Case } from "../../data/entities/Case"; -import { UserNotificationMethod, UserNotificationResult } from "../../utils"; -import { CaseArgs } from "../Cases/types"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { Queue } from "../../Queue.js"; +import { GuildCases } from "../../data/GuildCases.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildMutes } from "../../data/GuildMutes.js"; +import { GuildTempbans } from "../../data/GuildTempbans.js"; +import { Case } from "../../data/entities/Case.js"; +import { UserNotificationMethod, UserNotificationResult } from "../../utils.js"; +import { CaseArgs } from "../Cases/types.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export type AttachmentLinkReactionType = "none" | "warn" | "restrict" | null; diff --git a/backend/src/plugins/Mutes/MutesPlugin.ts b/backend/src/plugins/Mutes/MutesPlugin.ts index eeae16df..9eccb855 100644 --- a/backend/src/plugins/Mutes/MutesPlugin.ts +++ b/backend/src/plugins/Mutes/MutesPlugin.ts @@ -1,30 +1,30 @@ import { GuildMember, Snowflake } from "discord.js"; import { EventEmitter } from "events"; import { guildPlugin } from "knub"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildCases } from "../../data/GuildCases"; -import { onGuildEvent } from "../../data/GuildEvents"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildMutes } from "../../data/GuildMutes"; -import { makePublicFn } from "../../pluginUtils"; -import { CasesPlugin } from "../Cases/CasesPlugin"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildCases } from "../../data/GuildCases.js"; +import { onGuildEvent } from "../../data/GuildEvents.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildMutes } from "../../data/GuildMutes.js"; +import { makePublicFn } from "../../pluginUtils.js"; +import { CasesPlugin } from "../Cases/CasesPlugin.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin.js"; -import { ClearBannedMutesCmd } from "./commands/ClearBannedMutesCmd"; -import { ClearMutesCmd } from "./commands/ClearMutesCmd"; -import { ClearMutesWithoutRoleCmd } from "./commands/ClearMutesWithoutRoleCmd"; -import { MutesCmd } from "./commands/MutesCmd"; -import { ClearActiveMuteOnMemberBanEvt } from "./events/ClearActiveMuteOnMemberBanEvt"; -import { ReapplyActiveMuteOnJoinEvt } from "./events/ReapplyActiveMuteOnJoinEvt"; -import { RegisterManualTimeoutsEvt } from "./events/RegisterManualTimeoutsEvt"; -import { clearMute } from "./functions/clearMute"; -import { muteUser } from "./functions/muteUser"; -import { offMutesEvent } from "./functions/offMutesEvent"; -import { onMutesEvent } from "./functions/onMutesEvent"; -import { renewTimeoutMute } from "./functions/renewTimeoutMute"; -import { unmuteUser } from "./functions/unmuteUser"; -import { MutesPluginType, zMutesConfig } from "./types"; +import { ClearBannedMutesCmd } from "./commands/ClearBannedMutesCmd.js"; +import { ClearMutesCmd } from "./commands/ClearMutesCmd.js"; +import { ClearMutesWithoutRoleCmd } from "./commands/ClearMutesWithoutRoleCmd.js"; +import { MutesCmd } from "./commands/MutesCmd.js"; +import { ClearActiveMuteOnMemberBanEvt } from "./events/ClearActiveMuteOnMemberBanEvt.js"; +import { ReapplyActiveMuteOnJoinEvt } from "./events/ReapplyActiveMuteOnJoinEvt.js"; +import { RegisterManualTimeoutsEvt } from "./events/RegisterManualTimeoutsEvt.js"; +import { clearMute } from "./functions/clearMute.js"; +import { muteUser } from "./functions/muteUser.js"; +import { offMutesEvent } from "./functions/offMutesEvent.js"; +import { onMutesEvent } from "./functions/onMutesEvent.js"; +import { renewTimeoutMute } from "./functions/renewTimeoutMute.js"; +import { unmuteUser } from "./functions/unmuteUser.js"; +import { MutesPluginType, zMutesConfig } from "./types.js"; const defaultOptions = { config: { diff --git a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts index 43d2c58a..80a9a49e 100644 --- a/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearBannedMutesCmd.ts @@ -1,5 +1,5 @@ import { Snowflake } from "discord.js"; -import { mutesCmd } from "../types"; +import { mutesCmd } from "../types.js"; export const ClearBannedMutesCmd = mutesCmd({ trigger: "clear_banned_mutes", diff --git a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts index 43062754..773ac06d 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesCmd.ts @@ -1,5 +1,5 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { mutesCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { mutesCmd } from "../types.js"; export const ClearMutesCmd = mutesCmd({ trigger: "clear_mutes", diff --git a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts index b73d3b41..c225d407 100644 --- a/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts +++ b/backend/src/plugins/Mutes/commands/ClearMutesWithoutRoleCmd.ts @@ -1,6 +1,6 @@ import { Snowflake } from "discord.js"; -import { resolveMember } from "../../../utils"; -import { mutesCmd } from "../types"; +import { resolveMember } from "../../../utils.js"; +import { mutesCmd } from "../types.js"; export const ClearMutesWithoutRoleCmd = mutesCmd({ trigger: "clear_mutes_without_role", diff --git a/backend/src/plugins/Mutes/commands/MutesCmd.ts b/backend/src/plugins/Mutes/commands/MutesCmd.ts index 5000218c..d599edd4 100644 --- a/backend/src/plugins/Mutes/commands/MutesCmd.ts +++ b/backend/src/plugins/Mutes/commands/MutesCmd.ts @@ -7,11 +7,11 @@ import { Snowflake, } from "discord.js"; import moment from "moment-timezone"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { humanizeDurationShort } from "../../../humanizeDurationShort"; -import { getBaseUrl } from "../../../pluginUtils"; -import { DBDateFormat, MINUTES, renderUsername, resolveMember } from "../../../utils"; -import { IMuteWithDetails, mutesCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { humanizeDurationShort } from "../../../humanizeDurationShort.js"; +import { getBaseUrl } from "../../../pluginUtils.js"; +import { DBDateFormat, MINUTES, renderUsername, resolveMember } from "../../../utils.js"; +import { IMuteWithDetails, mutesCmd } from "../types.js"; export const MutesCmd = mutesCmd({ trigger: "mutes", diff --git a/backend/src/plugins/Mutes/events/ClearActiveMuteOnMemberBanEvt.ts b/backend/src/plugins/Mutes/events/ClearActiveMuteOnMemberBanEvt.ts index 94604dcd..dab16d25 100644 --- a/backend/src/plugins/Mutes/events/ClearActiveMuteOnMemberBanEvt.ts +++ b/backend/src/plugins/Mutes/events/ClearActiveMuteOnMemberBanEvt.ts @@ -1,4 +1,4 @@ -import { mutesEvt } from "../types"; +import { mutesEvt } from "../types.js"; /** * Clear active mute from the member if the member is banned diff --git a/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts b/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts index da6e24e5..0f9b5204 100644 --- a/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts +++ b/backend/src/plugins/Mutes/events/ClearActiveMuteOnRoleRemovalEvt.ts @@ -1,5 +1,5 @@ -import { memberHasMutedRole } from "../functions/memberHasMutedRole"; -import { mutesEvt } from "../types"; +import { memberHasMutedRole } from "../functions/memberHasMutedRole.js"; +import { mutesEvt } from "../types.js"; /** * Clear active mute if the mute role is removed manually diff --git a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts index 6db4f27c..914eb713 100644 --- a/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts +++ b/backend/src/plugins/Mutes/events/ReapplyActiveMuteOnJoinEvt.ts @@ -1,10 +1,10 @@ import moment from "moment-timezone"; -import { MuteTypes } from "../../../data/MuteTypes"; +import { MuteTypes } from "../../../data/MuteTypes.js"; import { noop } from "../../../utils.js"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; -import { getTimeoutExpiryTime } from "../functions/getTimeoutExpiryTime"; -import { mutesEvt } from "../types"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin.js"; +import { getTimeoutExpiryTime } from "../functions/getTimeoutExpiryTime.js"; +import { mutesEvt } from "../types.js"; /** * Reapply active mutes on join diff --git a/backend/src/plugins/Mutes/events/RegisterManualTimeoutsEvt.ts b/backend/src/plugins/Mutes/events/RegisterManualTimeoutsEvt.ts index 52c5a7cf..f627d479 100644 --- a/backend/src/plugins/Mutes/events/RegisterManualTimeoutsEvt.ts +++ b/backend/src/plugins/Mutes/events/RegisterManualTimeoutsEvt.ts @@ -1,8 +1,8 @@ import { AuditLogChange, AuditLogEvent } from "discord.js"; import moment from "moment-timezone"; -import { MuteTypes } from "../../../data/MuteTypes"; -import { resolveUser } from "../../../utils"; -import { mutesEvt } from "../types"; +import { MuteTypes } from "../../../data/MuteTypes.js"; +import { resolveUser } from "../../../utils.js"; +import { mutesEvt } from "../types.js"; export const RegisterManualTimeoutsEvt = mutesEvt({ event: "guildAuditLogEntryCreate", diff --git a/backend/src/plugins/Mutes/functions/clearMute.ts b/backend/src/plugins/Mutes/functions/clearMute.ts index f96068c7..712788b8 100644 --- a/backend/src/plugins/Mutes/functions/clearMute.ts +++ b/backend/src/plugins/Mutes/functions/clearMute.ts @@ -1,13 +1,13 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { MuteTypes } from "../../../data/MuteTypes"; -import { Mute } from "../../../data/entities/Mute"; -import { clearExpiringMute } from "../../../data/loops/expiringMutesLoop"; -import { resolveMember, verboseUserMention } from "../../../utils"; -import { memberRolesLock } from "../../../utils/lockNameHelpers"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; -import { MutesPluginType } from "../types"; +import { MuteTypes } from "../../../data/MuteTypes.js"; +import { Mute } from "../../../data/entities/Mute.js"; +import { clearExpiringMute } from "../../../data/loops/expiringMutesLoop.js"; +import { resolveMember, verboseUserMention } from "../../../utils.js"; +import { memberRolesLock } from "../../../utils/lockNameHelpers.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin.js"; +import { MutesPluginType } from "../types.js"; export async function clearMute( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Mutes/functions/getDefaultMuteType.ts b/backend/src/plugins/Mutes/functions/getDefaultMuteType.ts index b58333fd..3e72b37f 100644 --- a/backend/src/plugins/Mutes/functions/getDefaultMuteType.ts +++ b/backend/src/plugins/Mutes/functions/getDefaultMuteType.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { MuteTypes } from "../../../data/MuteTypes"; -import { MutesPluginType } from "../types"; +import { MuteTypes } from "../../../data/MuteTypes.js"; +import { MutesPluginType } from "../types.js"; export function getDefaultMuteType(pluginData: GuildPluginData): MuteTypes { const muteRole = pluginData.config.get().mute_role; diff --git a/backend/src/plugins/Mutes/functions/getTimeoutExpiryTime.ts b/backend/src/plugins/Mutes/functions/getTimeoutExpiryTime.ts index 28f760b9..8cad67a5 100644 --- a/backend/src/plugins/Mutes/functions/getTimeoutExpiryTime.ts +++ b/backend/src/plugins/Mutes/functions/getTimeoutExpiryTime.ts @@ -1,4 +1,4 @@ -import { MAX_TIMEOUT_DURATION } from "../../../data/Mutes"; +import { MAX_TIMEOUT_DURATION } from "../../../data/Mutes.js"; /** * Since timeouts have a limited duration (max 28d) but we support mutes longer than that, diff --git a/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts b/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts index 2790285a..d6f23cef 100644 --- a/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts +++ b/backend/src/plugins/Mutes/functions/memberHasMutedRole.ts @@ -1,6 +1,6 @@ import { GuildMember, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { MutesPluginType } from "../types"; +import { MutesPluginType } from "../types.js"; export function memberHasMutedRole(pluginData: GuildPluginData, member: GuildMember): boolean { const muteRole = pluginData.config.get().mute_role; diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index c61766c1..bb2b60ef 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -1,15 +1,15 @@ import { Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { AddMuteParams } from "../../../data/GuildMutes"; -import { MuteTypes } from "../../../data/MuteTypes"; -import { Case } from "../../../data/entities/Case"; -import { Mute } from "../../../data/entities/Mute"; -import { registerExpiringMute } from "../../../data/loops/expiringMutesLoop"; -import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin"; -import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError.js"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { AddMuteParams } from "../../../data/GuildMutes.js"; +import { MuteTypes } from "../../../data/MuteTypes.js"; +import { Case } from "../../../data/entities/Case.js"; +import { Mute } from "../../../data/entities/Mute.js"; +import { registerExpiringMute } from "../../../data/loops/expiringMutesLoop.js"; +import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin.js"; +import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter.js"; import { UserNotificationMethod, UserNotificationResult, @@ -18,14 +18,14 @@ import { resolveMember, resolveUser, ucfirst, -} from "../../../utils"; -import { muteLock } from "../../../utils/lockNameHelpers"; -import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; -import { MuteOptions, MutesPluginType } from "../types"; -import { getDefaultMuteType } from "./getDefaultMuteType"; -import { getTimeoutExpiryTime } from "./getTimeoutExpiryTime"; +} from "../../../utils.js"; +import { muteLock } from "../../../utils/lockNameHelpers.js"; +import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin.js"; +import { MuteOptions, MutesPluginType } from "../types.js"; +import { getDefaultMuteType } from "./getDefaultMuteType.js"; +import { getTimeoutExpiryTime } from "./getTimeoutExpiryTime.js"; /** * TODO: Clean up this function diff --git a/backend/src/plugins/Mutes/functions/offMutesEvent.ts b/backend/src/plugins/Mutes/functions/offMutesEvent.ts index e48f0d46..232f1a65 100644 --- a/backend/src/plugins/Mutes/functions/offMutesEvent.ts +++ b/backend/src/plugins/Mutes/functions/offMutesEvent.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { MutesEvents, MutesPluginType } from "../types"; +import { MutesEvents, MutesPluginType } from "../types.js"; export function offMutesEvent( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Mutes/functions/onMutesEvent.ts b/backend/src/plugins/Mutes/functions/onMutesEvent.ts index 71f13ba4..8c41f194 100644 --- a/backend/src/plugins/Mutes/functions/onMutesEvent.ts +++ b/backend/src/plugins/Mutes/functions/onMutesEvent.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { MutesEvents, MutesPluginType } from "../types"; +import { MutesEvents, MutesPluginType } from "../types.js"; export function onMutesEvent( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Mutes/functions/renewTimeoutMute.ts b/backend/src/plugins/Mutes/functions/renewTimeoutMute.ts index 8363cf9f..fa585513 100644 --- a/backend/src/plugins/Mutes/functions/renewTimeoutMute.ts +++ b/backend/src/plugins/Mutes/functions/renewTimeoutMute.ts @@ -1,11 +1,11 @@ import { PermissionFlagsBits } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { MAX_TIMEOUT_DURATION } from "../../../data/Mutes"; -import { Mute } from "../../../data/entities/Mute"; -import { DBDateFormat, noop, resolveMember } from "../../../utils"; +import { MAX_TIMEOUT_DURATION } from "../../../data/Mutes.js"; +import { Mute } from "../../../data/entities/Mute.js"; +import { DBDateFormat, noop, resolveMember } from "../../../utils.js"; import { LogsPlugin } from "../../Logs/LogsPlugin.js"; -import { MutesPluginType } from "../types"; +import { MutesPluginType } from "../types.js"; export async function renewTimeoutMute(pluginData: GuildPluginData, mute: Mute) { const me = diff --git a/backend/src/plugins/Mutes/functions/unmuteUser.ts b/backend/src/plugins/Mutes/functions/unmuteUser.ts index 4c81a52d..a5624f0a 100644 --- a/backend/src/plugins/Mutes/functions/unmuteUser.ts +++ b/backend/src/plugins/Mutes/functions/unmuteUser.ts @@ -1,19 +1,19 @@ import { Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { AddMuteParams } from "../../../data/GuildMutes"; -import { MuteTypes } from "../../../data/MuteTypes"; -import { Mute } from "../../../data/entities/Mute"; -import { noop, resolveMember, resolveUser } from "../../../utils"; -import { CasesPlugin } from "../../Cases/CasesPlugin"; -import { CaseArgs } from "../../Cases/types"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { MutesPluginType, UnmuteResult } from "../types"; -import { clearMute } from "./clearMute"; -import { getDefaultMuteType } from "./getDefaultMuteType"; -import { getTimeoutExpiryTime } from "./getTimeoutExpiryTime"; -import { memberHasMutedRole } from "./memberHasMutedRole"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { AddMuteParams } from "../../../data/GuildMutes.js"; +import { MuteTypes } from "../../../data/MuteTypes.js"; +import { Mute } from "../../../data/entities/Mute.js"; +import { noop, resolveMember, resolveUser } from "../../../utils.js"; +import { CasesPlugin } from "../../Cases/CasesPlugin.js"; +import { CaseArgs } from "../../Cases/types.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { MutesPluginType, UnmuteResult } from "../types.js"; +import { clearMute } from "./clearMute.js"; +import { getDefaultMuteType } from "./getDefaultMuteType.js"; +import { getTimeoutExpiryTime } from "./getTimeoutExpiryTime.js"; +import { memberHasMutedRole } from "./memberHasMutedRole.js"; export async function unmuteUser( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Mutes/info.ts b/backend/src/plugins/Mutes/info.ts index 0918e233..6654afed 100644 --- a/backend/src/plugins/Mutes/info.ts +++ b/backend/src/plugins/Mutes/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { zMutesConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { zMutesConfig } from "./types.js"; export const mutesPluginInfo: ZeppelinPluginInfo = { prettyName: "Mutes", diff --git a/backend/src/plugins/Mutes/types.ts b/backend/src/plugins/Mutes/types.ts index 59790782..4a4c01de 100644 --- a/backend/src/plugins/Mutes/types.ts +++ b/backend/src/plugins/Mutes/types.ts @@ -2,15 +2,15 @@ import { GuildMember } from "discord.js"; import { EventEmitter } from "events"; import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildCases } from "../../data/GuildCases"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildMutes } from "../../data/GuildMutes"; -import { Case } from "../../data/entities/Case"; -import { Mute } from "../../data/entities/Mute"; -import { UserNotificationMethod, UserNotificationResult, zSnowflake } from "../../utils"; -import { CaseArgs } from "../Cases/types"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildCases } from "../../data/GuildCases.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildMutes } from "../../data/GuildMutes.js"; +import { Case } from "../../data/entities/Case.js"; +import { Mute } from "../../data/entities/Mute.js"; +import { UserNotificationMethod, UserNotificationResult, zSnowflake } from "../../utils.js"; +import { CaseArgs } from "../Cases/types.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zMutesConfig = z.strictObject({ mute_role: zSnowflake.nullable(), diff --git a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts index 617ce019..1cb28123 100644 --- a/backend/src/plugins/NameHistory/NameHistoryPlugin.ts +++ b/backend/src/plugins/NameHistory/NameHistoryPlugin.ts @@ -1,10 +1,10 @@ import { PluginOptions, guildPlugin } from "knub"; -import { Queue } from "../../Queue"; -import { GuildNicknameHistory } from "../../data/GuildNicknameHistory"; -import { UsernameHistory } from "../../data/UsernameHistory"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { NamesCmd } from "./commands/NamesCmd"; -import { NameHistoryPluginType, zNameHistoryConfig } from "./types"; +import { Queue } from "../../Queue.js"; +import { GuildNicknameHistory } from "../../data/GuildNicknameHistory.js"; +import { UsernameHistory } from "../../data/UsernameHistory.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { NamesCmd } from "./commands/NamesCmd.js"; +import { NameHistoryPluginType, zNameHistoryConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/NameHistory/commands/NamesCmd.ts b/backend/src/plugins/NameHistory/commands/NamesCmd.ts index 3fadaadd..f7e27ce4 100644 --- a/backend/src/plugins/NameHistory/commands/NamesCmd.ts +++ b/backend/src/plugins/NameHistory/commands/NamesCmd.ts @@ -1,11 +1,11 @@ import { Snowflake } from "discord.js"; import { createChunkedMessage, disableCodeBlocks } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { MAX_NICKNAME_ENTRIES_PER_USER } from "../../../data/GuildNicknameHistory"; -import { MAX_USERNAME_ENTRIES_PER_USER } from "../../../data/UsernameHistory"; -import { NICKNAME_RETENTION_PERIOD } from "../../../data/cleanup/nicknames"; -import { DAYS, renderUsername } from "../../../utils"; -import { nameHistoryCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { MAX_NICKNAME_ENTRIES_PER_USER } from "../../../data/GuildNicknameHistory.js"; +import { MAX_USERNAME_ENTRIES_PER_USER } from "../../../data/UsernameHistory.js"; +import { NICKNAME_RETENTION_PERIOD } from "../../../data/cleanup/nicknames.js"; +import { DAYS, renderUsername } from "../../../utils.js"; +import { nameHistoryCmd } from "../types.js"; export const NamesCmd = nameHistoryCmd({ trigger: "names", diff --git a/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts b/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts index 0d644663..5bdbd496 100644 --- a/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts +++ b/backend/src/plugins/NameHistory/events/UpdateNameEvts.ts @@ -1,5 +1,5 @@ -import { nameHistoryEvt } from "../types"; -import { updateNickname } from "../updateNickname"; +import { nameHistoryEvt } from "../types.js"; +import { updateNickname } from "../updateNickname.js"; export const ChannelJoinEvt = nameHistoryEvt({ event: "voiceStateUpdate", diff --git a/backend/src/plugins/NameHistory/info.ts b/backend/src/plugins/NameHistory/info.ts index b67742d5..985652dd 100644 --- a/backend/src/plugins/NameHistory/info.ts +++ b/backend/src/plugins/NameHistory/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { zNameHistoryConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { zNameHistoryConfig } from "./types.js"; export const nameHistoryPluginInfo: ZeppelinPluginInfo = { prettyName: "Name history", diff --git a/backend/src/plugins/NameHistory/types.ts b/backend/src/plugins/NameHistory/types.ts index df96a56b..d36763b7 100644 --- a/backend/src/plugins/NameHistory/types.ts +++ b/backend/src/plugins/NameHistory/types.ts @@ -1,9 +1,9 @@ import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { Queue } from "../../Queue"; -import { GuildNicknameHistory } from "../../data/GuildNicknameHistory"; -import { UsernameHistory } from "../../data/UsernameHistory"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { Queue } from "../../Queue.js"; +import { GuildNicknameHistory } from "../../data/GuildNicknameHistory.js"; +import { UsernameHistory } from "../../data/UsernameHistory.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zNameHistoryConfig = z.strictObject({ can_view: z.boolean(), diff --git a/backend/src/plugins/NameHistory/updateNickname.ts b/backend/src/plugins/NameHistory/updateNickname.ts index e843ae3b..2eebad1e 100644 --- a/backend/src/plugins/NameHistory/updateNickname.ts +++ b/backend/src/plugins/NameHistory/updateNickname.ts @@ -1,6 +1,6 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; -import { NameHistoryPluginType } from "./types"; +import { NameHistoryPluginType } from "./types.js"; export async function updateNickname(pluginData: GuildPluginData, member: GuildMember) { if (!member) return; diff --git a/backend/src/plugins/Persist/PersistPlugin.ts b/backend/src/plugins/Persist/PersistPlugin.ts index 760ecc26..7d9a5d6e 100644 --- a/backend/src/plugins/Persist/PersistPlugin.ts +++ b/backend/src/plugins/Persist/PersistPlugin.ts @@ -1,11 +1,11 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildPersistedData } from "../../data/GuildPersistedData"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin"; -import { LoadDataEvt } from "./events/LoadDataEvt"; -import { StoreDataEvt } from "./events/StoreDataEvt"; -import { PersistPluginType, zPersistConfig } from "./types"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildPersistedData } from "../../data/GuildPersistedData.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin.js"; +import { LoadDataEvt } from "./events/LoadDataEvt.js"; +import { StoreDataEvt } from "./events/StoreDataEvt.js"; +import { PersistPluginType, zPersistConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Persist/events/LoadDataEvt.ts b/backend/src/plugins/Persist/events/LoadDataEvt.ts index 3fb1dcdb..47ccaedf 100644 --- a/backend/src/plugins/Persist/events/LoadDataEvt.ts +++ b/backend/src/plugins/Persist/events/LoadDataEvt.ts @@ -1,14 +1,14 @@ import { GuildMember, PermissionFlagsBits } from "discord.js"; import { GuildPluginData } from "knub"; import intersection from "lodash.intersection"; -import { PersistedData } from "../../../data/entities/PersistedData"; -import { SECONDS } from "../../../utils"; -import { canAssignRole } from "../../../utils/canAssignRole"; -import { getMissingPermissions } from "../../../utils/getMissingPermissions"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; -import { PersistPluginType, persistEvt } from "../types"; +import { PersistedData } from "../../../data/entities/PersistedData.js"; +import { SECONDS } from "../../../utils.js"; +import { canAssignRole } from "../../../utils/canAssignRole.js"; +import { getMissingPermissions } from "../../../utils/getMissingPermissions.js"; +import { missingPermissionError } from "../../../utils/missingPermissionError.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin.js"; +import { PersistPluginType, persistEvt } from "../types.js"; const p = PermissionFlagsBits; diff --git a/backend/src/plugins/Persist/events/StoreDataEvt.ts b/backend/src/plugins/Persist/events/StoreDataEvt.ts index 9385c279..e8380cad 100644 --- a/backend/src/plugins/Persist/events/StoreDataEvt.ts +++ b/backend/src/plugins/Persist/events/StoreDataEvt.ts @@ -1,5 +1,5 @@ -import { PersistedData } from "../../../data/entities/PersistedData"; -import { persistEvt } from "../types"; +import { PersistedData } from "../../../data/entities/PersistedData.js"; +import { persistEvt } from "../types.js"; export const StoreDataEvt = persistEvt({ event: "guildMemberRemove", diff --git a/backend/src/plugins/Persist/info.ts b/backend/src/plugins/Persist/info.ts index 0fc6f9b1..122b3eeb 100644 --- a/backend/src/plugins/Persist/info.ts +++ b/backend/src/plugins/Persist/info.ts @@ -1,6 +1,6 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; -import { zPersistConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; +import { zPersistConfig } from "./types.js"; export const persistPluginInfo: ZeppelinPluginInfo = { prettyName: "Persist", diff --git a/backend/src/plugins/Persist/types.ts b/backend/src/plugins/Persist/types.ts index 4f42faa9..6ce5d1df 100644 --- a/backend/src/plugins/Persist/types.ts +++ b/backend/src/plugins/Persist/types.ts @@ -1,8 +1,8 @@ import { BasePluginType, guildPluginEventListener } from "knub"; import z from "zod"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildPersistedData } from "../../data/GuildPersistedData"; -import { zSnowflake } from "../../utils"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildPersistedData } from "../../data/GuildPersistedData.js"; +import { zSnowflake } from "../../utils.js"; export const zPersistConfig = z.strictObject({ persisted_roles: z.array(zSnowflake), diff --git a/backend/src/plugins/Phisherman/PhishermanPlugin.ts b/backend/src/plugins/Phisherman/PhishermanPlugin.ts index a5196235..3e1b4a50 100644 --- a/backend/src/plugins/Phisherman/PhishermanPlugin.ts +++ b/backend/src/plugins/Phisherman/PhishermanPlugin.ts @@ -1,8 +1,8 @@ import { PluginOptions, guildPlugin } from "knub"; -import { hasPhishermanMasterAPIKey, phishermanApiKeyIsValid } from "../../data/Phisherman"; -import { makePublicFn } from "../../pluginUtils"; -import { getDomainInfo } from "./functions/getDomainInfo"; -import { PhishermanPluginType, zPhishermanConfig } from "./types"; +import { hasPhishermanMasterAPIKey, phishermanApiKeyIsValid } from "../../data/Phisherman.js"; +import { makePublicFn } from "../../pluginUtils.js"; +import { getDomainInfo } from "./functions/getDomainInfo.js"; +import { PhishermanPluginType, zPhishermanConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Phisherman/functions/getDomainInfo.ts b/backend/src/plugins/Phisherman/functions/getDomainInfo.ts index 2714ec01..f2913194 100644 --- a/backend/src/plugins/Phisherman/functions/getDomainInfo.ts +++ b/backend/src/plugins/Phisherman/functions/getDomainInfo.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { getPhishermanDomainInfo, phishermanDomainIsSafe, trackPhishermanCaughtDomain } from "../../../data/Phisherman"; -import { PhishermanDomainInfo } from "../../../data/types/phisherman"; -import { PhishermanPluginType } from "../types"; +import { getPhishermanDomainInfo, phishermanDomainIsSafe, trackPhishermanCaughtDomain } from "../../../data/Phisherman.js"; +import { PhishermanDomainInfo } from "../../../data/types/phisherman.js"; +import { PhishermanPluginType } from "../types.js"; export async function getDomainInfo( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Phisherman/info.ts b/backend/src/plugins/Phisherman/info.ts index 04c4c4a0..88922112 100644 --- a/backend/src/plugins/Phisherman/info.ts +++ b/backend/src/plugins/Phisherman/info.ts @@ -1,6 +1,6 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; -import { zPhishermanConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; +import { zPhishermanConfig } from "./types.js"; export const phishermanPluginInfo: ZeppelinPluginInfo = { prettyName: "Phisherman", diff --git a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts index 380a2a25..636208ee 100644 --- a/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts +++ b/backend/src/plugins/PingableRoles/PingableRolesPlugin.ts @@ -1,9 +1,9 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildPingableRoles } from "../../data/GuildPingableRoles"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { PingableRoleDisableCmd } from "./commands/PingableRoleDisableCmd"; -import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd"; -import { PingableRolesPluginType, zPingableRolesConfig } from "./types"; +import { GuildPingableRoles } from "../../data/GuildPingableRoles.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { PingableRoleDisableCmd } from "./commands/PingableRoleDisableCmd.js"; +import { PingableRoleEnableCmd } from "./commands/PingableRoleEnableCmd.js"; +import { PingableRolesPluginType, zPingableRolesConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts index a66d41a7..cc0d9887 100644 --- a/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts +++ b/backend/src/plugins/PingableRoles/commands/PingableRoleDisableCmd.ts @@ -1,5 +1,5 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { pingableRolesCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { pingableRolesCmd } from "../types.js"; export const PingableRoleDisableCmd = pingableRolesCmd({ trigger: ["pingable_role disable", "pingable_role d"], diff --git a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts index 31218b5d..20b3cc8f 100644 --- a/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts +++ b/backend/src/plugins/PingableRoles/commands/PingableRoleEnableCmd.ts @@ -1,5 +1,5 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { pingableRolesCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { pingableRolesCmd } from "../types.js"; export const PingableRoleEnableCmd = pingableRolesCmd({ trigger: "pingable_role", diff --git a/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts b/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts index f91b7264..1c97695a 100644 --- a/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts +++ b/backend/src/plugins/PingableRoles/events/ChangePingableEvts.ts @@ -1,7 +1,7 @@ -import { pingableRolesEvt } from "../types"; -import { disablePingableRoles } from "../utils/disablePingableRoles"; -import { enablePingableRoles } from "../utils/enablePingableRoles"; -import { getPingableRolesForChannel } from "../utils/getPingableRolesForChannel"; +import { pingableRolesEvt } from "../types.js"; +import { disablePingableRoles } from "../utils/disablePingableRoles.js"; +import { enablePingableRoles } from "../utils/enablePingableRoles.js"; +import { getPingableRolesForChannel } from "../utils/getPingableRolesForChannel.js"; const TIMEOUT = 10 * 1000; diff --git a/backend/src/plugins/PingableRoles/info.ts b/backend/src/plugins/PingableRoles/info.ts index 1282eb4c..f0823fc8 100644 --- a/backend/src/plugins/PingableRoles/info.ts +++ b/backend/src/plugins/PingableRoles/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { zPingableRolesConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { zPingableRolesConfig } from "./types.js"; export const pingableRolesPluginInfo: ZeppelinPluginInfo = { prettyName: "Pingable roles", diff --git a/backend/src/plugins/PingableRoles/types.ts b/backend/src/plugins/PingableRoles/types.ts index 55edd97c..b79ac27f 100644 --- a/backend/src/plugins/PingableRoles/types.ts +++ b/backend/src/plugins/PingableRoles/types.ts @@ -1,8 +1,8 @@ import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { GuildPingableRoles } from "../../data/GuildPingableRoles"; -import { PingableRole } from "../../data/entities/PingableRole"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { GuildPingableRoles } from "../../data/GuildPingableRoles.js"; +import { PingableRole } from "../../data/entities/PingableRole.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zPingableRolesConfig = z.strictObject({ can_manage: z.boolean(), diff --git a/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts b/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts index b417ecdf..a4ea15d5 100644 --- a/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts +++ b/backend/src/plugins/PingableRoles/utils/disablePingableRoles.ts @@ -1,7 +1,7 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { PingableRole } from "../../../data/entities/PingableRole"; -import { PingableRolesPluginType } from "../types"; +import { PingableRole } from "../../../data/entities/PingableRole.js"; +import { PingableRolesPluginType } from "../types.js"; export function disablePingableRoles( pluginData: GuildPluginData, diff --git a/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts b/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts index 7aec4df4..a4dc2634 100644 --- a/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts +++ b/backend/src/plugins/PingableRoles/utils/enablePingableRoles.ts @@ -1,7 +1,7 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { PingableRole } from "../../../data/entities/PingableRole"; -import { PingableRolesPluginType } from "../types"; +import { PingableRole } from "../../../data/entities/PingableRole.js"; +import { PingableRolesPluginType } from "../types.js"; export function enablePingableRoles( pluginData: GuildPluginData, diff --git a/backend/src/plugins/PingableRoles/utils/getPingableRolesForChannel.ts b/backend/src/plugins/PingableRoles/utils/getPingableRolesForChannel.ts index 96b6b228..6949edf1 100644 --- a/backend/src/plugins/PingableRoles/utils/getPingableRolesForChannel.ts +++ b/backend/src/plugins/PingableRoles/utils/getPingableRolesForChannel.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { PingableRole } from "../../../data/entities/PingableRole"; -import { PingableRolesPluginType } from "../types"; +import { PingableRole } from "../../../data/entities/PingableRole.js"; +import { PingableRolesPluginType } from "../types.js"; export async function getPingableRolesForChannel( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Post/PostPlugin.ts b/backend/src/plugins/Post/PostPlugin.ts index a96d21b4..b5e9a83a 100644 --- a/backend/src/plugins/Post/PostPlugin.ts +++ b/backend/src/plugins/Post/PostPlugin.ts @@ -1,20 +1,20 @@ import { PluginOptions, guildPlugin } from "knub"; -import { onGuildEvent } from "../../data/GuildEvents"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { GuildScheduledPosts } from "../../data/GuildScheduledPosts"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { EditCmd } from "./commands/EditCmd"; -import { EditEmbedCmd } from "./commands/EditEmbedCmd"; -import { PostCmd } from "./commands/PostCmd"; -import { PostEmbedCmd } from "./commands/PostEmbedCmd"; -import { ScheduledPostsDeleteCmd } from "./commands/ScheduledPostsDeleteCmd"; -import { ScheduledPostsListCmd } from "./commands/ScheduledPostsListCmd"; -import { ScheduledPostsShowCmd } from "./commands/ScheduledPostsShowCmd"; -import { PostPluginType, zPostConfig } from "./types"; -import { postScheduledPost } from "./util/postScheduledPost"; +import { onGuildEvent } from "../../data/GuildEvents.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { GuildScheduledPosts } from "../../data/GuildScheduledPosts.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin.js"; +import { EditCmd } from "./commands/EditCmd.js"; +import { EditEmbedCmd } from "./commands/EditEmbedCmd.js"; +import { PostCmd } from "./commands/PostCmd.js"; +import { PostEmbedCmd } from "./commands/PostEmbedCmd.js"; +import { ScheduledPostsDeleteCmd } from "./commands/ScheduledPostsDeleteCmd.js"; +import { ScheduledPostsListCmd } from "./commands/ScheduledPostsListCmd.js"; +import { ScheduledPostsShowCmd } from "./commands/ScheduledPostsShowCmd.js"; +import { PostPluginType, zPostConfig } from "./types.js"; +import { postScheduledPost } from "./util/postScheduledPost.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Post/commands/EditCmd.ts b/backend/src/plugins/Post/commands/EditCmd.ts index 9dc7d2d0..e3867dbb 100644 --- a/backend/src/plugins/Post/commands/EditCmd.ts +++ b/backend/src/plugins/Post/commands/EditCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { postCmd } from "../types"; -import { formatContent } from "../util/formatContent"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { postCmd } from "../types.js"; +import { formatContent } from "../util/formatContent.js"; export const EditCmd = postCmd({ trigger: "edit", diff --git a/backend/src/plugins/Post/commands/EditEmbedCmd.ts b/backend/src/plugins/Post/commands/EditEmbedCmd.ts index 3ceff537..01da2c14 100644 --- a/backend/src/plugins/Post/commands/EditEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/EditEmbedCmd.ts @@ -1,10 +1,10 @@ import { APIEmbed } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isValidEmbed, trimLines } from "../../../utils"; -import { parseColor } from "../../../utils/parseColor"; -import { rgbToInt } from "../../../utils/rgbToInt"; -import { postCmd } from "../types"; -import { formatContent } from "../util/formatContent"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isValidEmbed, trimLines } from "../../../utils.js"; +import { parseColor } from "../../../utils/parseColor.js"; +import { rgbToInt } from "../../../utils/rgbToInt.js"; +import { postCmd } from "../types.js"; +import { formatContent } from "../util/formatContent.js"; export const EditEmbedCmd = postCmd({ trigger: "edit_embed", diff --git a/backend/src/plugins/Post/commands/PostCmd.ts b/backend/src/plugins/Post/commands/PostCmd.ts index 4a1f3a4a..65fc007b 100644 --- a/backend/src/plugins/Post/commands/PostCmd.ts +++ b/backend/src/plugins/Post/commands/PostCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { postCmd } from "../types"; -import { actualPostCmd } from "../util/actualPostCmd"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { postCmd } from "../types.js"; +import { actualPostCmd } from "../util/actualPostCmd.js"; export const PostCmd = postCmd({ trigger: "post", diff --git a/backend/src/plugins/Post/commands/PostEmbedCmd.ts b/backend/src/plugins/Post/commands/PostEmbedCmd.ts index 4a71d8af..a3a5e60c 100644 --- a/backend/src/plugins/Post/commands/PostEmbedCmd.ts +++ b/backend/src/plugins/Post/commands/PostEmbedCmd.ts @@ -1,11 +1,11 @@ import { APIEmbed } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isValidEmbed, trimLines } from "../../../utils"; -import { parseColor } from "../../../utils/parseColor"; -import { rgbToInt } from "../../../utils/rgbToInt"; -import { postCmd } from "../types"; -import { actualPostCmd } from "../util/actualPostCmd"; -import { formatContent } from "../util/formatContent"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isValidEmbed, trimLines } from "../../../utils.js"; +import { parseColor } from "../../../utils/parseColor.js"; +import { rgbToInt } from "../../../utils/rgbToInt.js"; +import { postCmd } from "../types.js"; +import { actualPostCmd } from "../util/actualPostCmd.js"; +import { formatContent } from "../util/formatContent.js"; export const PostEmbedCmd = postCmd({ trigger: "post_embed", diff --git a/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts index 75602f54..3854ca94 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsDeleteCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { clearUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop"; -import { sorter } from "../../../utils"; -import { postCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { clearUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop.js"; +import { sorter } from "../../../utils.js"; +import { postCmd } from "../types.js"; export const ScheduledPostsDeleteCmd = postCmd({ trigger: ["scheduled_posts delete", "scheduled_posts d"], diff --git a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts index c118440f..99f93597 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsListCmd.ts @@ -1,9 +1,9 @@ import { escapeCodeBlock } from "discord.js"; import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; -import { createChunkedMessage, DBDateFormat, deactivateMentions, sorter, trimLines } from "../../../utils"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { postCmd } from "../types"; +import { createChunkedMessage, DBDateFormat, deactivateMentions, sorter, trimLines } from "../../../utils.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js"; +import { postCmd } from "../types.js"; const SCHEDULED_POST_PREVIEW_TEXT_LENGTH = 50; diff --git a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts index 38e450fc..ea979f5c 100644 --- a/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts +++ b/backend/src/plugins/Post/commands/ScheduledPostsShowCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { sorter } from "../../../utils"; -import { postCmd } from "../types"; -import { postMessage } from "../util/postMessage"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { sorter } from "../../../utils.js"; +import { postCmd } from "../types.js"; +import { postMessage } from "../util/postMessage.js"; export const ScheduledPostsShowCmd = postCmd({ trigger: ["scheduled_posts", "scheduled_posts show"], diff --git a/backend/src/plugins/Post/info.ts b/backend/src/plugins/Post/info.ts index f55fd873..94b30941 100644 --- a/backend/src/plugins/Post/info.ts +++ b/backend/src/plugins/Post/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { zPostConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { zPostConfig } from "./types.js"; export const postPluginInfo: ZeppelinPluginInfo = { prettyName: "Post", diff --git a/backend/src/plugins/Post/types.ts b/backend/src/plugins/Post/types.ts index 7a0a1db7..96b11e71 100644 --- a/backend/src/plugins/Post/types.ts +++ b/backend/src/plugins/Post/types.ts @@ -1,9 +1,9 @@ import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { GuildScheduledPosts } from "../../data/GuildScheduledPosts"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { GuildScheduledPosts } from "../../data/GuildScheduledPosts.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zPostConfig = z.strictObject({ can_post: z.boolean(), diff --git a/backend/src/plugins/Post/util/actualPostCmd.ts b/backend/src/plugins/Post/util/actualPostCmd.ts index 987be772..d1265b02 100644 --- a/backend/src/plugins/Post/util/actualPostCmd.ts +++ b/backend/src/plugins/Post/util/actualPostCmd.ts @@ -2,13 +2,13 @@ import { GuildTextBasedChannel, Message } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { registerUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop"; -import { DBDateFormat, MINUTES, StrictMessageContent, errorMessage, renderUsername } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { PostPluginType } from "../types"; -import { parseScheduleTime } from "./parseScheduleTime"; -import { postMessage } from "./postMessage"; +import { registerUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop.js"; +import { DBDateFormat, MINUTES, StrictMessageContent, errorMessage, renderUsername } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js"; +import { PostPluginType } from "../types.js"; +import { parseScheduleTime } from "./parseScheduleTime.js"; +import { postMessage } from "./postMessage.js"; const MIN_REPEAT_TIME = 5 * MINUTES; const MAX_REPEAT_TIME = Math.pow(2, 32); diff --git a/backend/src/plugins/Post/util/parseScheduleTime.ts b/backend/src/plugins/Post/util/parseScheduleTime.ts index 5f5325e5..8ac87fa1 100644 --- a/backend/src/plugins/Post/util/parseScheduleTime.ts +++ b/backend/src/plugins/Post/util/parseScheduleTime.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; import moment, { Moment } from "moment-timezone"; -import { convertDelayStringToMS } from "../../../utils"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; +import { convertDelayStringToMS } from "../../../utils.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js"; // TODO: Extract out of the Post plugin, use everywhere with a date input export async function parseScheduleTime( diff --git a/backend/src/plugins/Post/util/postMessage.ts b/backend/src/plugins/Post/util/postMessage.ts index e4b4c1e6..673aa833 100644 --- a/backend/src/plugins/Post/util/postMessage.ts +++ b/backend/src/plugins/Post/util/postMessage.ts @@ -1,9 +1,9 @@ import { Attachment, GuildTextBasedChannel, Message, MessageCreateOptions } from "discord.js"; import fs from "fs"; import { GuildPluginData } from "knub"; -import { downloadFile } from "../../../utils"; -import { PostPluginType } from "../types"; -import { formatContent } from "./formatContent"; +import { downloadFile } from "../../../utils.js"; +import { PostPluginType } from "../types.js"; +import { formatContent } from "./formatContent.js"; const fsp = fs.promises; diff --git a/backend/src/plugins/Post/util/postScheduledPost.ts b/backend/src/plugins/Post/util/postScheduledPost.ts index e4a3e1e0..7ffe62f3 100644 --- a/backend/src/plugins/Post/util/postScheduledPost.ts +++ b/backend/src/plugins/Post/util/postScheduledPost.ts @@ -1,13 +1,13 @@ import { Snowflake, User } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { ScheduledPost } from "../../../data/entities/ScheduledPost"; -import { registerUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop"; -import { logger } from "../../../logger"; -import { DBDateFormat, verboseChannelMention, verboseUserMention } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { PostPluginType } from "../types"; -import { postMessage } from "./postMessage"; +import { ScheduledPost } from "../../../data/entities/ScheduledPost.js"; +import { registerUpcomingScheduledPost } from "../../../data/loops/upcomingScheduledPostsLoop.js"; +import { logger } from "../../../logger.js"; +import { DBDateFormat, verboseChannelMention, verboseUserMention } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { PostPluginType } from "../types.js"; +import { postMessage } from "./postMessage.js"; export async function postScheduledPost(pluginData: GuildPluginData, post: ScheduledPost) { // First, update the scheduled post or delete it from the database *before* we try posting it. diff --git a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts index 79bcbef0..6d819fa7 100644 --- a/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts +++ b/backend/src/plugins/ReactionRoles/ReactionRolesPlugin.ts @@ -1,15 +1,15 @@ import { PluginOptions, guildPlugin } from "knub"; -import { Queue } from "../../Queue"; -import { GuildReactionRoles } from "../../data/GuildReactionRoles"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { ClearReactionRolesCmd } from "./commands/ClearReactionRolesCmd"; -import { InitReactionRolesCmd } from "./commands/InitReactionRolesCmd"; -import { RefreshReactionRolesCmd } from "./commands/RefreshReactionRolesCmd"; -import { AddReactionRoleEvt } from "./events/AddReactionRoleEvt"; -import { MessageDeletedEvt } from "./events/MessageDeletedEvt"; -import { ReactionRolesPluginType, zReactionRolesConfig } from "./types"; +import { Queue } from "../../Queue.js"; +import { GuildReactionRoles } from "../../data/GuildReactionRoles.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { ClearReactionRolesCmd } from "./commands/ClearReactionRolesCmd.js"; +import { InitReactionRolesCmd } from "./commands/InitReactionRolesCmd.js"; +import { RefreshReactionRolesCmd } from "./commands/RefreshReactionRolesCmd.js"; +import { AddReactionRoleEvt } from "./events/AddReactionRoleEvt.js"; +import { MessageDeletedEvt } from "./events/MessageDeletedEvt.js"; +import { ReactionRolesPluginType, zReactionRolesConfig } from "./types.js"; const MIN_AUTO_REFRESH = 1000 * 60 * 15; // 15min minimum, let's not abuse the API diff --git a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts index 44f22c99..5bfb5176 100644 --- a/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/ClearReactionRolesCmd.ts @@ -1,7 +1,7 @@ import { Message } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isDiscordAPIError } from "../../../utils"; -import { reactionRolesCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isDiscordAPIError } from "../../../utils.js"; +import { reactionRolesCmd } from "../types.js"; export const ClearReactionRolesCmd = reactionRolesCmd({ trigger: "reaction_roles clear", diff --git a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts index 35d23865..e3144123 100644 --- a/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/InitReactionRolesCmd.ts @@ -1,9 +1,9 @@ import { Snowflake } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canUseEmoji, isDiscordAPIError, isValidEmoji, noop, trimPluginDescription } from "../../../utils"; -import { canReadChannel } from "../../../utils/canReadChannel"; -import { TReactionRolePair, reactionRolesCmd } from "../types"; -import { applyReactionRoleReactionsToMessage } from "../util/applyReactionRoleReactionsToMessage"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { canUseEmoji, isDiscordAPIError, isValidEmoji, noop, trimPluginDescription } from "../../../utils.js"; +import { canReadChannel } from "../../../utils/canReadChannel.js"; +import { TReactionRolePair, reactionRolesCmd } from "../types.js"; +import { applyReactionRoleReactionsToMessage } from "../util/applyReactionRoleReactionsToMessage.js"; const CLEAR_ROLES_EMOJI = "❌"; diff --git a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts index ad2e0c47..3dd6392a 100644 --- a/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts +++ b/backend/src/plugins/ReactionRoles/commands/RefreshReactionRolesCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { reactionRolesCmd } from "../types"; -import { refreshReactionRoles } from "../util/refreshReactionRoles"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { reactionRolesCmd } from "../types.js"; +import { refreshReactionRoles } from "../util/refreshReactionRoles.js"; export const RefreshReactionRolesCmd = reactionRolesCmd({ trigger: "reaction_roles refresh", diff --git a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts index 324405b3..155fffb2 100644 --- a/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/AddReactionRoleEvt.ts @@ -1,7 +1,7 @@ import { Message } from "discord.js"; -import { noop, resolveMember, sleep } from "../../../utils"; -import { reactionRolesEvt } from "../types"; -import { addMemberPendingRoleChange } from "../util/addMemberPendingRoleChange"; +import { noop, resolveMember, sleep } from "../../../utils.js"; +import { reactionRolesEvt } from "../types.js"; +import { addMemberPendingRoleChange } from "../util/addMemberPendingRoleChange.js"; const CLEAR_ROLES_EMOJI = "❌"; diff --git a/backend/src/plugins/ReactionRoles/events/MessageDeletedEvt.ts b/backend/src/plugins/ReactionRoles/events/MessageDeletedEvt.ts index f75195c3..58e48bfd 100644 --- a/backend/src/plugins/ReactionRoles/events/MessageDeletedEvt.ts +++ b/backend/src/plugins/ReactionRoles/events/MessageDeletedEvt.ts @@ -1,4 +1,4 @@ -import { reactionRolesEvt } from "../types"; +import { reactionRolesEvt } from "../types.js"; export const MessageDeletedEvt = reactionRolesEvt({ event: "messageDelete", diff --git a/backend/src/plugins/ReactionRoles/info.ts b/backend/src/plugins/ReactionRoles/info.ts index 2ceebe5d..6cc21dd3 100644 --- a/backend/src/plugins/ReactionRoles/info.ts +++ b/backend/src/plugins/ReactionRoles/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { zReactionRolesConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { zReactionRolesConfig } from "./types.js"; export const reactionRolesPluginInfo: ZeppelinPluginInfo = { prettyName: "Reaction roles", diff --git a/backend/src/plugins/ReactionRoles/types.ts b/backend/src/plugins/ReactionRoles/types.ts index c985ece4..b5506c30 100644 --- a/backend/src/plugins/ReactionRoles/types.ts +++ b/backend/src/plugins/ReactionRoles/types.ts @@ -1,9 +1,9 @@ import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { Queue } from "../../Queue"; -import { GuildReactionRoles } from "../../data/GuildReactionRoles"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { Queue } from "../../Queue.js"; +import { GuildReactionRoles } from "../../data/GuildReactionRoles.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zReactionRolesConfig = z.strictObject({ auto_refresh_interval: z.number(), diff --git a/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts b/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts index 8f25a0ae..d239f7d7 100644 --- a/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts +++ b/backend/src/plugins/ReactionRoles/util/addMemberPendingRoleChange.ts @@ -1,9 +1,9 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { logger } from "../../../logger"; -import { renderUsername, resolveMember } from "../../../utils"; -import { memberRolesLock } from "../../../utils/lockNameHelpers"; -import { PendingMemberRoleChanges, ReactionRolesPluginType, RoleChangeMode } from "../types"; +import { logger } from "../../../logger.js"; +import { renderUsername, resolveMember } from "../../../utils.js"; +import { memberRolesLock } from "../../../utils/lockNameHelpers.js"; +import { PendingMemberRoleChanges, ReactionRolesPluginType, RoleChangeMode } from "../types.js"; const ROLE_CHANGE_BATCH_DEBOUNCE_TIME = 1500; diff --git a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts index 5d1b3a37..9c5094ed 100644 --- a/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts +++ b/backend/src/plugins/ReactionRoles/util/applyReactionRoleReactionsToMessage.ts @@ -1,9 +1,9 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { ReactionRole } from "../../../data/entities/ReactionRole"; -import { isDiscordAPIError, sleep } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { ReactionRolesPluginType } from "../types"; +import { ReactionRole } from "../../../data/entities/ReactionRole.js"; +import { isDiscordAPIError, sleep } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { ReactionRolesPluginType } from "../types.js"; const CLEAR_ROLES_EMOJI = "❌"; diff --git a/backend/src/plugins/ReactionRoles/util/autoRefreshLoop.ts b/backend/src/plugins/ReactionRoles/util/autoRefreshLoop.ts index 90b12578..f28cb5f3 100644 --- a/backend/src/plugins/ReactionRoles/util/autoRefreshLoop.ts +++ b/backend/src/plugins/ReactionRoles/util/autoRefreshLoop.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { ReactionRolesPluginType } from "../types"; -import { runAutoRefresh } from "./runAutoRefresh"; +import { ReactionRolesPluginType } from "../types.js"; +import { runAutoRefresh } from "./runAutoRefresh.js"; export async function autoRefreshLoop(pluginData: GuildPluginData, interval: number) { pluginData.state.autoRefreshTimeout = setTimeout(async () => { diff --git a/backend/src/plugins/ReactionRoles/util/refreshReactionRoles.ts b/backend/src/plugins/ReactionRoles/util/refreshReactionRoles.ts index 1cb3ff80..de61e85a 100644 --- a/backend/src/plugins/ReactionRoles/util/refreshReactionRoles.ts +++ b/backend/src/plugins/ReactionRoles/util/refreshReactionRoles.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { ReactionRolesPluginType } from "../types"; -import { applyReactionRoleReactionsToMessage } from "./applyReactionRoleReactionsToMessage"; +import { ReactionRolesPluginType } from "../types.js"; +import { applyReactionRoleReactionsToMessage } from "./applyReactionRoleReactionsToMessage.js"; export async function refreshReactionRoles( pluginData: GuildPluginData, diff --git a/backend/src/plugins/ReactionRoles/util/runAutoRefresh.ts b/backend/src/plugins/ReactionRoles/util/runAutoRefresh.ts index c1d2b42a..9a6dc446 100644 --- a/backend/src/plugins/ReactionRoles/util/runAutoRefresh.ts +++ b/backend/src/plugins/ReactionRoles/util/runAutoRefresh.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { ReactionRolesPluginType } from "../types"; -import { refreshReactionRoles } from "./refreshReactionRoles"; +import { ReactionRolesPluginType } from "../types.js"; +import { refreshReactionRoles } from "./refreshReactionRoles.js"; export async function runAutoRefresh(pluginData: GuildPluginData) { // Refresh reaction roles on all reaction role messages diff --git a/backend/src/plugins/Reminders/RemindersPlugin.ts b/backend/src/plugins/Reminders/RemindersPlugin.ts index 0a4d723f..439d7460 100644 --- a/backend/src/plugins/Reminders/RemindersPlugin.ts +++ b/backend/src/plugins/Reminders/RemindersPlugin.ts @@ -1,13 +1,13 @@ import { PluginOptions, guildPlugin } from "knub"; -import { onGuildEvent } from "../../data/GuildEvents"; -import { GuildReminders } from "../../data/GuildReminders"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { RemindCmd } from "./commands/RemindCmd"; -import { RemindersCmd } from "./commands/RemindersCmd"; -import { RemindersDeleteCmd } from "./commands/RemindersDeleteCmd"; -import { postReminder } from "./functions/postReminder"; -import { RemindersPluginType, zRemindersConfig } from "./types"; +import { onGuildEvent } from "../../data/GuildEvents.js"; +import { GuildReminders } from "../../data/GuildReminders.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin.js"; +import { RemindCmd } from "./commands/RemindCmd.js"; +import { RemindersCmd } from "./commands/RemindersCmd.js"; +import { RemindersDeleteCmd } from "./commands/RemindersDeleteCmd.js"; +import { postReminder } from "./functions/postReminder.js"; +import { RemindersPluginType, zRemindersConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Reminders/commands/RemindCmd.ts b/backend/src/plugins/Reminders/commands/RemindCmd.ts index 7999ad5a..eaa66746 100644 --- a/backend/src/plugins/Reminders/commands/RemindCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindCmd.ts @@ -1,10 +1,10 @@ import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { registerUpcomingReminder } from "../../../data/loops/upcomingRemindersLoop"; -import { convertDelayStringToMS, messageLink } from "../../../utils"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { remindersCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { registerUpcomingReminder } from "../../../data/loops/upcomingRemindersLoop.js"; +import { convertDelayStringToMS, messageLink } from "../../../utils.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js"; +import { remindersCmd } from "../types.js"; export const RemindCmd = remindersCmd({ trigger: ["remind", "remindme", "reminder"], diff --git a/backend/src/plugins/Reminders/commands/RemindersCmd.ts b/backend/src/plugins/Reminders/commands/RemindersCmd.ts index 393c5b24..585557ab 100644 --- a/backend/src/plugins/Reminders/commands/RemindersCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersCmd.ts @@ -1,8 +1,8 @@ import humanizeDuration from "humanize-duration"; import moment from "moment-timezone"; -import { createChunkedMessage, DBDateFormat, sorter } from "../../../utils"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { remindersCmd } from "../types"; +import { createChunkedMessage, DBDateFormat, sorter } from "../../../utils.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js"; +import { remindersCmd } from "../types.js"; export const RemindersCmd = remindersCmd({ trigger: "reminders", diff --git a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts index 5e40f692..a1eb5533 100644 --- a/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts +++ b/backend/src/plugins/Reminders/commands/RemindersDeleteCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { clearUpcomingReminder } from "../../../data/loops/upcomingRemindersLoop"; -import { sorter } from "../../../utils"; -import { remindersCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { clearUpcomingReminder } from "../../../data/loops/upcomingRemindersLoop.js"; +import { sorter } from "../../../utils.js"; +import { remindersCmd } from "../types.js"; export const RemindersDeleteCmd = remindersCmd({ trigger: ["reminders delete", "reminders d"], diff --git a/backend/src/plugins/Reminders/functions/postReminder.ts b/backend/src/plugins/Reminders/functions/postReminder.ts index 86afbf08..6726b5d4 100644 --- a/backend/src/plugins/Reminders/functions/postReminder.ts +++ b/backend/src/plugins/Reminders/functions/postReminder.ts @@ -2,9 +2,9 @@ import { HTTPError, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; import { disableLinkPreviews } from "knub/helpers"; import moment from "moment-timezone"; -import { Reminder } from "../../../data/entities/Reminder"; -import { DBDateFormat } from "../../../utils"; -import { RemindersPluginType } from "../types"; +import { Reminder } from "../../../data/entities/Reminder.js"; +import { DBDateFormat } from "../../../utils.js"; +import { RemindersPluginType } from "../types.js"; export async function postReminder(pluginData: GuildPluginData, reminder: Reminder) { const channel = pluginData.guild.channels.cache.get(reminder.channel_id as Snowflake); diff --git a/backend/src/plugins/Reminders/info.ts b/backend/src/plugins/Reminders/info.ts index 0110d36f..02f04cac 100644 --- a/backend/src/plugins/Reminders/info.ts +++ b/backend/src/plugins/Reminders/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { zRemindersConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { zRemindersConfig } from "./types.js"; export const remindersPluginInfo: ZeppelinPluginInfo = { prettyName: "Reminders", diff --git a/backend/src/plugins/Reminders/types.ts b/backend/src/plugins/Reminders/types.ts index ee2ad9bb..d3b3c05f 100644 --- a/backend/src/plugins/Reminders/types.ts +++ b/backend/src/plugins/Reminders/types.ts @@ -1,7 +1,7 @@ import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { GuildReminders } from "../../data/GuildReminders"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { GuildReminders } from "../../data/GuildReminders.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zRemindersConfig = z.strictObject({ can_use: z.boolean(), diff --git a/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts b/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts index e71c7ed0..f7d9f581 100644 --- a/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts +++ b/backend/src/plugins/RoleButtons/RoleButtonsPlugin.ts @@ -1,12 +1,12 @@ import { guildPlugin } from "knub"; -import { GuildRoleButtons } from "../../data/GuildRoleButtons"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin"; -import { resetButtonsCmd } from "./commands/resetButtons"; -import { onButtonInteraction } from "./events/buttonInteraction"; -import { applyAllRoleButtons } from "./functions/applyAllRoleButtons"; -import { RoleButtonsPluginType, zRoleButtonsConfig } from "./types"; +import { GuildRoleButtons } from "../../data/GuildRoleButtons.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin.js"; +import { resetButtonsCmd } from "./commands/resetButtons.js"; +import { onButtonInteraction } from "./events/buttonInteraction.js"; +import { applyAllRoleButtons } from "./functions/applyAllRoleButtons.js"; +import { RoleButtonsPluginType, zRoleButtonsConfig } from "./types.js"; export const RoleButtonsPlugin = guildPlugin()({ name: "role_buttons", diff --git a/backend/src/plugins/RoleButtons/commands/resetButtons.ts b/backend/src/plugins/RoleButtons/commands/resetButtons.ts index 49add73f..6213e4d5 100644 --- a/backend/src/plugins/RoleButtons/commands/resetButtons.ts +++ b/backend/src/plugins/RoleButtons/commands/resetButtons.ts @@ -1,7 +1,7 @@ import { guildPluginMessageCommand } from "knub"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { applyAllRoleButtons } from "../functions/applyAllRoleButtons"; -import { RoleButtonsPluginType } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { applyAllRoleButtons } from "../functions/applyAllRoleButtons.js"; +import { RoleButtonsPluginType } from "../types.js"; export const resetButtonsCmd = guildPluginMessageCommand()({ trigger: "role_buttons reset", diff --git a/backend/src/plugins/RoleButtons/events/buttonInteraction.ts b/backend/src/plugins/RoleButtons/events/buttonInteraction.ts index bc8c7632..f8973d05 100644 --- a/backend/src/plugins/RoleButtons/events/buttonInteraction.ts +++ b/backend/src/plugins/RoleButtons/events/buttonInteraction.ts @@ -1,10 +1,10 @@ import { GuildMember } from "discord.js"; import { guildPluginEventListener } from "knub"; -import { SECONDS } from "../../../utils"; -import { parseCustomId } from "../../../utils/parseCustomId"; -import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; -import { getAllRolesInButtons } from "../functions/getAllRolesInButtons"; -import { RoleButtonsPluginType, TRoleButtonOption } from "../types"; +import { SECONDS } from "../../../utils.js"; +import { parseCustomId } from "../../../utils/parseCustomId.js"; +import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin.js"; +import { getAllRolesInButtons } from "../functions/getAllRolesInButtons.js"; +import { RoleButtonsPluginType, TRoleButtonOption } from "../types.js"; const ROLE_BUTTON_CD = 5 * SECONDS; diff --git a/backend/src/plugins/RoleButtons/functions/applyAllRoleButtons.ts b/backend/src/plugins/RoleButtons/functions/applyAllRoleButtons.ts index bb50f3d5..fb456cd3 100644 --- a/backend/src/plugins/RoleButtons/functions/applyAllRoleButtons.ts +++ b/backend/src/plugins/RoleButtons/functions/applyAllRoleButtons.ts @@ -1,7 +1,7 @@ import { createHash } from "crypto"; import { GuildPluginData } from "knub"; -import { RoleButtonsPluginType } from "../types"; -import { applyRoleButtons } from "./applyRoleButtons"; +import { RoleButtonsPluginType } from "../types.js"; +import { applyRoleButtons } from "./applyRoleButtons.js"; export async function applyAllRoleButtons(pluginData: GuildPluginData) { const savedRoleButtons = await pluginData.state.roleButtons.getSavedRoleButtons(); diff --git a/backend/src/plugins/RoleButtons/functions/applyRoleButtons.ts b/backend/src/plugins/RoleButtons/functions/applyRoleButtons.ts index 3570ebd0..12d8bc3d 100644 --- a/backend/src/plugins/RoleButtons/functions/applyRoleButtons.ts +++ b/backend/src/plugins/RoleButtons/functions/applyRoleButtons.ts @@ -1,9 +1,9 @@ import { Message, MessageCreateOptions, MessageEditOptions } from "discord.js"; import { GuildPluginData } from "knub"; -import { RoleButtonsItem } from "../../../data/entities/RoleButtonsItem"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { RoleButtonsPluginType, TRoleButtonsConfigItem } from "../types"; -import { createButtonComponents } from "./createButtonComponents"; +import { RoleButtonsItem } from "../../../data/entities/RoleButtonsItem.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { RoleButtonsPluginType, TRoleButtonsConfigItem } from "../types.js"; +import { createButtonComponents } from "./createButtonComponents.js"; export async function applyRoleButtons( pluginData: GuildPluginData, diff --git a/backend/src/plugins/RoleButtons/functions/createButtonComponents.ts b/backend/src/plugins/RoleButtons/functions/createButtonComponents.ts index e41d87bc..8b56d3a9 100644 --- a/backend/src/plugins/RoleButtons/functions/createButtonComponents.ts +++ b/backend/src/plugins/RoleButtons/functions/createButtonComponents.ts @@ -1,7 +1,7 @@ import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js"; -import { buildCustomId } from "../../../utils/buildCustomId"; -import { TRoleButtonsConfigItem } from "../types"; -import { TooManyComponentsError } from "./TooManyComponentsError"; +import { buildCustomId } from "../../../utils/buildCustomId.js"; +import { TRoleButtonsConfigItem } from "../types.js"; +import { TooManyComponentsError } from "./TooManyComponentsError.js"; import { convertButtonStyleStringToEnum } from "./convertButtonStyleStringToEnum.js"; export function createButtonComponents(configItem: TRoleButtonsConfigItem): Array> { diff --git a/backend/src/plugins/RoleButtons/functions/getAllRolesInButtons.ts b/backend/src/plugins/RoleButtons/functions/getAllRolesInButtons.ts index c55c5990..38b82baa 100644 --- a/backend/src/plugins/RoleButtons/functions/getAllRolesInButtons.ts +++ b/backend/src/plugins/RoleButtons/functions/getAllRolesInButtons.ts @@ -1,4 +1,4 @@ -import { TRoleButtonsConfigItem } from "../types"; +import { TRoleButtonsConfigItem } from "../types.js"; // This function will be more complex in the future when the plugin supports select menus + sub-menus export function getAllRolesInButtons(buttons: TRoleButtonsConfigItem): string[] { diff --git a/backend/src/plugins/RoleButtons/info.ts b/backend/src/plugins/RoleButtons/info.ts index f729d006..7eaedaba 100644 --- a/backend/src/plugins/RoleButtons/info.ts +++ b/backend/src/plugins/RoleButtons/info.ts @@ -1,6 +1,6 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; -import { zRoleButtonsConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; +import { zRoleButtonsConfig } from "./types.js"; export const roleButtonsPluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/RoleButtons/types.ts b/backend/src/plugins/RoleButtons/types.ts index b863e7bc..37d84550 100644 --- a/backend/src/plugins/RoleButtons/types.ts +++ b/backend/src/plugins/RoleButtons/types.ts @@ -1,11 +1,11 @@ import { ButtonStyle } from "discord.js"; import { BasePluginType, pluginUtils } from "knub"; import z from "zod"; -import { GuildRoleButtons } from "../../data/GuildRoleButtons"; -import { zBoundedCharacters, zBoundedRecord, zMessageContent, zSnowflake } from "../../utils"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { TooManyComponentsError } from "./functions/TooManyComponentsError"; -import { createButtonComponents } from "./functions/createButtonComponents"; +import { GuildRoleButtons } from "../../data/GuildRoleButtons.js"; +import { zBoundedCharacters, zBoundedRecord, zMessageContent, zSnowflake } from "../../utils.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { TooManyComponentsError } from "./functions/TooManyComponentsError.js"; +import { createButtonComponents } from "./functions/createButtonComponents.js"; const zRoleButtonOption = z.strictObject({ role_id: zSnowflake, diff --git a/backend/src/plugins/RoleManager/RoleManagerPlugin.ts b/backend/src/plugins/RoleManager/RoleManagerPlugin.ts index a4430bfe..5137326f 100644 --- a/backend/src/plugins/RoleManager/RoleManagerPlugin.ts +++ b/backend/src/plugins/RoleManager/RoleManagerPlugin.ts @@ -1,13 +1,13 @@ import { guildPlugin } from "knub"; -import { GuildRoleQueue } from "../../data/GuildRoleQueue"; -import { makePublicFn } from "../../pluginUtils"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { addPriorityRole } from "./functions/addPriorityRole"; -import { addRole } from "./functions/addRole"; -import { removePriorityRole } from "./functions/removePriorityRole"; -import { removeRole } from "./functions/removeRole"; -import { runRoleAssignmentLoop } from "./functions/runRoleAssignmentLoop"; -import { RoleManagerPluginType, zRoleManagerConfig } from "./types"; +import { GuildRoleQueue } from "../../data/GuildRoleQueue.js"; +import { makePublicFn } from "../../pluginUtils.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { addPriorityRole } from "./functions/addPriorityRole.js"; +import { addRole } from "./functions/addRole.js"; +import { removePriorityRole } from "./functions/removePriorityRole.js"; +import { removeRole } from "./functions/removeRole.js"; +import { runRoleAssignmentLoop } from "./functions/runRoleAssignmentLoop.js"; +import { RoleManagerPluginType, zRoleManagerConfig } from "./types.js"; export const RoleManagerPlugin = guildPlugin()({ name: "role_manager", diff --git a/backend/src/plugins/RoleManager/functions/addPriorityRole.ts b/backend/src/plugins/RoleManager/functions/addPriorityRole.ts index 2c9534f6..5f46a0ca 100644 --- a/backend/src/plugins/RoleManager/functions/addPriorityRole.ts +++ b/backend/src/plugins/RoleManager/functions/addPriorityRole.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { PRIORITY_ROLE_PRIORITY } from "../constants"; -import { RoleManagerPluginType } from "../types"; -import { runRoleAssignmentLoop } from "./runRoleAssignmentLoop"; +import { PRIORITY_ROLE_PRIORITY } from "../constants.js"; +import { RoleManagerPluginType } from "../types.js"; +import { runRoleAssignmentLoop } from "./runRoleAssignmentLoop.js"; export async function addPriorityRole( pluginData: GuildPluginData, diff --git a/backend/src/plugins/RoleManager/functions/addRole.ts b/backend/src/plugins/RoleManager/functions/addRole.ts index 02f6d4a3..eab1f003 100644 --- a/backend/src/plugins/RoleManager/functions/addRole.ts +++ b/backend/src/plugins/RoleManager/functions/addRole.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { RoleManagerPluginType } from "../types"; -import { runRoleAssignmentLoop } from "./runRoleAssignmentLoop"; +import { RoleManagerPluginType } from "../types.js"; +import { runRoleAssignmentLoop } from "./runRoleAssignmentLoop.js"; export async function addRole(pluginData: GuildPluginData, userId: string, roleId: string) { await pluginData.state.roleQueue.addQueueItem(userId, roleId, true); diff --git a/backend/src/plugins/RoleManager/functions/removePriorityRole.ts b/backend/src/plugins/RoleManager/functions/removePriorityRole.ts index 4192a762..ac40c3ba 100644 --- a/backend/src/plugins/RoleManager/functions/removePriorityRole.ts +++ b/backend/src/plugins/RoleManager/functions/removePriorityRole.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { PRIORITY_ROLE_PRIORITY } from "../constants"; -import { RoleManagerPluginType } from "../types"; -import { runRoleAssignmentLoop } from "./runRoleAssignmentLoop"; +import { PRIORITY_ROLE_PRIORITY } from "../constants.js"; +import { RoleManagerPluginType } from "../types.js"; +import { runRoleAssignmentLoop } from "./runRoleAssignmentLoop.js"; export async function removePriorityRole( pluginData: GuildPluginData, diff --git a/backend/src/plugins/RoleManager/functions/removeRole.ts b/backend/src/plugins/RoleManager/functions/removeRole.ts index 2a2b6070..713afded 100644 --- a/backend/src/plugins/RoleManager/functions/removeRole.ts +++ b/backend/src/plugins/RoleManager/functions/removeRole.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { RoleManagerPluginType } from "../types"; -import { runRoleAssignmentLoop } from "./runRoleAssignmentLoop"; +import { RoleManagerPluginType } from "../types.js"; +import { runRoleAssignmentLoop } from "./runRoleAssignmentLoop.js"; export async function removeRole(pluginData: GuildPluginData, userId: string, roleId: string) { await pluginData.state.roleQueue.addQueueItem(userId, roleId, false); diff --git a/backend/src/plugins/RoleManager/functions/runRoleAssignmentLoop.ts b/backend/src/plugins/RoleManager/functions/runRoleAssignmentLoop.ts index 3ed71eef..a3699806 100644 --- a/backend/src/plugins/RoleManager/functions/runRoleAssignmentLoop.ts +++ b/backend/src/plugins/RoleManager/functions/runRoleAssignmentLoop.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; -import { logger } from "../../../logger"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { RoleManagerPluginType } from "../types"; +import { logger } from "../../../logger.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { RoleManagerPluginType } from "../types.js"; const ROLE_ASSIGNMENTS_PER_BATCH = 10; diff --git a/backend/src/plugins/RoleManager/info.ts b/backend/src/plugins/RoleManager/info.ts index 985a6111..7bc9571e 100644 --- a/backend/src/plugins/RoleManager/info.ts +++ b/backend/src/plugins/RoleManager/info.ts @@ -1,4 +1,4 @@ -import { ZeppelinPluginInfo } from "../../types"; +import { ZeppelinPluginInfo } from "../../types.js"; export const roleManagerPluginInfo: ZeppelinPluginInfo = { prettyName: "Role manager", diff --git a/backend/src/plugins/RoleManager/types.ts b/backend/src/plugins/RoleManager/types.ts index 51ba3080..1954d994 100644 --- a/backend/src/plugins/RoleManager/types.ts +++ b/backend/src/plugins/RoleManager/types.ts @@ -1,6 +1,6 @@ import { BasePluginType } from "knub"; import z from "zod"; -import { GuildRoleQueue } from "../../data/GuildRoleQueue"; +import { GuildRoleQueue } from "../../data/GuildRoleQueue.js"; export const zRoleManagerConfig = z.strictObject({}); diff --git a/backend/src/plugins/Roles/RolesPlugin.ts b/backend/src/plugins/Roles/RolesPlugin.ts index 117339b8..2334280b 100644 --- a/backend/src/plugins/Roles/RolesPlugin.ts +++ b/backend/src/plugins/Roles/RolesPlugin.ts @@ -1,13 +1,13 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildLogs } from "../../data/GuildLogs"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin"; -import { AddRoleCmd } from "./commands/AddRoleCmd"; -import { MassAddRoleCmd } from "./commands/MassAddRoleCmd"; -import { MassRemoveRoleCmd } from "./commands/MassRemoveRoleCmd"; -import { RemoveRoleCmd } from "./commands/RemoveRoleCmd"; -import { RolesPluginType, zRolesConfig } from "./types"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { RoleManagerPlugin } from "../RoleManager/RoleManagerPlugin.js"; +import { AddRoleCmd } from "./commands/AddRoleCmd.js"; +import { MassAddRoleCmd } from "./commands/MassAddRoleCmd.js"; +import { MassRemoveRoleCmd } from "./commands/MassRemoveRoleCmd.js"; +import { RemoveRoleCmd } from "./commands/RemoveRoleCmd.js"; +import { RolesPluginType, zRolesConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Roles/commands/AddRoleCmd.ts b/backend/src/plugins/Roles/commands/AddRoleCmd.ts index 9ce16346..d984082f 100644 --- a/backend/src/plugins/Roles/commands/AddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/AddRoleCmd.ts @@ -1,10 +1,10 @@ import { GuildChannel } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn } from "../../../pluginUtils"; -import { resolveRoleId, verboseUserMention } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; -import { rolesCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { canActOn } from "../../../pluginUtils.js"; +import { resolveRoleId, verboseUserMention } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin.js"; +import { rolesCmd } from "../types.js"; export const AddRoleCmd = rolesCmd({ trigger: "addrole", diff --git a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts index 4a73eaa9..6d008f32 100644 --- a/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassAddRoleCmd.ts @@ -1,11 +1,11 @@ import { GuildMember } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { logger } from "../../../logger"; -import { canActOn } from "../../../pluginUtils"; -import { resolveMember, resolveRoleId, successMessage } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; -import { rolesCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { logger } from "../../../logger.js"; +import { canActOn } from "../../../pluginUtils.js"; +import { resolveMember, resolveRoleId, successMessage } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin.js"; +import { rolesCmd } from "../types.js"; export const MassAddRoleCmd = rolesCmd({ trigger: "massaddrole", diff --git a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts index bc0d3233..169cf413 100644 --- a/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/MassRemoveRoleCmd.ts @@ -1,10 +1,10 @@ import { GuildMember } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn } from "../../../pluginUtils"; -import { resolveMember, resolveRoleId, successMessage } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; -import { rolesCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { canActOn } from "../../../pluginUtils.js"; +import { resolveMember, resolveRoleId, successMessage } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin.js"; +import { rolesCmd } from "../types.js"; export const MassRemoveRoleCmd = rolesCmd({ trigger: "massremoverole", diff --git a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts index a8b12479..1a4a4202 100644 --- a/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts +++ b/backend/src/plugins/Roles/commands/RemoveRoleCmd.ts @@ -1,10 +1,10 @@ import { GuildChannel } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn } from "../../../pluginUtils"; -import { resolveRoleId, verboseUserMention } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin"; -import { rolesCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { canActOn } from "../../../pluginUtils.js"; +import { resolveRoleId, verboseUserMention } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { RoleManagerPlugin } from "../../RoleManager/RoleManagerPlugin.js"; +import { rolesCmd } from "../types.js"; export const RemoveRoleCmd = rolesCmd({ trigger: "removerole", diff --git a/backend/src/plugins/Roles/info.ts b/backend/src/plugins/Roles/info.ts index cb876584..d946bf4f 100644 --- a/backend/src/plugins/Roles/info.ts +++ b/backend/src/plugins/Roles/info.ts @@ -1,6 +1,6 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; -import { zRolesConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; +import { zRolesConfig } from "./types.js"; export const rolesPluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/Roles/types.ts b/backend/src/plugins/Roles/types.ts index c3f48670..557a1d86 100644 --- a/backend/src/plugins/Roles/types.ts +++ b/backend/src/plugins/Roles/types.ts @@ -1,7 +1,7 @@ import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { GuildLogs } from "../../data/GuildLogs"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zRolesConfig = z.strictObject({ can_assign: z.boolean(), diff --git a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts index e7fbe875..b97e0857 100644 --- a/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts +++ b/backend/src/plugins/SelfGrantableRoles/SelfGrantableRolesPlugin.ts @@ -1,9 +1,9 @@ import { CooldownManager, PluginOptions, guildPlugin } from "knub"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { RoleAddCmd } from "./commands/RoleAddCmd"; -import { RoleHelpCmd } from "./commands/RoleHelpCmd"; -import { RoleRemoveCmd } from "./commands/RoleRemoveCmd"; -import { SelfGrantableRolesPluginType, zSelfGrantableRolesConfig } from "./types"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { RoleAddCmd } from "./commands/RoleAddCmd.js"; +import { RoleHelpCmd } from "./commands/RoleHelpCmd.js"; +import { RoleRemoveCmd } from "./commands/RoleRemoveCmd.js"; +import { SelfGrantableRolesPluginType, zSelfGrantableRolesConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts index f4e718aa..eacd9b2b 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleAddCmd.ts @@ -1,11 +1,11 @@ import { Role, Snowflake } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { memberRolesLock } from "../../../utils/lockNameHelpers"; -import { selfGrantableRolesCmd } from "../types"; -import { findMatchingRoles } from "../util/findMatchingRoles"; -import { getApplyingEntries } from "../util/getApplyingEntries"; -import { normalizeRoleNames } from "../util/normalizeRoleNames"; -import { splitRoleNames } from "../util/splitRoleNames"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { memberRolesLock } from "../../../utils/lockNameHelpers.js"; +import { selfGrantableRolesCmd } from "../types.js"; +import { findMatchingRoles } from "../util/findMatchingRoles.js"; +import { getApplyingEntries } from "../util/getApplyingEntries.js"; +import { normalizeRoleNames } from "../util/normalizeRoleNames.js"; +import { splitRoleNames } from "../util/splitRoleNames.js"; export const RoleAddCmd = selfGrantableRolesCmd({ trigger: ["role", "role add"], diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts index b1bf6899..5eb2d661 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleHelpCmd.ts @@ -1,6 +1,6 @@ -import { asSingleLine, trimLines } from "../../../utils"; -import { selfGrantableRolesCmd } from "../types"; -import { getApplyingEntries } from "../util/getApplyingEntries"; +import { asSingleLine, trimLines } from "../../../utils.js"; +import { selfGrantableRolesCmd } from "../types.js"; +import { getApplyingEntries } from "../util/getApplyingEntries.js"; export const RoleHelpCmd = selfGrantableRolesCmd({ trigger: ["role help", "role"], diff --git a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts index 1ca76b4d..b6e8d8ff 100644 --- a/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts +++ b/backend/src/plugins/SelfGrantableRoles/commands/RoleRemoveCmd.ts @@ -1,11 +1,11 @@ import { Snowflake } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { memberRolesLock } from "../../../utils/lockNameHelpers"; -import { selfGrantableRolesCmd } from "../types"; -import { findMatchingRoles } from "../util/findMatchingRoles"; -import { getApplyingEntries } from "../util/getApplyingEntries"; -import { normalizeRoleNames } from "../util/normalizeRoleNames"; -import { splitRoleNames } from "../util/splitRoleNames"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { memberRolesLock } from "../../../utils/lockNameHelpers.js"; +import { selfGrantableRolesCmd } from "../types.js"; +import { findMatchingRoles } from "../util/findMatchingRoles.js"; +import { getApplyingEntries } from "../util/getApplyingEntries.js"; +import { normalizeRoleNames } from "../util/normalizeRoleNames.js"; +import { splitRoleNames } from "../util/splitRoleNames.js"; export const RoleRemoveCmd = selfGrantableRolesCmd({ trigger: "role remove", diff --git a/backend/src/plugins/SelfGrantableRoles/info.ts b/backend/src/plugins/SelfGrantableRoles/info.ts index e6b9db28..40b6d451 100644 --- a/backend/src/plugins/SelfGrantableRoles/info.ts +++ b/backend/src/plugins/SelfGrantableRoles/info.ts @@ -1,6 +1,6 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; -import { zSelfGrantableRolesConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; +import { zSelfGrantableRolesConfig } from "./types.js"; export const selfGrantableRolesPluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/SelfGrantableRoles/types.ts b/backend/src/plugins/SelfGrantableRoles/types.ts index 7d8c4a0f..891672e9 100644 --- a/backend/src/plugins/SelfGrantableRoles/types.ts +++ b/backend/src/plugins/SelfGrantableRoles/types.ts @@ -1,7 +1,7 @@ import { BasePluginType, CooldownManager, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { zBoundedCharacters, zBoundedRecord } from "../../utils"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { zBoundedCharacters, zBoundedRecord } from "../../utils.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; const zRoleMap = z.record( zBoundedCharacters(1, 100), diff --git a/backend/src/plugins/SelfGrantableRoles/util/findMatchingRoles.ts b/backend/src/plugins/SelfGrantableRoles/util/findMatchingRoles.ts index 42a6dd34..ad82419a 100644 --- a/backend/src/plugins/SelfGrantableRoles/util/findMatchingRoles.ts +++ b/backend/src/plugins/SelfGrantableRoles/util/findMatchingRoles.ts @@ -1,4 +1,4 @@ -import { TSelfGrantableRoleEntry } from "../types"; +import { TSelfGrantableRoleEntry } from "../types.js"; export function findMatchingRoles(roleNames: string[], entries: TSelfGrantableRoleEntry[]): string[] { const aliasToRoleId = entries.reduce((map, entry) => { diff --git a/backend/src/plugins/SelfGrantableRoles/util/getApplyingEntries.ts b/backend/src/plugins/SelfGrantableRoles/util/getApplyingEntries.ts index 25482d1c..c0aea14b 100644 --- a/backend/src/plugins/SelfGrantableRoles/util/getApplyingEntries.ts +++ b/backend/src/plugins/SelfGrantableRoles/util/getApplyingEntries.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { SelfGrantableRolesPluginType, TSelfGrantableRoleEntry } from "../types"; +import { SelfGrantableRolesPluginType, TSelfGrantableRoleEntry } from "../types.js"; export async function getApplyingEntries( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Slowmode/SlowmodePlugin.ts b/backend/src/plugins/Slowmode/SlowmodePlugin.ts index e82d6d62..4b80e2e1 100644 --- a/backend/src/plugins/Slowmode/SlowmodePlugin.ts +++ b/backend/src/plugins/Slowmode/SlowmodePlugin.ts @@ -1,18 +1,18 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { GuildSlowmodes } from "../../data/GuildSlowmodes"; -import { SECONDS } from "../../utils"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { SlowmodeClearCmd } from "./commands/SlowmodeClearCmd"; -import { SlowmodeDisableCmd } from "./commands/SlowmodeDisableCmd"; -import { SlowmodeGetCmd } from "./commands/SlowmodeGetCmd"; -import { SlowmodeListCmd } from "./commands/SlowmodeListCmd"; -import { SlowmodeSetCmd } from "./commands/SlowmodeSetCmd"; -import { SlowmodePluginType, zSlowmodeConfig } from "./types"; -import { clearExpiredSlowmodes } from "./util/clearExpiredSlowmodes"; -import { onMessageCreate } from "./util/onMessageCreate"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { GuildSlowmodes } from "../../data/GuildSlowmodes.js"; +import { SECONDS } from "../../utils.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { SlowmodeClearCmd } from "./commands/SlowmodeClearCmd.js"; +import { SlowmodeDisableCmd } from "./commands/SlowmodeDisableCmd.js"; +import { SlowmodeGetCmd } from "./commands/SlowmodeGetCmd.js"; +import { SlowmodeListCmd } from "./commands/SlowmodeListCmd.js"; +import { SlowmodeSetCmd } from "./commands/SlowmodeSetCmd.js"; +import { SlowmodePluginType, zSlowmodeConfig } from "./types.js"; +import { clearExpiredSlowmodes } from "./util/clearExpiredSlowmodes.js"; +import { onMessageCreate } from "./util/onMessageCreate.js"; const BOT_SLOWMODE_CLEAR_INTERVAL = 60 * SECONDS; diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts index c00f1ad9..e2b4569f 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeClearCmd.ts @@ -1,11 +1,11 @@ import { ChannelType, escapeInlineCode } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { asSingleLine, renderUsername } from "../../../utils"; -import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { BOT_SLOWMODE_CLEAR_PERMISSIONS } from "../requiredPermissions"; -import { slowmodeCmd } from "../types"; -import { clearBotSlowmodeFromUserId } from "../util/clearBotSlowmodeFromUserId"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { asSingleLine, renderUsername } from "../../../utils.js"; +import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions.js"; +import { missingPermissionError } from "../../../utils/missingPermissionError.js"; +import { BOT_SLOWMODE_CLEAR_PERMISSIONS } from "../requiredPermissions.js"; +import { slowmodeCmd } from "../types.js"; +import { clearBotSlowmodeFromUserId } from "../util/clearBotSlowmodeFromUserId.js"; export const SlowmodeClearCmd = slowmodeCmd({ trigger: ["slowmode clear", "slowmode c"], diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeDisableCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeDisableCmd.ts index 1889c559..011bf065 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeDisableCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeDisableCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { slowmodeCmd } from "../types"; -import { actualDisableSlowmodeCmd } from "../util/actualDisableSlowmodeCmd"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { slowmodeCmd } from "../types.js"; +import { actualDisableSlowmodeCmd } from "../util/actualDisableSlowmodeCmd.js"; export const SlowmodeDisableCmd = slowmodeCmd({ trigger: ["slowmode disable", "slowmode d"], diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts index 9583d433..e98160b4 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeGetCmd.ts @@ -1,6 +1,6 @@ import humanizeDuration from "humanize-duration"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { slowmodeCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { slowmodeCmd } from "../types.js"; export const SlowmodeGetCmd = slowmodeCmd({ trigger: "slowmode", diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts index 0fe32f84..043d7d5a 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeListCmd.ts @@ -1,8 +1,8 @@ import { GuildChannel, TextChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { createChunkedMessage } from "knub/helpers"; -import { errorMessage } from "../../../utils"; -import { slowmodeCmd } from "../types"; +import { errorMessage } from "../../../utils.js"; +import { slowmodeCmd } from "../types.js"; export const SlowmodeListCmd = slowmodeCmd({ trigger: ["slowmode list", "slowmode l", "slowmodes"], diff --git a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts index 84cf6baa..52a5713e 100644 --- a/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts +++ b/backend/src/plugins/Slowmode/commands/SlowmodeSetCmd.ts @@ -1,13 +1,13 @@ import { escapeInlineCode, PermissionsBitField } from "discord.js"; import humanizeDuration from "humanize-duration"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { asSingleLine, DAYS, HOURS, MINUTES } from "../../../utils"; -import { getMissingPermissions } from "../../../utils/getMissingPermissions"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { BOT_SLOWMODE_PERMISSIONS, NATIVE_SLOWMODE_PERMISSIONS } from "../requiredPermissions"; -import { slowmodeCmd } from "../types"; -import { actualDisableSlowmodeCmd } from "../util/actualDisableSlowmodeCmd"; -import { disableBotSlowmodeForChannel } from "../util/disableBotSlowmodeForChannel"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { asSingleLine, DAYS, HOURS, MINUTES } from "../../../utils.js"; +import { getMissingPermissions } from "../../../utils/getMissingPermissions.js"; +import { missingPermissionError } from "../../../utils/missingPermissionError.js"; +import { BOT_SLOWMODE_PERMISSIONS, NATIVE_SLOWMODE_PERMISSIONS } from "../requiredPermissions.js"; +import { slowmodeCmd } from "../types.js"; +import { actualDisableSlowmodeCmd } from "../util/actualDisableSlowmodeCmd.js"; +import { disableBotSlowmodeForChannel } from "../util/disableBotSlowmodeForChannel.js"; const MAX_NATIVE_SLOWMODE = 6 * HOURS; // 6 hours const MAX_BOT_SLOWMODE = DAYS * 365 * 100; // 100 years diff --git a/backend/src/plugins/Slowmode/info.ts b/backend/src/plugins/Slowmode/info.ts index 4dc4de79..b223b39c 100644 --- a/backend/src/plugins/Slowmode/info.ts +++ b/backend/src/plugins/Slowmode/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { zSlowmodeConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { zSlowmodeConfig } from "./types.js"; export const slowmodePluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/Slowmode/types.ts b/backend/src/plugins/Slowmode/types.ts index 73bd3cb8..a8ea070b 100644 --- a/backend/src/plugins/Slowmode/types.ts +++ b/backend/src/plugins/Slowmode/types.ts @@ -1,10 +1,10 @@ import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { GuildSlowmodes } from "../../data/GuildSlowmodes"; -import { SlowmodeChannel } from "../../data/entities/SlowmodeChannel"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { GuildSlowmodes } from "../../data/GuildSlowmodes.js"; +import { SlowmodeChannel } from "../../data/entities/SlowmodeChannel.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zSlowmodeConfig = z.strictObject({ use_native_slowmode: z.boolean(), diff --git a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts index 64298763..4c26e812 100644 --- a/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts +++ b/backend/src/plugins/Slowmode/util/actualDisableSlowmodeCmd.ts @@ -1,9 +1,9 @@ import { Message } from "discord.js"; -import { noop } from "../../../utils"; -import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { BOT_SLOWMODE_DISABLE_PERMISSIONS } from "../requiredPermissions"; -import { disableBotSlowmodeForChannel } from "./disableBotSlowmodeForChannel"; +import { noop } from "../../../utils.js"; +import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions.js"; +import { missingPermissionError } from "../../../utils/missingPermissionError.js"; +import { BOT_SLOWMODE_DISABLE_PERMISSIONS } from "../requiredPermissions.js"; +import { disableBotSlowmodeForChannel } from "./disableBotSlowmodeForChannel.js"; export async function actualDisableSlowmodeCmd(msg: Message, args, pluginData) { const botSlowmode = await pluginData.state.slowmodes.getChannelSlowmode(args.channel.id); diff --git a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts index ebfd653d..d9e7dddf 100644 --- a/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts +++ b/backend/src/plugins/Slowmode/util/applyBotSlowmodeToUserId.ts @@ -1,10 +1,10 @@ import { GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { logger } from "../../../logger"; -import { UnknownUser, isDiscordAPIError, verboseChannelMention, verboseUserMention } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { SlowmodePluginType } from "../types"; +import { LogType } from "../../../data/LogType.js"; +import { logger } from "../../../logger.js"; +import { UnknownUser, isDiscordAPIError, verboseChannelMention, verboseUserMention } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { SlowmodePluginType } from "../types.js"; export async function applyBotSlowmodeToUserId( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts index f76c924a..beb5d8ac 100644 --- a/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts +++ b/backend/src/plugins/Slowmode/util/clearBotSlowmodeFromUserId.ts @@ -1,7 +1,7 @@ import { AnyThreadChannel, GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { LogType } from "../../../data/LogType"; -import { SlowmodePluginType } from "../types"; +import { LogType } from "../../../data/LogType.js"; +import { SlowmodePluginType } from "../types.js"; export async function clearBotSlowmodeFromUserId( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts index d2f840fa..8e27b23c 100644 --- a/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts +++ b/backend/src/plugins/Slowmode/util/clearExpiredSlowmodes.ts @@ -1,10 +1,10 @@ import { GuildChannel, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { logger } from "../../../logger"; -import { UnknownUser, verboseChannelMention, verboseUserMention } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { SlowmodePluginType } from "../types"; -import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId"; +import { logger } from "../../../logger.js"; +import { UnknownUser, verboseChannelMention, verboseUserMention } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { SlowmodePluginType } from "../types.js"; +import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId.js"; export async function clearExpiredSlowmodes(pluginData: GuildPluginData) { const expiredSlowmodeUsers = await pluginData.state.slowmodes.getExpiredSlowmodeUsers(); diff --git a/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts b/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts index d3292901..0187504b 100644 --- a/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts +++ b/backend/src/plugins/Slowmode/util/disableBotSlowmodeForChannel.ts @@ -1,7 +1,7 @@ import { AnyThreadChannel, GuildTextBasedChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { SlowmodePluginType } from "../types"; -import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId"; +import { SlowmodePluginType } from "../types.js"; +import { clearBotSlowmodeFromUserId } from "./clearBotSlowmodeFromUserId.js"; export async function disableBotSlowmodeForChannel( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Slowmode/util/onMessageCreate.ts b/backend/src/plugins/Slowmode/util/onMessageCreate.ts index a83c315b..17c723a6 100644 --- a/backend/src/plugins/Slowmode/util/onMessageCreate.ts +++ b/backend/src/plugins/Slowmode/util/onMessageCreate.ts @@ -1,16 +1,16 @@ import { ChannelType, GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { SlowmodeChannel } from "../../../data/entities/SlowmodeChannel"; -import { hasPermission } from "../../../pluginUtils"; -import { resolveMember } from "../../../utils"; -import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions"; -import { messageLock } from "../../../utils/lockNameHelpers"; -import { missingPermissionError } from "../../../utils/missingPermissionError"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { BOT_SLOWMODE_PERMISSIONS } from "../requiredPermissions"; -import { SlowmodePluginType } from "../types"; -import { applyBotSlowmodeToUserId } from "./applyBotSlowmodeToUserId"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { SlowmodeChannel } from "../../../data/entities/SlowmodeChannel.js"; +import { hasPermission } from "../../../pluginUtils.js"; +import { resolveMember } from "../../../utils.js"; +import { getMissingChannelPermissions } from "../../../utils/getMissingChannelPermissions.js"; +import { messageLock } from "../../../utils/lockNameHelpers.js"; +import { missingPermissionError } from "../../../utils/missingPermissionError.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { BOT_SLOWMODE_PERMISSIONS } from "../requiredPermissions.js"; +import { SlowmodePluginType } from "../types.js"; +import { applyBotSlowmodeToUserId } from "./applyBotSlowmodeToUserId.js"; export async function onMessageCreate(pluginData: GuildPluginData, msg: SavedMessage) { if (msg.is_bot) return; diff --git a/backend/src/plugins/Spam/SpamPlugin.ts b/backend/src/plugins/Spam/SpamPlugin.ts index b4d27ae3..c4df1eda 100644 --- a/backend/src/plugins/Spam/SpamPlugin.ts +++ b/backend/src/plugins/Spam/SpamPlugin.ts @@ -1,13 +1,13 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildMutes } from "../../data/GuildMutes"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { SpamVoiceStateUpdateEvt } from "./events/SpamVoiceEvt"; -import { SpamPluginType, zSpamConfig } from "./types"; -import { clearOldRecentActions } from "./util/clearOldRecentActions"; -import { onMessageCreate } from "./util/onMessageCreate"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildMutes } from "../../data/GuildMutes.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { SpamVoiceStateUpdateEvt } from "./events/SpamVoiceEvt.js"; +import { SpamPluginType, zSpamConfig } from "./types.js"; +import { clearOldRecentActions } from "./util/clearOldRecentActions.js"; +import { onMessageCreate } from "./util/onMessageCreate.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Spam/events/SpamVoiceEvt.ts b/backend/src/plugins/Spam/events/SpamVoiceEvt.ts index ea354a98..81f8d697 100644 --- a/backend/src/plugins/Spam/events/SpamVoiceEvt.ts +++ b/backend/src/plugins/Spam/events/SpamVoiceEvt.ts @@ -1,5 +1,5 @@ -import { RecentActionType, spamEvt } from "../types"; -import { logAndDetectOtherSpam } from "../util/logAndDetectOtherSpam"; +import { RecentActionType, spamEvt } from "../types.js"; +import { logAndDetectOtherSpam } from "../util/logAndDetectOtherSpam.js"; export const SpamVoiceStateUpdateEvt = spamEvt({ event: "voiceStateUpdate", diff --git a/backend/src/plugins/Spam/info.ts b/backend/src/plugins/Spam/info.ts index 757fc294..7b3bac6a 100644 --- a/backend/src/plugins/Spam/info.ts +++ b/backend/src/plugins/Spam/info.ts @@ -1,6 +1,6 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; -import { zSpamConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; +import { zSpamConfig } from "./types.js"; export const spamPluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/Spam/types.ts b/backend/src/plugins/Spam/types.ts index f71e4180..8072474e 100644 --- a/backend/src/plugins/Spam/types.ts +++ b/backend/src/plugins/Spam/types.ts @@ -1,10 +1,10 @@ import { BasePluginType, guildPluginEventListener } from "knub"; import z from "zod"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildMutes } from "../../data/GuildMutes"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { zSnowflake } from "../../utils"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildMutes } from "../../data/GuildMutes.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { zSnowflake } from "../../utils.js"; const zBaseSingleSpamConfig = z.strictObject({ interval: z.number(), diff --git a/backend/src/plugins/Spam/util/addRecentAction.ts b/backend/src/plugins/Spam/util/addRecentAction.ts index 418702a8..ee80cc8b 100644 --- a/backend/src/plugins/Spam/util/addRecentAction.ts +++ b/backend/src/plugins/Spam/util/addRecentAction.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { RecentActionType, SpamPluginType } from "../types"; +import { RecentActionType, SpamPluginType } from "../types.js"; export function addRecentAction( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Spam/util/clearOldRecentActions.ts b/backend/src/plugins/Spam/util/clearOldRecentActions.ts index 1c0857b3..fc858285 100644 --- a/backend/src/plugins/Spam/util/clearOldRecentActions.ts +++ b/backend/src/plugins/Spam/util/clearOldRecentActions.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { SpamPluginType } from "../types"; +import { SpamPluginType } from "../types.js"; const MAX_INTERVAL = 300; diff --git a/backend/src/plugins/Spam/util/clearRecentUserActions.ts b/backend/src/plugins/Spam/util/clearRecentUserActions.ts index f4fab914..151b2b70 100644 --- a/backend/src/plugins/Spam/util/clearRecentUserActions.ts +++ b/backend/src/plugins/Spam/util/clearRecentUserActions.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { RecentActionType, SpamPluginType } from "../types"; +import { RecentActionType, SpamPluginType } from "../types.js"; export function clearRecentUserActions( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Spam/util/getRecentActionCount.ts b/backend/src/plugins/Spam/util/getRecentActionCount.ts index 5b0b0aef..17bcf9be 100644 --- a/backend/src/plugins/Spam/util/getRecentActionCount.ts +++ b/backend/src/plugins/Spam/util/getRecentActionCount.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { RecentActionType, SpamPluginType } from "../types"; +import { RecentActionType, SpamPluginType } from "../types.js"; export function getRecentActionCount( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Spam/util/getRecentActions.ts b/backend/src/plugins/Spam/util/getRecentActions.ts index de652a28..4492a642 100644 --- a/backend/src/plugins/Spam/util/getRecentActions.ts +++ b/backend/src/plugins/Spam/util/getRecentActions.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { RecentActionType, SpamPluginType } from "../types"; +import { RecentActionType, SpamPluginType } from "../types.js"; export function getRecentActions( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts index 4c8a4e25..56a06067 100644 --- a/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectMessageSpam.ts @@ -1,22 +1,22 @@ import { GuildTextBasedChannel, Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { LogType } from "../../../data/LogType"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { logger } from "../../../logger"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; -import { MuteResult } from "../../../plugins/Mutes/types"; -import { DBDateFormat, convertDelayStringToMS, noop, resolveMember, trimLines } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { RecentActionType, SpamPluginType, TBaseSingleSpamConfig } from "../types"; -import { addRecentAction } from "./addRecentAction"; -import { clearRecentUserActions } from "./clearRecentUserActions"; -import { getRecentActionCount } from "./getRecentActionCount"; -import { getRecentActions } from "./getRecentActions"; -import { saveSpamArchives } from "./saveSpamArchives"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError.js"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { LogType } from "../../../data/LogType.js"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { logger } from "../../../logger.js"; +import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin.js"; +import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin.js"; +import { MuteResult } from "../../../plugins/Mutes/types.js"; +import { DBDateFormat, convertDelayStringToMS, noop, resolveMember, trimLines } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { RecentActionType, SpamPluginType, TBaseSingleSpamConfig } from "../types.js"; +import { addRecentAction } from "./addRecentAction.js"; +import { clearRecentUserActions } from "./clearRecentUserActions.js"; +import { getRecentActionCount } from "./getRecentActionCount.js"; +import { getRecentActions } from "./getRecentActions.js"; +import { saveSpamArchives } from "./saveSpamArchives.js"; export async function logAndDetectMessageSpam( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts index 5b83c9a1..6f0a2744 100644 --- a/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts +++ b/backend/src/plugins/Spam/util/logAndDetectOtherSpam.ts @@ -1,14 +1,14 @@ import { GuildPluginData } from "knub"; -import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError"; -import { CaseTypes } from "../../../data/CaseTypes"; -import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin"; -import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin"; -import { convertDelayStringToMS, resolveMember } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { RecentActionType, SpamPluginType } from "../types"; -import { addRecentAction } from "./addRecentAction"; -import { clearRecentUserActions } from "./clearRecentUserActions"; -import { getRecentActionCount } from "./getRecentActionCount"; +import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError.js"; +import { CaseTypes } from "../../../data/CaseTypes.js"; +import { CasesPlugin } from "../../../plugins/Cases/CasesPlugin.js"; +import { MutesPlugin } from "../../../plugins/Mutes/MutesPlugin.js"; +import { convertDelayStringToMS, resolveMember } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { RecentActionType, SpamPluginType } from "../types.js"; +import { addRecentAction } from "./addRecentAction.js"; +import { clearRecentUserActions } from "./clearRecentUserActions.js"; +import { getRecentActionCount } from "./getRecentActionCount.js"; export async function logAndDetectOtherSpam( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Spam/util/logCensor.ts b/backend/src/plugins/Spam/util/logCensor.ts index 1b09c16e..13c024ef 100644 --- a/backend/src/plugins/Spam/util/logCensor.ts +++ b/backend/src/plugins/Spam/util/logCensor.ts @@ -1,8 +1,8 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { RecentActionType, SpamPluginType } from "../types"; -import { logAndDetectMessageSpam } from "./logAndDetectMessageSpam"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { RecentActionType, SpamPluginType } from "../types.js"; +import { logAndDetectMessageSpam } from "./logAndDetectMessageSpam.js"; export async function logCensor(pluginData: GuildPluginData, savedMessage: SavedMessage) { const member = pluginData.guild.members.cache.get(savedMessage.user_id as Snowflake); diff --git a/backend/src/plugins/Spam/util/onMessageCreate.ts b/backend/src/plugins/Spam/util/onMessageCreate.ts index 769fe50d..0a72de9c 100644 --- a/backend/src/plugins/Spam/util/onMessageCreate.ts +++ b/backend/src/plugins/Spam/util/onMessageCreate.ts @@ -1,9 +1,9 @@ import { Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils"; -import { RecentActionType, SpamPluginType } from "../types"; -import { logAndDetectMessageSpam } from "./logAndDetectMessageSpam"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { getEmojiInString, getRoleMentions, getUrlsInString, getUserMentions } from "../../../utils.js"; +import { RecentActionType, SpamPluginType } from "../types.js"; +import { logAndDetectMessageSpam } from "./logAndDetectMessageSpam.js"; export async function onMessageCreate(pluginData: GuildPluginData, savedMessage: SavedMessage) { if (savedMessage.is_bot) return; diff --git a/backend/src/plugins/Spam/util/saveSpamArchives.ts b/backend/src/plugins/Spam/util/saveSpamArchives.ts index d6d062a1..8e5b261e 100644 --- a/backend/src/plugins/Spam/util/saveSpamArchives.ts +++ b/backend/src/plugins/Spam/util/saveSpamArchives.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { getBaseUrl } from "../../../pluginUtils"; -import { SpamPluginType } from "../types"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { getBaseUrl } from "../../../pluginUtils.js"; +import { SpamPluginType } from "../types.js"; const SPAM_ARCHIVE_EXPIRY_DAYS = 90; diff --git a/backend/src/plugins/Starboard/StarboardPlugin.ts b/backend/src/plugins/Starboard/StarboardPlugin.ts index 37ac2397..474a2be2 100644 --- a/backend/src/plugins/Starboard/StarboardPlugin.ts +++ b/backend/src/plugins/Starboard/StarboardPlugin.ts @@ -1,13 +1,13 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { GuildStarboardMessages } from "../../data/GuildStarboardMessages"; -import { GuildStarboardReactions } from "../../data/GuildStarboardReactions"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { MigratePinsCmd } from "./commands/MigratePinsCmd"; -import { StarboardReactionAddEvt } from "./events/StarboardReactionAddEvt"; -import { StarboardReactionRemoveAllEvt, StarboardReactionRemoveEvt } from "./events/StarboardReactionRemoveEvts"; -import { StarboardPluginType, zStarboardConfig } from "./types"; -import { onMessageDelete } from "./util/onMessageDelete"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { GuildStarboardMessages } from "../../data/GuildStarboardMessages.js"; +import { GuildStarboardReactions } from "../../data/GuildStarboardReactions.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { MigratePinsCmd } from "./commands/MigratePinsCmd.js"; +import { StarboardReactionAddEvt } from "./events/StarboardReactionAddEvt.js"; +import { StarboardReactionRemoveAllEvt, StarboardReactionRemoveEvt } from "./events/StarboardReactionRemoveEvts.js"; +import { StarboardPluginType, zStarboardConfig } from "./types.js"; +import { onMessageDelete } from "./util/onMessageDelete.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts index 448ba465..f2971aa0 100644 --- a/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts +++ b/backend/src/plugins/Starboard/commands/MigratePinsCmd.ts @@ -1,7 +1,7 @@ import { Snowflake, TextChannel } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { starboardCmd } from "../types"; -import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { starboardCmd } from "../types.js"; +import { saveMessageToStarboard } from "../util/saveMessageToStarboard.js"; export const MigratePinsCmd = starboardCmd({ trigger: "starboard migrate_pins", diff --git a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts index 45b7e731..a8e761e8 100644 --- a/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts +++ b/backend/src/plugins/Starboard/events/StarboardReactionAddEvt.ts @@ -1,9 +1,9 @@ import { Message, Snowflake, TextChannel } from "discord.js"; -import { noop, resolveMember } from "../../../utils"; -import { allStarboardsLock } from "../../../utils/lockNameHelpers"; -import { starboardEvt } from "../types"; -import { saveMessageToStarboard } from "../util/saveMessageToStarboard"; -import { updateStarboardMessageStarCount } from "../util/updateStarboardMessageStarCount"; +import { noop, resolveMember } from "../../../utils.js"; +import { allStarboardsLock } from "../../../utils/lockNameHelpers.js"; +import { starboardEvt } from "../types.js"; +import { saveMessageToStarboard } from "../util/saveMessageToStarboard.js"; +import { updateStarboardMessageStarCount } from "../util/updateStarboardMessageStarCount.js"; export const StarboardReactionAddEvt = starboardEvt({ event: "messageReactionAdd", diff --git a/backend/src/plugins/Starboard/events/StarboardReactionRemoveEvts.ts b/backend/src/plugins/Starboard/events/StarboardReactionRemoveEvts.ts index 203c4bde..bb694620 100644 --- a/backend/src/plugins/Starboard/events/StarboardReactionRemoveEvts.ts +++ b/backend/src/plugins/Starboard/events/StarboardReactionRemoveEvts.ts @@ -1,5 +1,5 @@ -import { allStarboardsLock } from "../../../utils/lockNameHelpers"; -import { starboardEvt } from "../types"; +import { allStarboardsLock } from "../../../utils/lockNameHelpers.js"; +import { starboardEvt } from "../types.js"; export const StarboardReactionRemoveEvt = starboardEvt({ event: "messageReactionRemove", diff --git a/backend/src/plugins/Starboard/info.ts b/backend/src/plugins/Starboard/info.ts index fffe701f..bc51d961 100644 --- a/backend/src/plugins/Starboard/info.ts +++ b/backend/src/plugins/Starboard/info.ts @@ -1,6 +1,6 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; -import { zStarboardConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; +import { zStarboardConfig } from "./types.js"; export const starboardPluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/Starboard/types.ts b/backend/src/plugins/Starboard/types.ts index 2e625d5a..336cd297 100644 --- a/backend/src/plugins/Starboard/types.ts +++ b/backend/src/plugins/Starboard/types.ts @@ -1,10 +1,10 @@ import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { GuildStarboardMessages } from "../../data/GuildStarboardMessages"; -import { GuildStarboardReactions } from "../../data/GuildStarboardReactions"; -import { zBoundedRecord, zSnowflake } from "../../utils"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { GuildStarboardMessages } from "../../data/GuildStarboardMessages.js"; +import { GuildStarboardReactions } from "../../data/GuildStarboardReactions.js"; +import { zBoundedRecord, zSnowflake } from "../../utils.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; const zStarboardOpts = z.strictObject({ channel_id: zSnowflake, diff --git a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts index 93ba4dfd..91d4a52d 100644 --- a/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardEmbedFromMessage.ts @@ -1,6 +1,6 @@ import { GuildChannel, Message } from "discord.js"; import path from "path"; -import { EMPTY_CHAR, EmbedWith, renderUsername } from "../../../utils"; +import { EMPTY_CHAR, EmbedWith, renderUsername } from "../../../utils.js"; const imageAttachmentExtensions = ["jpeg", "jpg", "png", "gif", "webp"]; const audioAttachmentExtensions = ["wav", "mp3", "m4a"]; diff --git a/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts b/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts index 49d2cdde..913c5ff1 100644 --- a/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts +++ b/backend/src/plugins/Starboard/util/createStarboardPseudoFooterForMessage.ts @@ -1,6 +1,6 @@ import { EmbedField, Message } from "discord.js"; -import { EMPTY_CHAR, messageLink } from "../../../utils"; -import { TStarboardOpts } from "../types"; +import { EMPTY_CHAR, messageLink } from "../../../utils.js"; +import { TStarboardOpts } from "../types.js"; export function createStarboardPseudoFooterForMessage( starboard: TStarboardOpts, diff --git a/backend/src/plugins/Starboard/util/onMessageDelete.ts b/backend/src/plugins/Starboard/util/onMessageDelete.ts index fb6c7f2e..9c3ff0b1 100644 --- a/backend/src/plugins/Starboard/util/onMessageDelete.ts +++ b/backend/src/plugins/Starboard/util/onMessageDelete.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { StarboardPluginType } from "../types"; -import { removeMessageFromStarboard } from "./removeMessageFromStarboard"; -import { removeMessageFromStarboardMessages } from "./removeMessageFromStarboardMessages"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { StarboardPluginType } from "../types.js"; +import { removeMessageFromStarboard } from "./removeMessageFromStarboard.js"; +import { removeMessageFromStarboardMessages } from "./removeMessageFromStarboardMessages.js"; export async function onMessageDelete(pluginData: GuildPluginData, msg: SavedMessage) { // Deleted source message diff --git a/backend/src/plugins/Starboard/util/removeMessageFromStarboard.ts b/backend/src/plugins/Starboard/util/removeMessageFromStarboard.ts index cb62432e..d5cb68a7 100644 --- a/backend/src/plugins/Starboard/util/removeMessageFromStarboard.ts +++ b/backend/src/plugins/Starboard/util/removeMessageFromStarboard.ts @@ -1,8 +1,8 @@ import { ChannelType } from "discord.js"; import { GuildPluginData } from "knub"; -import { StarboardMessage } from "../../../data/entities/StarboardMessage"; -import { noop } from "../../../utils"; -import { StarboardPluginType } from "../types"; +import { StarboardMessage } from "../../../data/entities/StarboardMessage.js"; +import { noop } from "../../../utils.js"; +import { StarboardPluginType } from "../types.js"; export async function removeMessageFromStarboard( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Starboard/util/removeMessageFromStarboardMessages.ts b/backend/src/plugins/Starboard/util/removeMessageFromStarboardMessages.ts index 698b7b09..33f0206f 100644 --- a/backend/src/plugins/Starboard/util/removeMessageFromStarboardMessages.ts +++ b/backend/src/plugins/Starboard/util/removeMessageFromStarboardMessages.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { StarboardPluginType } from "../types"; +import { StarboardPluginType } from "../types.js"; export async function removeMessageFromStarboardMessages( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts index af614705..1f5c7c9e 100644 --- a/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts +++ b/backend/src/plugins/Starboard/util/saveMessageToStarboard.ts @@ -1,8 +1,8 @@ import { APIEmbed, Message, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { StarboardPluginType, TStarboardOpts } from "../types"; -import { createStarboardEmbedFromMessage } from "./createStarboardEmbedFromMessage"; -import { createStarboardPseudoFooterForMessage } from "./createStarboardPseudoFooterForMessage"; +import { StarboardPluginType, TStarboardOpts } from "../types.js"; +import { createStarboardEmbedFromMessage } from "./createStarboardEmbedFromMessage.js"; +import { createStarboardPseudoFooterForMessage } from "./createStarboardPseudoFooterForMessage.js"; export async function saveMessageToStarboard( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts b/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts index 04f6002c..0d313546 100644 --- a/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts +++ b/backend/src/plugins/Starboard/util/updateStarboardMessageStarCount.ts @@ -1,6 +1,6 @@ import { Message } from "discord.js"; -import { TStarboardOpts } from "../types"; -import { createStarboardPseudoFooterForMessage } from "./createStarboardPseudoFooterForMessage"; +import { TStarboardOpts } from "../types.js"; +import { createStarboardPseudoFooterForMessage } from "./createStarboardPseudoFooterForMessage.js"; import Timeout = NodeJS.Timeout; const DEBOUNCE_DELAY = 1000; diff --git a/backend/src/plugins/Tags/TagsPlugin.ts b/backend/src/plugins/Tags/TagsPlugin.ts index cf82440e..f1ded1d3 100644 --- a/backend/src/plugins/Tags/TagsPlugin.ts +++ b/backend/src/plugins/Tags/TagsPlugin.ts @@ -2,25 +2,25 @@ import { Snowflake } from "discord.js"; import humanizeDuration from "humanize-duration"; import { PluginOptions, guildPlugin } from "knub"; import moment from "moment-timezone"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { GuildTags } from "../../data/GuildTags"; -import { makePublicFn } from "../../pluginUtils"; -import { convertDelayStringToMS } from "../../utils"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { TagCreateCmd } from "./commands/TagCreateCmd"; -import { TagDeleteCmd } from "./commands/TagDeleteCmd"; -import { TagEvalCmd } from "./commands/TagEvalCmd"; -import { TagListCmd } from "./commands/TagListCmd"; -import { TagSourceCmd } from "./commands/TagSourceCmd"; -import { TagsPluginType, zTagsConfig } from "./types"; -import { findTagByName } from "./util/findTagByName"; -import { onMessageCreate } from "./util/onMessageCreate"; -import { onMessageDelete } from "./util/onMessageDelete"; -import { renderTagBody } from "./util/renderTagBody"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { GuildTags } from "../../data/GuildTags.js"; +import { makePublicFn } from "../../pluginUtils.js"; +import { convertDelayStringToMS } from "../../utils.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin.js"; +import { TagCreateCmd } from "./commands/TagCreateCmd.js"; +import { TagDeleteCmd } from "./commands/TagDeleteCmd.js"; +import { TagEvalCmd } from "./commands/TagEvalCmd.js"; +import { TagListCmd } from "./commands/TagListCmd.js"; +import { TagSourceCmd } from "./commands/TagSourceCmd.js"; +import { TagsPluginType, zTagsConfig } from "./types.js"; +import { findTagByName } from "./util/findTagByName.js"; +import { onMessageCreate } from "./util/onMessageCreate.js"; +import { onMessageDelete } from "./util/onMessageDelete.js"; +import { renderTagBody } from "./util/renderTagBody.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Tags/commands/TagCreateCmd.ts b/backend/src/plugins/Tags/commands/TagCreateCmd.ts index 872c63bd..c1a2d3cc 100644 --- a/backend/src/plugins/Tags/commands/TagCreateCmd.ts +++ b/backend/src/plugins/Tags/commands/TagCreateCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { TemplateParseError, parseTemplate } from "../../../templateFormatter"; -import { tagsCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { TemplateParseError, parseTemplate } from "../../../templateFormatter.js"; +import { tagsCmd } from "../types.js"; export const TagCreateCmd = tagsCmd({ trigger: "tag", diff --git a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts index 66913a5e..a0f1f0ea 100644 --- a/backend/src/plugins/Tags/commands/TagDeleteCmd.ts +++ b/backend/src/plugins/Tags/commands/TagDeleteCmd.ts @@ -1,5 +1,5 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { tagsCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { tagsCmd } from "../types.js"; export const TagDeleteCmd = tagsCmd({ trigger: "tag delete", diff --git a/backend/src/plugins/Tags/commands/TagEvalCmd.ts b/backend/src/plugins/Tags/commands/TagEvalCmd.ts index 3cc045e6..204f5e8c 100644 --- a/backend/src/plugins/Tags/commands/TagEvalCmd.ts +++ b/backend/src/plugins/Tags/commands/TagEvalCmd.ts @@ -1,10 +1,10 @@ import { MessageCreateOptions } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { logger } from "../../../logger"; -import { TemplateParseError } from "../../../templateFormatter"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { tagsCmd } from "../types"; -import { renderTagBody } from "../util/renderTagBody"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { logger } from "../../../logger.js"; +import { TemplateParseError } from "../../../templateFormatter.js"; +import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { tagsCmd } from "../types.js"; +import { renderTagBody } from "../util/renderTagBody.js"; export const TagEvalCmd = tagsCmd({ trigger: "tag eval", diff --git a/backend/src/plugins/Tags/commands/TagListCmd.ts b/backend/src/plugins/Tags/commands/TagListCmd.ts index 008a22a1..02132f95 100644 --- a/backend/src/plugins/Tags/commands/TagListCmd.ts +++ b/backend/src/plugins/Tags/commands/TagListCmd.ts @@ -1,7 +1,7 @@ import escapeStringRegexp from "escape-string-regexp"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { createChunkedMessage } from "../../../utils"; -import { tagsCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { createChunkedMessage } from "../../../utils.js"; +import { tagsCmd } from "../types.js"; export const TagListCmd = tagsCmd({ trigger: ["tag list", "tags", "taglist"], diff --git a/backend/src/plugins/Tags/commands/TagSourceCmd.ts b/backend/src/plugins/Tags/commands/TagSourceCmd.ts index 35be3515..92aaff68 100644 --- a/backend/src/plugins/Tags/commands/TagSourceCmd.ts +++ b/backend/src/plugins/Tags/commands/TagSourceCmd.ts @@ -1,7 +1,7 @@ import moment from "moment-timezone"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getBaseUrl } from "../../../pluginUtils"; -import { tagsCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { getBaseUrl } from "../../../pluginUtils.js"; +import { tagsCmd } from "../types.js"; export const TagSourceCmd = tagsCmd({ trigger: "tag", diff --git a/backend/src/plugins/Tags/info.ts b/backend/src/plugins/Tags/info.ts index 5f9c5fba..0b7b7b12 100644 --- a/backend/src/plugins/Tags/info.ts +++ b/backend/src/plugins/Tags/info.ts @@ -1,7 +1,7 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; -import { TemplateFunctions } from "./templateFunctions"; -import { TemplateFunction, zTagsConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; +import { TemplateFunctions } from "./templateFunctions.js"; +import { TemplateFunction, zTagsConfig } from "./types.js"; export const tagsPluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/Tags/templateFunctions.ts b/backend/src/plugins/Tags/templateFunctions.ts index 67a49069..4f50cd85 100644 --- a/backend/src/plugins/Tags/templateFunctions.ts +++ b/backend/src/plugins/Tags/templateFunctions.ts @@ -1,4 +1,4 @@ -import { TemplateFunction } from "./types"; +import { TemplateFunction } from "./types.js"; // TODO: Generate this dynamically, lmao export const TemplateFunctions: TemplateFunction[] = [ diff --git a/backend/src/plugins/Tags/types.ts b/backend/src/plugins/Tags/types.ts index c750edc8..6a730e75 100644 --- a/backend/src/plugins/Tags/types.ts +++ b/backend/src/plugins/Tags/types.ts @@ -1,11 +1,11 @@ import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { GuildTags } from "../../data/GuildTags"; -import { zBoundedCharacters, zStrictMessageContent } from "../../utils"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { GuildTags } from "../../data/GuildTags.js"; +import { zBoundedCharacters, zStrictMessageContent } from "../../utils.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zTag = z.union([zBoundedCharacters(0, 4000), zStrictMessageContent]); export type TTag = z.infer; diff --git a/backend/src/plugins/Tags/util/findTagByName.ts b/backend/src/plugins/Tags/util/findTagByName.ts index 98fafc3f..4184b2fd 100644 --- a/backend/src/plugins/Tags/util/findTagByName.ts +++ b/backend/src/plugins/Tags/util/findTagByName.ts @@ -1,5 +1,5 @@ import { ExtendedMatchParams, GuildPluginData } from "knub"; -import { TTag, TagsPluginType } from "../types"; +import { TTag, TagsPluginType } from "../types.js"; export async function findTagByName( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts index 8e90fe82..6b2fadc2 100644 --- a/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts +++ b/backend/src/plugins/Tags/util/matchAndRenderTagFromString.ts @@ -1,9 +1,9 @@ import { GuildMember } from "discord.js"; import escapeStringRegexp from "escape-string-regexp"; import { ExtendedMatchParams, GuildPluginData } from "knub"; -import { StrictMessageContent } from "../../../utils"; -import { TTagCategory, TagsPluginType } from "../types"; -import { renderTagFromString } from "./renderTagFromString"; +import { StrictMessageContent } from "../../../utils.js"; +import { TTagCategory, TagsPluginType } from "../types.js"; +import { renderTagFromString } from "./renderTagFromString.js"; interface BaseResult { renderedContent: StrictMessageContent; diff --git a/backend/src/plugins/Tags/util/onMessageCreate.ts b/backend/src/plugins/Tags/util/onMessageCreate.ts index f06d3282..89c8708d 100644 --- a/backend/src/plugins/Tags/util/onMessageCreate.ts +++ b/backend/src/plugins/Tags/util/onMessageCreate.ts @@ -1,12 +1,12 @@ import { Snowflake, TextChannel } from "discord.js"; import { GuildPluginData } from "knub"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { convertDelayStringToMS, resolveMember, zStrictMessageContent } from "../../../utils"; -import { erisAllowedMentionsToDjsMentionOptions } from "../../../utils/erisAllowedMentionsToDjsMentionOptions"; -import { messageIsEmpty } from "../../../utils/messageIsEmpty"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { TagsPluginType } from "../types"; -import { matchAndRenderTagFromString } from "./matchAndRenderTagFromString"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { convertDelayStringToMS, resolveMember, zStrictMessageContent } from "../../../utils.js"; +import { erisAllowedMentionsToDjsMentionOptions } from "../../../utils/erisAllowedMentionsToDjsMentionOptions.js"; +import { messageIsEmpty } from "../../../utils/messageIsEmpty.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { TagsPluginType } from "../types.js"; +import { matchAndRenderTagFromString } from "./matchAndRenderTagFromString.js"; export async function onMessageCreate(pluginData: GuildPluginData, msg: SavedMessage) { if (msg.is_bot) return; diff --git a/backend/src/plugins/Tags/util/onMessageDelete.ts b/backend/src/plugins/Tags/util/onMessageDelete.ts index cf0728eb..927b1261 100644 --- a/backend/src/plugins/Tags/util/onMessageDelete.ts +++ b/backend/src/plugins/Tags/util/onMessageDelete.ts @@ -1,5 +1,5 @@ import { guildPluginEventListener } from "knub"; -import { noop } from "../../../utils"; +import { noop } from "../../../utils.js"; export const onMessageDelete = guildPluginEventListener({ event: "messageDelete", diff --git a/backend/src/plugins/Tags/util/renderTagBody.ts b/backend/src/plugins/Tags/util/renderTagBody.ts index e75a12cf..4298580b 100644 --- a/backend/src/plugins/Tags/util/renderTagBody.ts +++ b/backend/src/plugins/Tags/util/renderTagBody.ts @@ -1,8 +1,8 @@ import { ExtendedMatchParams, GuildPluginData } from "knub"; -import { TemplateSafeValue, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; -import { StrictMessageContent, renderRecursively } from "../../../utils"; -import { TTag, TagsPluginType } from "../types"; -import { findTagByName } from "./findTagByName"; +import { TemplateSafeValue, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter.js"; +import { StrictMessageContent, renderRecursively } from "../../../utils.js"; +import { TTag, TagsPluginType } from "../types.js"; +import { findTagByName } from "./findTagByName.js"; const MAX_TAG_FN_CALLS = 25; diff --git a/backend/src/plugins/Tags/util/renderTagFromString.ts b/backend/src/plugins/Tags/util/renderTagFromString.ts index 10306777..24f0e19b 100644 --- a/backend/src/plugins/Tags/util/renderTagFromString.ts +++ b/backend/src/plugins/Tags/util/renderTagFromString.ts @@ -1,13 +1,13 @@ import { GuildMember } from "discord.js"; import { GuildPluginData } from "knub"; import { parseArguments } from "knub-command-manager"; -import { logger } from "../../../logger"; -import { TemplateParseError } from "../../../templateFormatter"; -import { StrictMessageContent, validateAndParseMessageContent } from "../../../utils"; -import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { TTag, TagsPluginType } from "../types"; -import { renderTagBody } from "./renderTagBody"; +import { logger } from "../../../logger.js"; +import { TemplateParseError } from "../../../templateFormatter.js"; +import { StrictMessageContent, validateAndParseMessageContent } from "../../../utils.js"; +import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { TTag, TagsPluginType } from "../types.js"; +import { renderTagBody } from "./renderTagBody.js"; export async function renderTagFromString( pluginData: GuildPluginData, diff --git a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts index daeaa2ad..7de26655 100644 --- a/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts +++ b/backend/src/plugins/TimeAndDate/TimeAndDatePlugin.ts @@ -1,17 +1,17 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildMemberTimezones } from "../../data/GuildMemberTimezones"; -import { makePublicFn } from "../../pluginUtils"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { ResetTimezoneCmd } from "./commands/ResetTimezoneCmd"; -import { SetTimezoneCmd } from "./commands/SetTimezoneCmd"; -import { ViewTimezoneCmd } from "./commands/ViewTimezoneCmd"; -import { defaultDateFormats } from "./defaultDateFormats"; -import { getDateFormat } from "./functions/getDateFormat"; -import { getGuildTz } from "./functions/getGuildTz"; -import { getMemberTz } from "./functions/getMemberTz"; -import { inGuildTz } from "./functions/inGuildTz"; -import { inMemberTz } from "./functions/inMemberTz"; -import { TimeAndDatePluginType, zTimeAndDateConfig } from "./types"; +import { GuildMemberTimezones } from "../../data/GuildMemberTimezones.js"; +import { makePublicFn } from "../../pluginUtils.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { ResetTimezoneCmd } from "./commands/ResetTimezoneCmd.js"; +import { SetTimezoneCmd } from "./commands/SetTimezoneCmd.js"; +import { ViewTimezoneCmd } from "./commands/ViewTimezoneCmd.js"; +import { defaultDateFormats } from "./defaultDateFormats.js"; +import { getDateFormat } from "./functions/getDateFormat.js"; +import { getGuildTz } from "./functions/getGuildTz.js"; +import { getMemberTz } from "./functions/getMemberTz.js"; +import { inGuildTz } from "./functions/inGuildTz.js"; +import { inMemberTz } from "./functions/inMemberTz.js"; +import { TimeAndDatePluginType, zTimeAndDateConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts index 1a9c1daf..fa5a41a0 100644 --- a/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/ResetTimezoneCmd.ts @@ -1,5 +1,5 @@ -import { getGuildTz } from "../functions/getGuildTz"; -import { timeAndDateCmd } from "../types"; +import { getGuildTz } from "../functions/getGuildTz.js"; +import { timeAndDateCmd } from "../types.js"; export const ResetTimezoneCmd = timeAndDateCmd({ trigger: "timezone reset", diff --git a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts index 092edadc..f15546e5 100644 --- a/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/SetTimezoneCmd.ts @@ -1,8 +1,8 @@ import { escapeInlineCode } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { trimLines } from "../../../utils"; -import { parseFuzzyTimezone } from "../../../utils/parseFuzzyTimezone"; -import { timeAndDateCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { trimLines } from "../../../utils.js"; +import { parseFuzzyTimezone } from "../../../utils/parseFuzzyTimezone.js"; +import { timeAndDateCmd } from "../types.js"; export const SetTimezoneCmd = timeAndDateCmd({ trigger: "timezone", diff --git a/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts b/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts index 86585abd..62f12a69 100644 --- a/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts +++ b/backend/src/plugins/TimeAndDate/commands/ViewTimezoneCmd.ts @@ -1,5 +1,5 @@ -import { getGuildTz } from "../functions/getGuildTz"; -import { timeAndDateCmd } from "../types"; +import { getGuildTz } from "../functions/getGuildTz.js"; +import { timeAndDateCmd } from "../types.js"; export const ViewTimezoneCmd = timeAndDateCmd({ trigger: "timezone", diff --git a/backend/src/plugins/TimeAndDate/functions/getDateFormat.ts b/backend/src/plugins/TimeAndDate/functions/getDateFormat.ts index d420ab26..13290bcf 100644 --- a/backend/src/plugins/TimeAndDate/functions/getDateFormat.ts +++ b/backend/src/plugins/TimeAndDate/functions/getDateFormat.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { defaultDateFormats } from "../defaultDateFormats"; -import { TimeAndDatePluginType } from "../types"; +import { defaultDateFormats } from "../defaultDateFormats.js"; +import { TimeAndDatePluginType } from "../types.js"; export function getDateFormat( pluginData: GuildPluginData, diff --git a/backend/src/plugins/TimeAndDate/functions/getGuildTz.ts b/backend/src/plugins/TimeAndDate/functions/getGuildTz.ts index 922c7c88..a29074f5 100644 --- a/backend/src/plugins/TimeAndDate/functions/getGuildTz.ts +++ b/backend/src/plugins/TimeAndDate/functions/getGuildTz.ts @@ -1,5 +1,5 @@ import { GuildPluginData } from "knub"; -import { TimeAndDatePluginType } from "../types"; +import { TimeAndDatePluginType } from "../types.js"; export function getGuildTz(pluginData: GuildPluginData) { return pluginData.config.get().timezone; diff --git a/backend/src/plugins/TimeAndDate/functions/getMemberTz.ts b/backend/src/plugins/TimeAndDate/functions/getMemberTz.ts index 8194a5ba..9363a1a2 100644 --- a/backend/src/plugins/TimeAndDate/functions/getMemberTz.ts +++ b/backend/src/plugins/TimeAndDate/functions/getMemberTz.ts @@ -1,6 +1,6 @@ import { GuildPluginData } from "knub"; -import { TimeAndDatePluginType } from "../types"; -import { getGuildTz } from "./getGuildTz"; +import { TimeAndDatePluginType } from "../types.js"; +import { getGuildTz } from "./getGuildTz.js"; export async function getMemberTz(pluginData: GuildPluginData, memberId: string) { const memberTz = await pluginData.state.memberTimezones.get(memberId); diff --git a/backend/src/plugins/TimeAndDate/functions/inGuildTz.ts b/backend/src/plugins/TimeAndDate/functions/inGuildTz.ts index d19a6d68..1b17fba1 100644 --- a/backend/src/plugins/TimeAndDate/functions/inGuildTz.ts +++ b/backend/src/plugins/TimeAndDate/functions/inGuildTz.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { TimeAndDatePluginType } from "../types"; -import { getGuildTz } from "./getGuildTz"; +import { TimeAndDatePluginType } from "../types.js"; +import { getGuildTz } from "./getGuildTz.js"; export function inGuildTz(pluginData: GuildPluginData, input?: moment.Moment | number) { let momentObj: moment.Moment; diff --git a/backend/src/plugins/TimeAndDate/functions/inMemberTz.ts b/backend/src/plugins/TimeAndDate/functions/inMemberTz.ts index 37ec7ca3..16682ef5 100644 --- a/backend/src/plugins/TimeAndDate/functions/inMemberTz.ts +++ b/backend/src/plugins/TimeAndDate/functions/inMemberTz.ts @@ -1,7 +1,7 @@ import { GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { TimeAndDatePluginType } from "../types"; -import { getMemberTz } from "./getMemberTz"; +import { TimeAndDatePluginType } from "../types.js"; +import { getMemberTz } from "./getMemberTz.js"; export async function inMemberTz( pluginData: GuildPluginData, diff --git a/backend/src/plugins/TimeAndDate/info.ts b/backend/src/plugins/TimeAndDate/info.ts index 22441d32..3ce217e6 100644 --- a/backend/src/plugins/TimeAndDate/info.ts +++ b/backend/src/plugins/TimeAndDate/info.ts @@ -1,6 +1,6 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { trimPluginDescription } from "../../utils"; -import { zTimeAndDateConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { trimPluginDescription } from "../../utils.js"; +import { zTimeAndDateConfig } from "./types.js"; export const timeAndDatePluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/TimeAndDate/types.ts b/backend/src/plugins/TimeAndDate/types.ts index 1890e3d4..bcdc4b09 100644 --- a/backend/src/plugins/TimeAndDate/types.ts +++ b/backend/src/plugins/TimeAndDate/types.ts @@ -1,11 +1,11 @@ import { BasePluginType, guildPluginMessageCommand, pluginUtils } from "knub"; import { U } from "ts-toolbelt"; import z from "zod"; -import { GuildMemberTimezones } from "../../data/GuildMemberTimezones"; -import { keys } from "../../utils"; -import { zValidTimezone } from "../../utils/zValidTimezone"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { defaultDateFormats } from "./defaultDateFormats"; +import { GuildMemberTimezones } from "../../data/GuildMemberTimezones.js"; +import { keys } from "../../utils.js"; +import { zValidTimezone } from "../../utils/zValidTimezone.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { defaultDateFormats } from "./defaultDateFormats.js"; const zDateFormatKeys = z.enum(keys(defaultDateFormats) as U.ListOf); diff --git a/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts b/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts index b731bd27..fe38fd13 100644 --- a/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts +++ b/backend/src/plugins/UsernameSaver/UsernameSaverPlugin.ts @@ -1,8 +1,8 @@ import { guildPlugin } from "knub"; -import { Queue } from "../../Queue"; -import { UsernameHistory } from "../../data/UsernameHistory"; -import { MessageCreateUpdateUsernameEvt, VoiceChannelJoinUpdateUsernameEvt } from "./events/UpdateUsernameEvts"; -import { UsernameSaverPluginType, zUsernameSaverConfig } from "./types"; +import { Queue } from "../../Queue.js"; +import { UsernameHistory } from "../../data/UsernameHistory.js"; +import { MessageCreateUpdateUsernameEvt, VoiceChannelJoinUpdateUsernameEvt } from "./events/UpdateUsernameEvts.js"; +import { UsernameSaverPluginType, zUsernameSaverConfig } from "./types.js"; export const UsernameSaverPlugin = guildPlugin()({ name: "username_saver", diff --git a/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts b/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts index 093dbce7..805b8a73 100644 --- a/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts +++ b/backend/src/plugins/UsernameSaver/events/UpdateUsernameEvts.ts @@ -1,5 +1,5 @@ -import { usernameSaverEvt } from "../types"; -import { updateUsername } from "../updateUsername"; +import { usernameSaverEvt } from "../types.js"; +import { updateUsername } from "../updateUsername.js"; export const MessageCreateUpdateUsernameEvt = usernameSaverEvt({ event: "messageCreate", diff --git a/backend/src/plugins/UsernameSaver/info.ts b/backend/src/plugins/UsernameSaver/info.ts index 4a9b5bba..7f9afb5f 100644 --- a/backend/src/plugins/UsernameSaver/info.ts +++ b/backend/src/plugins/UsernameSaver/info.ts @@ -1,4 +1,4 @@ -import { ZeppelinPluginInfo } from "../../types"; +import { ZeppelinPluginInfo } from "../../types.js"; export const usernameSaverPluginInfo: ZeppelinPluginInfo = { showInDocs: false, diff --git a/backend/src/plugins/UsernameSaver/types.ts b/backend/src/plugins/UsernameSaver/types.ts index 16d6e342..4828db6e 100644 --- a/backend/src/plugins/UsernameSaver/types.ts +++ b/backend/src/plugins/UsernameSaver/types.ts @@ -1,7 +1,7 @@ import { BasePluginType, guildPluginEventListener } from "knub"; import z from "zod"; -import { Queue } from "../../Queue"; -import { UsernameHistory } from "../../data/UsernameHistory"; +import { Queue } from "../../Queue.js"; +import { UsernameHistory } from "../../data/UsernameHistory.js"; export const zUsernameSaverConfig = z.strictObject({}); diff --git a/backend/src/plugins/UsernameSaver/updateUsername.ts b/backend/src/plugins/UsernameSaver/updateUsername.ts index ed0fb73f..f067f168 100644 --- a/backend/src/plugins/UsernameSaver/updateUsername.ts +++ b/backend/src/plugins/UsernameSaver/updateUsername.ts @@ -1,7 +1,7 @@ import { User } from "discord.js"; import { GuildPluginData } from "knub"; -import { renderUsername } from "../../utils"; -import { UsernameSaverPluginType } from "./types"; +import { renderUsername } from "../../utils.js"; +import { UsernameSaverPluginType } from "./types.js"; export async function updateUsername(pluginData: GuildPluginData, user: User) { if (!user) return; diff --git a/backend/src/plugins/Utility/UtilityPlugin.ts b/backend/src/plugins/Utility/UtilityPlugin.ts index bd35837e..3fa32e72 100644 --- a/backend/src/plugins/Utility/UtilityPlugin.ts +++ b/backend/src/plugins/Utility/UtilityPlugin.ts @@ -1,48 +1,48 @@ import { Snowflake } from "discord.js"; import { PluginOptions, guildPlugin } from "knub"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildCases } from "../../data/GuildCases"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { Supporters } from "../../data/Supporters"; -import { makePublicFn } from "../../pluginUtils"; -import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners"; -import { CommonPlugin } from "../Common/CommonPlugin"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { ModActionsPlugin } from "../ModActions/ModActionsPlugin"; -import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; -import { AboutCmd } from "./commands/AboutCmd"; -import { AvatarCmd } from "./commands/AvatarCmd"; -import { BanSearchCmd } from "./commands/BanSearchCmd"; -import { ChannelInfoCmd } from "./commands/ChannelInfoCmd"; -import { CleanCmd, cleanCmd } from "./commands/CleanCmd"; -import { ContextCmd } from "./commands/ContextCmd"; -import { EmojiInfoCmd } from "./commands/EmojiInfoCmd"; -import { HelpCmd } from "./commands/HelpCmd"; -import { InfoCmd } from "./commands/InfoCmd"; -import { InviteInfoCmd } from "./commands/InviteInfoCmd"; -import { JumboCmd } from "./commands/JumboCmd"; -import { LevelCmd } from "./commands/LevelCmd"; -import { MessageInfoCmd } from "./commands/MessageInfoCmd"; -import { NicknameCmd } from "./commands/NicknameCmd"; -import { NicknameResetCmd } from "./commands/NicknameResetCmd"; -import { PingCmd } from "./commands/PingCmd"; -import { ReloadGuildCmd } from "./commands/ReloadGuildCmd"; -import { RoleInfoCmd } from "./commands/RoleInfoCmd"; -import { RolesCmd } from "./commands/RolesCmd"; -import { SearchCmd } from "./commands/SearchCmd"; -import { ServerInfoCmd } from "./commands/ServerInfoCmd"; -import { SnowflakeInfoCmd } from "./commands/SnowflakeInfoCmd"; -import { SourceCmd } from "./commands/SourceCmd"; -import { UserInfoCmd } from "./commands/UserInfoCmd"; -import { VcdisconnectCmd } from "./commands/VcdisconnectCmd"; -import { VcmoveAllCmd, VcmoveCmd } from "./commands/VcmoveCmd"; -import { AutoJoinThreadEvt, AutoJoinThreadSyncEvt } from "./events/AutoJoinThreadEvt"; -import { getUserInfoEmbed } from "./functions/getUserInfoEmbed"; -import { hasPermission } from "./functions/hasPermission"; -import { activeReloads } from "./guildReloads"; -import { refreshMembersIfNeeded } from "./refreshMembers"; -import { UtilityPluginType, zUtilityConfig } from "./types"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildCases } from "../../data/GuildCases.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { Supporters } from "../../data/Supporters.js"; +import { makePublicFn } from "../../pluginUtils.js"; +import { discardRegExpRunner, getRegExpRunner } from "../../regExpRunners.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { ModActionsPlugin } from "../ModActions/ModActionsPlugin.js"; +import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin.js"; +import { AboutCmd } from "./commands/AboutCmd.js"; +import { AvatarCmd } from "./commands/AvatarCmd.js"; +import { BanSearchCmd } from "./commands/BanSearchCmd.js"; +import { ChannelInfoCmd } from "./commands/ChannelInfoCmd.js"; +import { CleanCmd, cleanCmd } from "./commands/CleanCmd.js"; +import { ContextCmd } from "./commands/ContextCmd.js"; +import { EmojiInfoCmd } from "./commands/EmojiInfoCmd.js"; +import { HelpCmd } from "./commands/HelpCmd.js"; +import { InfoCmd } from "./commands/InfoCmd.js"; +import { InviteInfoCmd } from "./commands/InviteInfoCmd.js"; +import { JumboCmd } from "./commands/JumboCmd.js"; +import { LevelCmd } from "./commands/LevelCmd.js"; +import { MessageInfoCmd } from "./commands/MessageInfoCmd.js"; +import { NicknameCmd } from "./commands/NicknameCmd.js"; +import { NicknameResetCmd } from "./commands/NicknameResetCmd.js"; +import { PingCmd } from "./commands/PingCmd.js"; +import { ReloadGuildCmd } from "./commands/ReloadGuildCmd.js"; +import { RoleInfoCmd } from "./commands/RoleInfoCmd.js"; +import { RolesCmd } from "./commands/RolesCmd.js"; +import { SearchCmd } from "./commands/SearchCmd.js"; +import { ServerInfoCmd } from "./commands/ServerInfoCmd.js"; +import { SnowflakeInfoCmd } from "./commands/SnowflakeInfoCmd.js"; +import { SourceCmd } from "./commands/SourceCmd.js"; +import { UserInfoCmd } from "./commands/UserInfoCmd.js"; +import { VcdisconnectCmd } from "./commands/VcdisconnectCmd.js"; +import { VcmoveAllCmd, VcmoveCmd } from "./commands/VcmoveCmd.js"; +import { AutoJoinThreadEvt, AutoJoinThreadSyncEvt } from "./events/AutoJoinThreadEvt.js"; +import { getUserInfoEmbed } from "./functions/getUserInfoEmbed.js"; +import { hasPermission } from "./functions/hasPermission.js"; +import { activeReloads } from "./guildReloads.js"; +import { refreshMembersIfNeeded } from "./refreshMembers.js"; +import { UtilityPluginType, zUtilityConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/Utility/commands/AboutCmd.ts b/backend/src/plugins/Utility/commands/AboutCmd.ts index d4188ad7..e31eb19a 100644 --- a/backend/src/plugins/Utility/commands/AboutCmd.ts +++ b/backend/src/plugins/Utility/commands/AboutCmd.ts @@ -3,11 +3,11 @@ import humanizeDuration from "humanize-duration"; import LCL from "last-commit-log"; import { shuffle } from "lodash"; import moment from "moment-timezone"; -import { rootDir } from "../../../paths"; -import { getCurrentUptime } from "../../../uptime"; -import { resolveMember, sorter } from "../../../utils"; -import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; -import { utilityCmd } from "../types"; +import { rootDir } from "../../../paths.js"; +import { getCurrentUptime } from "../../../uptime.js"; +import { resolveMember, sorter } from "../../../utils.js"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js"; +import { utilityCmd } from "../types.js"; export const AboutCmd = utilityCmd({ trigger: "about", diff --git a/backend/src/plugins/Utility/commands/AvatarCmd.ts b/backend/src/plugins/Utility/commands/AvatarCmd.ts index 4fb146e7..a4c13f85 100644 --- a/backend/src/plugins/Utility/commands/AvatarCmd.ts +++ b/backend/src/plugins/Utility/commands/AvatarCmd.ts @@ -1,7 +1,7 @@ import { APIEmbed, ImageFormat } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { UnknownUser, renderUsername } from "../../../utils"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { UnknownUser, renderUsername } from "../../../utils.js"; +import { utilityCmd } from "../types.js"; export const AvatarCmd = utilityCmd({ trigger: ["avatar", "av"], diff --git a/backend/src/plugins/Utility/commands/BanSearchCmd.ts b/backend/src/plugins/Utility/commands/BanSearchCmd.ts index 25d60fb4..eb8051bc 100644 --- a/backend/src/plugins/Utility/commands/BanSearchCmd.ts +++ b/backend/src/plugins/Utility/commands/BanSearchCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { archiveSearch, displaySearch, SearchType } from "../search"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { archiveSearch, displaySearch, SearchType } from "../search.js"; +import { utilityCmd } from "../types.js"; // Separate from BanSearchCmd to avoid a circular reference from ./search.ts export const banSearchSignature = { diff --git a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts index d39d5364..f3e718fe 100644 --- a/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ChannelInfoCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed.js"; +import { utilityCmd } from "../types.js"; export const ChannelInfoCmd = utilityCmd({ trigger: ["channel", "channelinfo"], diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index fb06f689..db8553d3 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -1,15 +1,15 @@ import { Message, ModalSubmitInteraction, Snowflake, TextChannel, User } from "discord.js"; import { GuildPluginData } from "knub"; -import { allowTimeout } from "../../../RegExpRunner"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { LogType } from "../../../data/LogType"; -import { SavedMessage } from "../../../data/entities/SavedMessage"; -import { humanizeDurationShort } from "../../../humanizeDurationShort"; -import { getBaseUrl } from "../../../pluginUtils"; -import { ModActionsPlugin } from "../../../plugins/ModActions/ModActionsPlugin"; -import { DAYS, SECONDS, chunkArray, getInviteCodesInString, noop } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { UtilityPluginType, utilityCmd } from "../types"; +import { allowTimeout } from "../../../RegExpRunner.js"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { LogType } from "../../../data/LogType.js"; +import { SavedMessage } from "../../../data/entities/SavedMessage.js"; +import { humanizeDurationShort } from "../../../humanizeDurationShort.js"; +import { getBaseUrl } from "../../../pluginUtils.js"; +import { ModActionsPlugin } from "../../../plugins/ModActions/ModActionsPlugin.js"; +import { DAYS, SECONDS, chunkArray, getInviteCodesInString, noop } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { UtilityPluginType, utilityCmd } from "../types.js"; const MAX_CLEAN_COUNT = 300; const MAX_CLEAN_TIME = 1 * DAYS; diff --git a/backend/src/plugins/Utility/commands/ContextCmd.ts b/backend/src/plugins/Utility/commands/ContextCmd.ts index 0bbb8d68..295116ec 100644 --- a/backend/src/plugins/Utility/commands/ContextCmd.ts +++ b/backend/src/plugins/Utility/commands/ContextCmd.ts @@ -1,8 +1,8 @@ import { Snowflake, TextChannel } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { messageLink } from "../../../utils"; -import { canReadChannel } from "../../../utils/canReadChannel"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { messageLink } from "../../../utils.js"; +import { canReadChannel } from "../../../utils/canReadChannel.js"; +import { utilityCmd } from "../types.js"; export const ContextCmd = utilityCmd({ trigger: "context", diff --git a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts index ff1a8fa7..7c079e3f 100644 --- a/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/EmojiInfoCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getCustomEmojiId } from "../functions/getCustomEmojiId"; -import { getEmojiInfoEmbed } from "../functions/getEmojiInfoEmbed"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { getCustomEmojiId } from "../functions/getCustomEmojiId.js"; +import { getEmojiInfoEmbed } from "../functions/getEmojiInfoEmbed.js"; +import { utilityCmd } from "../types.js"; export const EmojiInfoCmd = utilityCmd({ trigger: ["emoji", "emojiinfo"], diff --git a/backend/src/plugins/Utility/commands/HelpCmd.ts b/backend/src/plugins/Utility/commands/HelpCmd.ts index 7e3391fd..a1be304b 100644 --- a/backend/src/plugins/Utility/commands/HelpCmd.ts +++ b/backend/src/plugins/Utility/commands/HelpCmd.ts @@ -1,7 +1,7 @@ import { LoadedGuildPlugin, PluginCommandDefinition } from "knub"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { createChunkedMessage } from "../../../utils"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { createChunkedMessage } from "../../../utils.js"; +import { utilityCmd } from "../types.js"; export const HelpCmd = utilityCmd({ trigger: "help", diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index 75f12197..f286de40 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -1,20 +1,20 @@ import { Snowflake } from "discord.js"; import { getChannelId, getRoleId } from "knub/helpers"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { isValidSnowflake, noop, parseInviteCodeInput, resolveInvite, resolveUser } from "../../../utils"; -import { canReadChannel } from "../../../utils/canReadChannel"; -import { resolveMessageTarget } from "../../../utils/resolveMessageTarget"; -import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed"; -import { getCustomEmojiId } from "../functions/getCustomEmojiId"; -import { getEmojiInfoEmbed } from "../functions/getEmojiInfoEmbed"; -import { getGuildPreview } from "../functions/getGuildPreview"; -import { getInviteInfoEmbed } from "../functions/getInviteInfoEmbed"; -import { getMessageInfoEmbed } from "../functions/getMessageInfoEmbed"; -import { getRoleInfoEmbed } from "../functions/getRoleInfoEmbed"; -import { getServerInfoEmbed } from "../functions/getServerInfoEmbed"; -import { getSnowflakeInfoEmbed } from "../functions/getSnowflakeInfoEmbed"; -import { getUserInfoEmbed } from "../functions/getUserInfoEmbed"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { isValidSnowflake, noop, parseInviteCodeInput, resolveInvite, resolveUser } from "../../../utils.js"; +import { canReadChannel } from "../../../utils/canReadChannel.js"; +import { resolveMessageTarget } from "../../../utils/resolveMessageTarget.js"; +import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed.js"; +import { getCustomEmojiId } from "../functions/getCustomEmojiId.js"; +import { getEmojiInfoEmbed } from "../functions/getEmojiInfoEmbed.js"; +import { getGuildPreview } from "../functions/getGuildPreview.js"; +import { getInviteInfoEmbed } from "../functions/getInviteInfoEmbed.js"; +import { getMessageInfoEmbed } from "../functions/getMessageInfoEmbed.js"; +import { getRoleInfoEmbed } from "../functions/getRoleInfoEmbed.js"; +import { getServerInfoEmbed } from "../functions/getServerInfoEmbed.js"; +import { getSnowflakeInfoEmbed } from "../functions/getSnowflakeInfoEmbed.js"; +import { getUserInfoEmbed } from "../functions/getUserInfoEmbed.js"; +import { utilityCmd } from "../types.js"; export const InfoCmd = utilityCmd({ trigger: "info", diff --git a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts index 37d8493b..e553b6b5 100644 --- a/backend/src/plugins/Utility/commands/InviteInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InviteInfoCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { parseInviteCodeInput } from "../../../utils"; -import { getInviteInfoEmbed } from "../functions/getInviteInfoEmbed"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { parseInviteCodeInput } from "../../../utils.js"; +import { getInviteInfoEmbed } from "../functions/getInviteInfoEmbed.js"; +import { utilityCmd } from "../types.js"; export const InviteInfoCmd = utilityCmd({ trigger: ["invite", "inviteinfo"], diff --git a/backend/src/plugins/Utility/commands/JumboCmd.ts b/backend/src/plugins/Utility/commands/JumboCmd.ts index 11d42a04..6a693d3f 100644 --- a/backend/src/plugins/Utility/commands/JumboCmd.ts +++ b/backend/src/plugins/Utility/commands/JumboCmd.ts @@ -2,9 +2,9 @@ import photon from "@silvia-odwyer/photon-node"; import { AttachmentBuilder } from "discord.js"; import fs from "fs"; import twemoji from "twemoji"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { downloadFile, isEmoji, SECONDS } from "../../../utils"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { downloadFile, isEmoji, SECONDS } from "../../../utils.js"; +import { utilityCmd } from "../types.js"; const fsp = fs.promises; diff --git a/backend/src/plugins/Utility/commands/LevelCmd.ts b/backend/src/plugins/Utility/commands/LevelCmd.ts index 5830f66a..9542dd8b 100644 --- a/backend/src/plugins/Utility/commands/LevelCmd.ts +++ b/backend/src/plugins/Utility/commands/LevelCmd.ts @@ -1,7 +1,7 @@ import { helpers } from "knub"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { renderUsername } from "../../../utils"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { renderUsername } from "../../../utils.js"; +import { utilityCmd } from "../types.js"; const { getMemberLevel } = helpers; diff --git a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts index 1b4496b8..8abff0f1 100644 --- a/backend/src/plugins/Utility/commands/MessageInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/MessageInfoCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canReadChannel } from "../../../utils/canReadChannel"; -import { getMessageInfoEmbed } from "../functions/getMessageInfoEmbed"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { canReadChannel } from "../../../utils/canReadChannel.js"; +import { getMessageInfoEmbed } from "../functions/getMessageInfoEmbed.js"; +import { utilityCmd } from "../types.js"; export const MessageInfoCmd = utilityCmd({ trigger: ["message", "messageinfo"], diff --git a/backend/src/plugins/Utility/commands/NicknameCmd.ts b/backend/src/plugins/Utility/commands/NicknameCmd.ts index ec274703..8c00f784 100644 --- a/backend/src/plugins/Utility/commands/NicknameCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameCmd.ts @@ -1,8 +1,8 @@ import { escapeBold } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn } from "../../../pluginUtils"; -import { errorMessage } from "../../../utils"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { canActOn } from "../../../pluginUtils.js"; +import { errorMessage } from "../../../utils.js"; +import { utilityCmd } from "../types.js"; export const NicknameCmd = utilityCmd({ trigger: ["nickname", "nick"], diff --git a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts index 34ae2cbb..df4d89c3 100644 --- a/backend/src/plugins/Utility/commands/NicknameResetCmd.ts +++ b/backend/src/plugins/Utility/commands/NicknameResetCmd.ts @@ -1,7 +1,7 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn } from "../../../pluginUtils"; -import { errorMessage } from "../../../utils"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { canActOn } from "../../../pluginUtils.js"; +import { errorMessage } from "../../../utils.js"; +import { utilityCmd } from "../types.js"; export const NicknameResetCmd = utilityCmd({ trigger: ["nickname reset", "nick reset"], diff --git a/backend/src/plugins/Utility/commands/PingCmd.ts b/backend/src/plugins/Utility/commands/PingCmd.ts index 0777cdc9..e41665eb 100644 --- a/backend/src/plugins/Utility/commands/PingCmd.ts +++ b/backend/src/plugins/Utility/commands/PingCmd.ts @@ -1,7 +1,7 @@ import { Message } from "discord.js"; import { performance } from "perf_hooks"; -import { noop, trimLines } from "../../../utils"; -import { utilityCmd } from "../types"; +import { noop, trimLines } from "../../../utils.js"; +import { utilityCmd } from "../types.js"; export const PingCmd = utilityCmd({ trigger: ["ping", "pong"], diff --git a/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts b/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts index 2b8b2f32..3c00eda7 100644 --- a/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts +++ b/backend/src/plugins/Utility/commands/ReloadGuildCmd.ts @@ -1,6 +1,6 @@ import { TextChannel } from "discord.js"; -import { activeReloads } from "../guildReloads"; -import { utilityCmd } from "../types"; +import { activeReloads } from "../guildReloads.js"; +import { utilityCmd } from "../types.js"; export const ReloadGuildCmd = utilityCmd({ trigger: "reload_guild", diff --git a/backend/src/plugins/Utility/commands/RoleInfoCmd.ts b/backend/src/plugins/Utility/commands/RoleInfoCmd.ts index 6f540b4b..76070deb 100644 --- a/backend/src/plugins/Utility/commands/RoleInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/RoleInfoCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getRoleInfoEmbed } from "../functions/getRoleInfoEmbed"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { getRoleInfoEmbed } from "../functions/getRoleInfoEmbed.js"; +import { utilityCmd } from "../types.js"; export const RoleInfoCmd = utilityCmd({ trigger: ["roleinfo"], diff --git a/backend/src/plugins/Utility/commands/RolesCmd.ts b/backend/src/plugins/Utility/commands/RolesCmd.ts index a9d9dc1d..e9fb5f75 100644 --- a/backend/src/plugins/Utility/commands/RolesCmd.ts +++ b/backend/src/plugins/Utility/commands/RolesCmd.ts @@ -1,8 +1,8 @@ import { Role } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { chunkArray, sorter, trimLines } from "../../../utils"; -import { refreshMembersIfNeeded } from "../refreshMembers"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { chunkArray, sorter, trimLines } from "../../../utils.js"; +import { refreshMembersIfNeeded } from "../refreshMembers.js"; +import { utilityCmd } from "../types.js"; export const RolesCmd = utilityCmd({ trigger: "roles", diff --git a/backend/src/plugins/Utility/commands/SearchCmd.ts b/backend/src/plugins/Utility/commands/SearchCmd.ts index fb4d2ad1..7856728f 100644 --- a/backend/src/plugins/Utility/commands/SearchCmd.ts +++ b/backend/src/plugins/Utility/commands/SearchCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { archiveSearch, displaySearch, SearchType } from "../search"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { archiveSearch, displaySearch, SearchType } from "../search.js"; +import { utilityCmd } from "../types.js"; // Separate from SearchCmd to avoid a circular reference from ./search.ts export const searchCmdSignature = { diff --git a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts index 94a9c91d..01e6e762 100644 --- a/backend/src/plugins/Utility/commands/ServerInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/ServerInfoCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getServerInfoEmbed } from "../functions/getServerInfoEmbed"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { getServerInfoEmbed } from "../functions/getServerInfoEmbed.js"; +import { utilityCmd } from "../types.js"; export const ServerInfoCmd = utilityCmd({ trigger: ["server", "serverinfo"], diff --git a/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts b/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts index bf0e859f..45984746 100644 --- a/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/SnowflakeInfoCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getSnowflakeInfoEmbed } from "../functions/getSnowflakeInfoEmbed"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { getSnowflakeInfoEmbed } from "../functions/getSnowflakeInfoEmbed.js"; +import { utilityCmd } from "../types.js"; export const SnowflakeInfoCmd = utilityCmd({ trigger: ["snowflake", "snowflakeinfo"], diff --git a/backend/src/plugins/Utility/commands/SourceCmd.ts b/backend/src/plugins/Utility/commands/SourceCmd.ts index e51f94d3..dde7d537 100644 --- a/backend/src/plugins/Utility/commands/SourceCmd.ts +++ b/backend/src/plugins/Utility/commands/SourceCmd.ts @@ -1,8 +1,8 @@ import moment from "moment-timezone"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getBaseUrl } from "../../../pluginUtils"; -import { canReadChannel } from "../../../utils/canReadChannel"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { getBaseUrl } from "../../../pluginUtils.js"; +import { canReadChannel } from "../../../utils/canReadChannel.js"; +import { utilityCmd } from "../types.js"; export const SourceCmd = utilityCmd({ trigger: "source", diff --git a/backend/src/plugins/Utility/commands/UserInfoCmd.ts b/backend/src/plugins/Utility/commands/UserInfoCmd.ts index 274fbbbc..99603f84 100644 --- a/backend/src/plugins/Utility/commands/UserInfoCmd.ts +++ b/backend/src/plugins/Utility/commands/UserInfoCmd.ts @@ -1,6 +1,6 @@ -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { getUserInfoEmbed } from "../functions/getUserInfoEmbed"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { getUserInfoEmbed } from "../functions/getUserInfoEmbed.js"; +import { utilityCmd } from "../types.js"; export const UserInfoCmd = utilityCmd({ trigger: ["user", "userinfo", "whois"], diff --git a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts index 299b27a6..8c849d98 100644 --- a/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts +++ b/backend/src/plugins/Utility/commands/VcdisconnectCmd.ts @@ -1,9 +1,9 @@ import { VoiceChannel } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn } from "../../../pluginUtils"; -import { renderUsername } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { canActOn } from "../../../pluginUtils.js"; +import { renderUsername } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { utilityCmd } from "../types.js"; export const VcdisconnectCmd = utilityCmd({ trigger: ["vcdisconnect", "vcdisc", "vcdc", "vckick", "vck"], diff --git a/backend/src/plugins/Utility/commands/VcmoveCmd.ts b/backend/src/plugins/Utility/commands/VcmoveCmd.ts index a037d379..d8bee3ac 100644 --- a/backend/src/plugins/Utility/commands/VcmoveCmd.ts +++ b/backend/src/plugins/Utility/commands/VcmoveCmd.ts @@ -1,9 +1,9 @@ import { ChannelType, Snowflake, VoiceChannel } from "discord.js"; -import { commandTypeHelpers as ct } from "../../../commandTypes"; -import { canActOn } from "../../../pluginUtils"; -import { channelMentionRegex, isSnowflake, renderUsername, simpleClosestStringMatch } from "../../../utils"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes.js"; +import { canActOn } from "../../../pluginUtils.js"; +import { channelMentionRegex, isSnowflake, renderUsername, simpleClosestStringMatch } from "../../../utils.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { utilityCmd } from "../types.js"; export const VcmoveCmd = utilityCmd({ trigger: "vcmove", diff --git a/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts b/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts index 7dddcedf..c61d2a6c 100644 --- a/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts +++ b/backend/src/plugins/Utility/events/AutoJoinThreadEvt.ts @@ -1,4 +1,4 @@ -import { utilityEvt } from "../types"; +import { utilityEvt } from "../types.js"; export const AutoJoinThreadEvt = utilityEvt({ event: "threadCreate", diff --git a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts index befd1467..5c0cd334 100644 --- a/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getChannelInfoEmbed.ts @@ -1,8 +1,8 @@ import { APIEmbed, ChannelType, Snowflake, StageChannel, VoiceChannel } from "discord.js"; import humanizeDuration from "humanize-duration"; import { GuildPluginData } from "knub"; -import { EmbedWith, MINUTES, formatNumber, preEmbedPadding, trimLines, verboseUserMention } from "../../../utils"; -import { UtilityPluginType } from "../types"; +import { EmbedWith, MINUTES, formatNumber, preEmbedPadding, trimLines, verboseUserMention } from "../../../utils.js"; +import { UtilityPluginType } from "../types.js"; const TEXT_CHANNEL_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/740656843545772062/text-channel.png"; diff --git a/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts b/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts index 01001e2d..b4e68404 100644 --- a/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getEmojiInfoEmbed.ts @@ -1,7 +1,7 @@ import { APIEmbed } from "discord.js"; import { GuildPluginData } from "knub"; -import { EmbedWith, preEmbedPadding, trimLines } from "../../../utils"; -import { UtilityPluginType } from "../types"; +import { EmbedWith, preEmbedPadding, trimLines } from "../../../utils.js"; +import { UtilityPluginType } from "../types.js"; export async function getEmojiInfoEmbed( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Utility/functions/getGuildPreview.ts b/backend/src/plugins/Utility/functions/getGuildPreview.ts index 6ead2537..d82f1dee 100644 --- a/backend/src/plugins/Utility/functions/getGuildPreview.ts +++ b/backend/src/plugins/Utility/functions/getGuildPreview.ts @@ -1,5 +1,5 @@ import { Client, GuildPreview, Snowflake } from "discord.js"; -import { MINUTES, memoize } from "../../../utils"; +import { MINUTES, memoize } from "../../../utils.js"; /** * Memoized getGuildPreview diff --git a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts index b844b937..a990dd50 100644 --- a/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getInviteInfoEmbed.ts @@ -11,9 +11,9 @@ import { renderUsername, resolveInvite, trimLines, -} from "../../../utils"; -import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp"; -import { UtilityPluginType } from "../types"; +} from "../../../utils.js"; +import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp.js"; +import { UtilityPluginType } from "../types.js"; export async function getInviteInfoEmbed( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts index 34a89fe6..f003080f 100644 --- a/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getMessageInfoEmbed.ts @@ -8,8 +8,8 @@ import { renderUsername, trimEmptyLines, trimLines, -} from "../../../utils"; -import { UtilityPluginType } from "../types"; +} from "../../../utils.js"; +import { UtilityPluginType } from "../types.js"; const MESSAGE_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/740685652152025088/message.png"; diff --git a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts index dd19d9b2..9c27cefe 100644 --- a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts @@ -1,8 +1,8 @@ import { APIEmbed, PermissionFlagsBits, Role } from "discord.js"; import { GuildPluginData } from "knub"; -import { EmbedWith, preEmbedPadding, trimLines } from "../../../utils"; +import { EmbedWith, preEmbedPadding, trimLines } from "../../../utils.js"; import { PERMISSION_NAMES } from "../../../utils/permissionNames.js"; -import { UtilityPluginType } from "../types"; +import { UtilityPluginType } from "../types.js"; const MENTION_ICON = "https://cdn.discordapp.com/attachments/705009450855039042/839284872152481792/mention.png"; diff --git a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts index fa7368a6..f223563d 100644 --- a/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getServerInfoEmbed.ts @@ -11,10 +11,10 @@ import { resolveInvite, resolveUser, trimLines, -} from "../../../utils"; -import { idToTimestamp } from "../../../utils/idToTimestamp"; -import { UtilityPluginType } from "../types"; -import { getGuildPreview } from "./getGuildPreview"; +} from "../../../utils.js"; +import { idToTimestamp } from "../../../utils/idToTimestamp.js"; +import { UtilityPluginType } from "../types.js"; +import { getGuildPreview } from "./getGuildPreview.js"; const prettifyFeature = (feature: string): string => `\`${feature diff --git a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts index 8449ba74..18ac7389 100644 --- a/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getSnowflakeInfoEmbed.ts @@ -1,6 +1,6 @@ import { APIEmbed } from "discord.js"; -import { EmbedWith, preEmbedPadding } from "../../../utils"; -import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp"; +import { EmbedWith, preEmbedPadding } from "../../../utils.js"; +import { snowflakeToTimestamp } from "../../../utils/snowflakeToTimestamp.js"; const SNOWFLAKE_ICON = "https://cdn.discordapp.com/attachments/740650744830623756/742020790471491668/snowflake.png"; diff --git a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts index 395dcfbf..30f95ee5 100644 --- a/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts +++ b/backend/src/plugins/Utility/functions/getUserInfoEmbed.ts @@ -1,6 +1,6 @@ import { APIEmbed } from "discord.js"; import { GuildPluginData } from "knub"; -import { CaseTypes } from "../../../data/CaseTypes"; +import { CaseTypes } from "../../../data/CaseTypes.js"; import { EmbedWith, messageLink, @@ -12,8 +12,8 @@ import { trimEmptyLines, trimLines, UnknownUser, -} from "../../../utils"; -import { UtilityPluginType } from "../types"; +} from "../../../utils.js"; +import { UtilityPluginType } from "../types.js"; const MAX_ROLES_TO_DISPLAY = 15; diff --git a/backend/src/plugins/Utility/functions/hasPermission.ts b/backend/src/plugins/Utility/functions/hasPermission.ts index 919d28f7..ebefe203 100644 --- a/backend/src/plugins/Utility/functions/hasPermission.ts +++ b/backend/src/plugins/Utility/functions/hasPermission.ts @@ -1,6 +1,6 @@ import { GuildMember, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { UtilityPluginType } from "../types"; +import { UtilityPluginType } from "../types.js"; export async function hasPermission( pluginData: GuildPluginData, diff --git a/backend/src/plugins/Utility/info.ts b/backend/src/plugins/Utility/info.ts index 1cedf4b1..9fea0438 100644 --- a/backend/src/plugins/Utility/info.ts +++ b/backend/src/plugins/Utility/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { zUtilityConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { zUtilityConfig } from "./types.js"; export const utilityPluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/Utility/refreshMembers.ts b/backend/src/plugins/Utility/refreshMembers.ts index aa4920d6..6bf47b9e 100644 --- a/backend/src/plugins/Utility/refreshMembers.ts +++ b/backend/src/plugins/Utility/refreshMembers.ts @@ -1,5 +1,5 @@ import { Guild } from "discord.js"; -import { HOURS, noop } from "../../utils"; +import { HOURS, noop } from "../../utils.js"; const MEMBER_REFRESH_FREQUENCY = 1 * HOURS; // How often to do a full member refresh when using commands that need it const memberRefreshLog = new Map }>(); diff --git a/backend/src/plugins/Utility/search.ts b/backend/src/plugins/Utility/search.ts index 4b50ab1f..a2a23700 100644 --- a/backend/src/plugins/Utility/search.ts +++ b/backend/src/plugins/Utility/search.ts @@ -12,8 +12,8 @@ import { import escapeStringRegexp from "escape-string-regexp"; import { ArgsFromSignatureOrArray, GuildPluginData } from "knub"; import moment from "moment-timezone"; -import { RegExpRunner, allowTimeout } from "../../RegExpRunner"; -import { getBaseUrl } from "../../pluginUtils"; +import { RegExpRunner, allowTimeout } from "../../RegExpRunner.js"; +import { getBaseUrl } from "../../pluginUtils.js"; import { InvalidRegexError, MINUTES, @@ -22,14 +22,14 @@ import { renderUsername, sorter, trimLines, -} from "../../utils"; -import { asyncFilter } from "../../utils/async"; -import { hasDiscordPermissions } from "../../utils/hasDiscordPermissions"; -import { banSearchSignature } from "./commands/BanSearchCmd"; -import { searchCmdSignature } from "./commands/SearchCmd"; -import { getUserInfoEmbed } from "./functions/getUserInfoEmbed"; -import { refreshMembersIfNeeded } from "./refreshMembers"; -import { UtilityPluginType } from "./types"; +} from "../../utils.js"; +import { asyncFilter } from "../../utils/async.js"; +import { hasDiscordPermissions } from "../../utils/hasDiscordPermissions.js"; +import { banSearchSignature } from "./commands/BanSearchCmd.js"; +import { searchCmdSignature } from "./commands/SearchCmd.js"; +import { getUserInfoEmbed } from "./functions/getUserInfoEmbed.js"; +import { refreshMembersIfNeeded } from "./refreshMembers.js"; +import { UtilityPluginType } from "./types.js"; import Timeout = NodeJS.Timeout; const SEARCH_RESULTS_PER_PAGE = 15; diff --git a/backend/src/plugins/Utility/types.ts b/backend/src/plugins/Utility/types.ts index 0bcb56dd..2ab37f3e 100644 --- a/backend/src/plugins/Utility/types.ts +++ b/backend/src/plugins/Utility/types.ts @@ -1,12 +1,12 @@ import { BasePluginType, guildPluginEventListener, guildPluginMessageCommand, pluginUtils } from "knub"; import z from "zod"; -import { RegExpRunner } from "../../RegExpRunner"; -import { GuildArchives } from "../../data/GuildArchives"; -import { GuildCases } from "../../data/GuildCases"; -import { GuildLogs } from "../../data/GuildLogs"; -import { GuildSavedMessages } from "../../data/GuildSavedMessages"; -import { Supporters } from "../../data/Supporters"; -import { CommonPlugin } from "../Common/CommonPlugin"; +import { RegExpRunner } from "../../RegExpRunner.js"; +import { GuildArchives } from "../../data/GuildArchives.js"; +import { GuildCases } from "../../data/GuildCases.js"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { GuildSavedMessages } from "../../data/GuildSavedMessages.js"; +import { Supporters } from "../../data/Supporters.js"; +import { CommonPlugin } from "../Common/CommonPlugin.js"; export const zUtilityConfig = z.strictObject({ can_roles: z.boolean(), diff --git a/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts b/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts index a8fb9261..7848393a 100644 --- a/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts +++ b/backend/src/plugins/WelcomeMessage/WelcomeMessagePlugin.ts @@ -1,8 +1,8 @@ import { PluginOptions, guildPlugin } from "knub"; -import { GuildLogs } from "../../data/GuildLogs"; -import { LogsPlugin } from "../Logs/LogsPlugin"; -import { SendWelcomeMessageEvt } from "./events/SendWelcomeMessageEvt"; -import { WelcomeMessagePluginType, zWelcomeMessageConfig } from "./types"; +import { GuildLogs } from "../../data/GuildLogs.js"; +import { LogsPlugin } from "../Logs/LogsPlugin.js"; +import { SendWelcomeMessageEvt } from "./events/SendWelcomeMessageEvt.js"; +import { WelcomeMessagePluginType, zWelcomeMessageConfig } from "./types.js"; const defaultOptions: PluginOptions = { config: { diff --git a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts index 879b99cd..df983f0e 100644 --- a/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts +++ b/backend/src/plugins/WelcomeMessage/events/SendWelcomeMessageEvt.ts @@ -1,14 +1,14 @@ import { Snowflake, TextChannel } from "discord.js"; -import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter"; -import { createChunkedMessage, verboseChannelMention, verboseUserMention } from "../../../utils"; -import { sendDM } from "../../../utils/sendDM"; +import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter.js"; +import { createChunkedMessage, verboseChannelMention, verboseUserMention } from "../../../utils.js"; +import { sendDM } from "../../../utils/sendDM.js"; import { guildToTemplateSafeGuild, memberToTemplateSafeMember, userToTemplateSafeUser, -} from "../../../utils/templateSafeObjects"; -import { LogsPlugin } from "../../Logs/LogsPlugin"; -import { welcomeMessageEvt } from "../types"; +} from "../../../utils/templateSafeObjects.js"; +import { LogsPlugin } from "../../Logs/LogsPlugin.js"; +import { welcomeMessageEvt } from "../types.js"; export const SendWelcomeMessageEvt = welcomeMessageEvt({ event: "guildMemberAdd", diff --git a/backend/src/plugins/WelcomeMessage/info.ts b/backend/src/plugins/WelcomeMessage/info.ts index b1e394b8..a8a4c339 100644 --- a/backend/src/plugins/WelcomeMessage/info.ts +++ b/backend/src/plugins/WelcomeMessage/info.ts @@ -1,5 +1,5 @@ -import { ZeppelinPluginInfo } from "../../types"; -import { zWelcomeMessageConfig } from "./types"; +import { ZeppelinPluginInfo } from "../../types.js"; +import { zWelcomeMessageConfig } from "./types.js"; export const welcomeMessagePluginInfo: ZeppelinPluginInfo = { showInDocs: true, diff --git a/backend/src/plugins/WelcomeMessage/types.ts b/backend/src/plugins/WelcomeMessage/types.ts index 25e9afb1..05bd3354 100644 --- a/backend/src/plugins/WelcomeMessage/types.ts +++ b/backend/src/plugins/WelcomeMessage/types.ts @@ -1,6 +1,6 @@ import { BasePluginType, guildPluginEventListener } from "knub"; import z from "zod"; -import { GuildLogs } from "../../data/GuildLogs"; +import { GuildLogs } from "../../data/GuildLogs.js"; export const zWelcomeMessageConfig = z.strictObject({ send_dm: z.boolean(), diff --git a/backend/src/plugins/availablePlugins.ts b/backend/src/plugins/availablePlugins.ts index 81651eb5..9323e461 100644 --- a/backend/src/plugins/availablePlugins.ts +++ b/backend/src/plugins/availablePlugins.ts @@ -1,44 +1,44 @@ import { GlobalPluginBlueprint, GuildPluginBlueprint } from "knub"; -import { AutoDeletePlugin } from "./AutoDelete/AutoDeletePlugin"; -import { AutoReactionsPlugin } from "./AutoReactions/AutoReactionsPlugin"; -import { AutomodPlugin } from "./Automod/AutomodPlugin"; -import { BotControlPlugin } from "./BotControl/BotControlPlugin"; -import { CasesPlugin } from "./Cases/CasesPlugin"; -import { CensorPlugin } from "./Censor/CensorPlugin"; -import { ChannelArchiverPlugin } from "./ChannelArchiver/ChannelArchiverPlugin"; -import { CommonPlugin } from "./Common/CommonPlugin"; -import { CompanionChannelsPlugin } from "./CompanionChannels/CompanionChannelsPlugin"; -import { ContextMenuPlugin } from "./ContextMenus/ContextMenuPlugin"; -import { CountersPlugin } from "./Counters/CountersPlugin"; -import { CustomEventsPlugin } from "./CustomEvents/CustomEventsPlugin"; -import { GuildAccessMonitorPlugin } from "./GuildAccessMonitor/GuildAccessMonitorPlugin"; -import { GuildConfigReloaderPlugin } from "./GuildConfigReloader/GuildConfigReloaderPlugin"; -import { GuildInfoSaverPlugin } from "./GuildInfoSaver/GuildInfoSaverPlugin"; -import { InternalPosterPlugin } from "./InternalPoster/InternalPosterPlugin"; -import { LocateUserPlugin } from "./LocateUser/LocateUserPlugin"; -import { LogsPlugin } from "./Logs/LogsPlugin"; -import { MessageSaverPlugin } from "./MessageSaver/MessageSaverPlugin"; -import { ModActionsPlugin } from "./ModActions/ModActionsPlugin"; -import { MutesPlugin } from "./Mutes/MutesPlugin"; -import { NameHistoryPlugin } from "./NameHistory/NameHistoryPlugin"; -import { PersistPlugin } from "./Persist/PersistPlugin"; -import { PhishermanPlugin } from "./Phisherman/PhishermanPlugin"; -import { PingableRolesPlugin } from "./PingableRoles/PingableRolesPlugin"; -import { PostPlugin } from "./Post/PostPlugin"; -import { ReactionRolesPlugin } from "./ReactionRoles/ReactionRolesPlugin"; -import { RemindersPlugin } from "./Reminders/RemindersPlugin"; -import { RoleButtonsPlugin } from "./RoleButtons/RoleButtonsPlugin"; -import { RoleManagerPlugin } from "./RoleManager/RoleManagerPlugin"; -import { RolesPlugin } from "./Roles/RolesPlugin"; -import { SelfGrantableRolesPlugin } from "./SelfGrantableRoles/SelfGrantableRolesPlugin"; -import { SlowmodePlugin } from "./Slowmode/SlowmodePlugin"; -import { SpamPlugin } from "./Spam/SpamPlugin"; -import { StarboardPlugin } from "./Starboard/StarboardPlugin"; -import { TagsPlugin } from "./Tags/TagsPlugin"; -import { TimeAndDatePlugin } from "./TimeAndDate/TimeAndDatePlugin"; -import { UsernameSaverPlugin } from "./UsernameSaver/UsernameSaverPlugin"; -import { UtilityPlugin } from "./Utility/UtilityPlugin"; -import { WelcomeMessagePlugin } from "./WelcomeMessage/WelcomeMessagePlugin"; +import { AutoDeletePlugin } from "./AutoDelete/AutoDeletePlugin.js"; +import { AutoReactionsPlugin } from "./AutoReactions/AutoReactionsPlugin.js"; +import { AutomodPlugin } from "./Automod/AutomodPlugin.js"; +import { BotControlPlugin } from "./BotControl/BotControlPlugin.js"; +import { CasesPlugin } from "./Cases/CasesPlugin.js"; +import { CensorPlugin } from "./Censor/CensorPlugin.js"; +import { ChannelArchiverPlugin } from "./ChannelArchiver/ChannelArchiverPlugin.js"; +import { CommonPlugin } from "./Common/CommonPlugin.js"; +import { CompanionChannelsPlugin } from "./CompanionChannels/CompanionChannelsPlugin.js"; +import { ContextMenuPlugin } from "./ContextMenus/ContextMenuPlugin.js"; +import { CountersPlugin } from "./Counters/CountersPlugin.js"; +import { CustomEventsPlugin } from "./CustomEvents/CustomEventsPlugin.js"; +import { GuildAccessMonitorPlugin } from "./GuildAccessMonitor/GuildAccessMonitorPlugin.js"; +import { GuildConfigReloaderPlugin } from "./GuildConfigReloader/GuildConfigReloaderPlugin.js"; +import { GuildInfoSaverPlugin } from "./GuildInfoSaver/GuildInfoSaverPlugin.js"; +import { InternalPosterPlugin } from "./InternalPoster/InternalPosterPlugin.js"; +import { LocateUserPlugin } from "./LocateUser/LocateUserPlugin.js"; +import { LogsPlugin } from "./Logs/LogsPlugin.js"; +import { MessageSaverPlugin } from "./MessageSaver/MessageSaverPlugin.js"; +import { ModActionsPlugin } from "./ModActions/ModActionsPlugin.js"; +import { MutesPlugin } from "./Mutes/MutesPlugin.js"; +import { NameHistoryPlugin } from "./NameHistory/NameHistoryPlugin.js"; +import { PersistPlugin } from "./Persist/PersistPlugin.js"; +import { PhishermanPlugin } from "./Phisherman/PhishermanPlugin.js"; +import { PingableRolesPlugin } from "./PingableRoles/PingableRolesPlugin.js"; +import { PostPlugin } from "./Post/PostPlugin.js"; +import { ReactionRolesPlugin } from "./ReactionRoles/ReactionRolesPlugin.js"; +import { RemindersPlugin } from "./Reminders/RemindersPlugin.js"; +import { RoleButtonsPlugin } from "./RoleButtons/RoleButtonsPlugin.js"; +import { RoleManagerPlugin } from "./RoleManager/RoleManagerPlugin.js"; +import { RolesPlugin } from "./Roles/RolesPlugin.js"; +import { SelfGrantableRolesPlugin } from "./SelfGrantableRoles/SelfGrantableRolesPlugin.js"; +import { SlowmodePlugin } from "./Slowmode/SlowmodePlugin.js"; +import { SpamPlugin } from "./Spam/SpamPlugin.js"; +import { StarboardPlugin } from "./Starboard/StarboardPlugin.js"; +import { TagsPlugin } from "./Tags/TagsPlugin.js"; +import { TimeAndDatePlugin } from "./TimeAndDate/TimeAndDatePlugin.js"; +import { UsernameSaverPlugin } from "./UsernameSaver/UsernameSaverPlugin.js"; +import { UtilityPlugin } from "./Utility/UtilityPlugin.js"; +import { WelcomeMessagePlugin } from "./WelcomeMessage/WelcomeMessagePlugin.js"; // prettier-ignore export const guildPlugins: Array> = [ diff --git a/backend/src/plugins/pluginInfo.ts b/backend/src/plugins/pluginInfo.ts index 0d9305b2..58dbc34f 100644 --- a/backend/src/plugins/pluginInfo.ts +++ b/backend/src/plugins/pluginInfo.ts @@ -1,74 +1,74 @@ -import { ZeppelinPluginInfo } from "../types"; -import { AutoDeletePlugin } from "./AutoDelete/AutoDeletePlugin"; -import { autoDeletePluginInfo } from "./AutoDelete/info"; -import { AutoReactionsPlugin } from "./AutoReactions/AutoReactionsPlugin"; -import { autoReactionsInfo } from "./AutoReactions/info"; -import { AutomodPlugin } from "./Automod/AutomodPlugin"; -import { automodPluginInfo } from "./Automod/info"; -import { CasesPlugin } from "./Cases/CasesPlugin"; -import { casesPluginInfo } from "./Cases/info"; -import { CensorPlugin } from "./Censor/CensorPlugin"; -import { censorPluginInfo } from "./Censor/info"; -import { CompanionChannelsPlugin } from "./CompanionChannels/CompanionChannelsPlugin"; -import { companionChannelsPluginInfo } from "./CompanionChannels/info"; -import { ContextMenuPlugin } from "./ContextMenus/ContextMenuPlugin"; -import { contextMenuPluginInfo } from "./ContextMenus/info"; -import { CountersPlugin } from "./Counters/CountersPlugin"; -import { countersPluginInfo } from "./Counters/info"; -import { CustomEventsPlugin } from "./CustomEvents/CustomEventsPlugin"; -import { customEventsPluginInfo } from "./CustomEvents/info"; -import { GuildInfoSaverPlugin } from "./GuildInfoSaver/GuildInfoSaverPlugin"; -import { guildInfoSaverPluginInfo } from "./GuildInfoSaver/info"; -import { InternalPosterPlugin } from "./InternalPoster/InternalPosterPlugin"; -import { internalPosterPluginInfo } from "./InternalPoster/info"; -import { LocateUserPlugin } from "./LocateUser/LocateUserPlugin"; -import { locateUserPluginInfo } from "./LocateUser/info"; -import { LogsPlugin } from "./Logs/LogsPlugin"; -import { logsPluginInfo } from "./Logs/info"; -import { MessageSaverPlugin } from "./MessageSaver/MessageSaverPlugin"; -import { messageSaverPluginInfo } from "./MessageSaver/info"; -import { ModActionsPlugin } from "./ModActions/ModActionsPlugin"; -import { modActionsPluginInfo } from "./ModActions/info"; -import { MutesPlugin } from "./Mutes/MutesPlugin"; -import { mutesPluginInfo } from "./Mutes/info"; -import { NameHistoryPlugin } from "./NameHistory/NameHistoryPlugin"; -import { nameHistoryPluginInfo } from "./NameHistory/info"; -import { PersistPlugin } from "./Persist/PersistPlugin"; -import { persistPluginInfo } from "./Persist/info"; -import { PhishermanPlugin } from "./Phisherman/PhishermanPlugin"; -import { phishermanPluginInfo } from "./Phisherman/info"; -import { PingableRolesPlugin } from "./PingableRoles/PingableRolesPlugin"; -import { pingableRolesPluginInfo } from "./PingableRoles/info"; -import { PostPlugin } from "./Post/PostPlugin"; -import { postPluginInfo } from "./Post/info"; -import { ReactionRolesPlugin } from "./ReactionRoles/ReactionRolesPlugin"; -import { reactionRolesPluginInfo } from "./ReactionRoles/info"; -import { RemindersPlugin } from "./Reminders/RemindersPlugin"; -import { remindersPluginInfo } from "./Reminders/info"; -import { RoleButtonsPlugin } from "./RoleButtons/RoleButtonsPlugin"; -import { roleButtonsPluginInfo } from "./RoleButtons/info"; -import { RoleManagerPlugin } from "./RoleManager/RoleManagerPlugin"; -import { roleManagerPluginInfo } from "./RoleManager/info"; -import { RolesPlugin } from "./Roles/RolesPlugin"; -import { rolesPluginInfo } from "./Roles/info"; -import { SelfGrantableRolesPlugin } from "./SelfGrantableRoles/SelfGrantableRolesPlugin"; -import { selfGrantableRolesPluginInfo } from "./SelfGrantableRoles/info"; -import { SlowmodePlugin } from "./Slowmode/SlowmodePlugin"; -import { slowmodePluginInfo } from "./Slowmode/info"; -import { SpamPlugin } from "./Spam/SpamPlugin"; -import { spamPluginInfo } from "./Spam/info"; -import { StarboardPlugin } from "./Starboard/StarboardPlugin"; -import { starboardPluginInfo } from "./Starboard/info"; -import { TagsPlugin } from "./Tags/TagsPlugin"; -import { tagsPluginInfo } from "./Tags/info"; -import { TimeAndDatePlugin } from "./TimeAndDate/TimeAndDatePlugin"; -import { timeAndDatePluginInfo } from "./TimeAndDate/info"; -import { UsernameSaverPlugin } from "./UsernameSaver/UsernameSaverPlugin"; -import { usernameSaverPluginInfo } from "./UsernameSaver/info"; -import { UtilityPlugin } from "./Utility/UtilityPlugin"; -import { utilityPluginInfo } from "./Utility/info"; -import { WelcomeMessagePlugin } from "./WelcomeMessage/WelcomeMessagePlugin"; -import { welcomeMessagePluginInfo } from "./WelcomeMessage/info"; +import { ZeppelinPluginInfo } from "../types.js"; +import { AutoDeletePlugin } from "./AutoDelete/AutoDeletePlugin.js"; +import { autoDeletePluginInfo } from "./AutoDelete/info.js"; +import { AutoReactionsPlugin } from "./AutoReactions/AutoReactionsPlugin.js"; +import { autoReactionsInfo } from "./AutoReactions/info.js"; +import { AutomodPlugin } from "./Automod/AutomodPlugin.js"; +import { automodPluginInfo } from "./Automod/info.js"; +import { CasesPlugin } from "./Cases/CasesPlugin.js"; +import { casesPluginInfo } from "./Cases/info.js"; +import { CensorPlugin } from "./Censor/CensorPlugin.js"; +import { censorPluginInfo } from "./Censor/info.js"; +import { CompanionChannelsPlugin } from "./CompanionChannels/CompanionChannelsPlugin.js"; +import { companionChannelsPluginInfo } from "./CompanionChannels/info.js"; +import { ContextMenuPlugin } from "./ContextMenus/ContextMenuPlugin.js"; +import { contextMenuPluginInfo } from "./ContextMenus/info.js"; +import { CountersPlugin } from "./Counters/CountersPlugin.js"; +import { countersPluginInfo } from "./Counters/info.js"; +import { CustomEventsPlugin } from "./CustomEvents/CustomEventsPlugin.js"; +import { customEventsPluginInfo } from "./CustomEvents/info.js"; +import { GuildInfoSaverPlugin } from "./GuildInfoSaver/GuildInfoSaverPlugin.js"; +import { guildInfoSaverPluginInfo } from "./GuildInfoSaver/info.js"; +import { InternalPosterPlugin } from "./InternalPoster/InternalPosterPlugin.js"; +import { internalPosterPluginInfo } from "./InternalPoster/info.js"; +import { LocateUserPlugin } from "./LocateUser/LocateUserPlugin.js"; +import { locateUserPluginInfo } from "./LocateUser/info.js"; +import { LogsPlugin } from "./Logs/LogsPlugin.js"; +import { logsPluginInfo } from "./Logs/info.js"; +import { MessageSaverPlugin } from "./MessageSaver/MessageSaverPlugin.js"; +import { messageSaverPluginInfo } from "./MessageSaver/info.js"; +import { ModActionsPlugin } from "./ModActions/ModActionsPlugin.js"; +import { modActionsPluginInfo } from "./ModActions/info.js"; +import { MutesPlugin } from "./Mutes/MutesPlugin.js"; +import { mutesPluginInfo } from "./Mutes/info.js"; +import { NameHistoryPlugin } from "./NameHistory/NameHistoryPlugin.js"; +import { nameHistoryPluginInfo } from "./NameHistory/info.js"; +import { PersistPlugin } from "./Persist/PersistPlugin.js"; +import { persistPluginInfo } from "./Persist/info.js"; +import { PhishermanPlugin } from "./Phisherman/PhishermanPlugin.js"; +import { phishermanPluginInfo } from "./Phisherman/info.js"; +import { PingableRolesPlugin } from "./PingableRoles/PingableRolesPlugin.js"; +import { pingableRolesPluginInfo } from "./PingableRoles/info.js"; +import { PostPlugin } from "./Post/PostPlugin.js"; +import { postPluginInfo } from "./Post/info.js"; +import { ReactionRolesPlugin } from "./ReactionRoles/ReactionRolesPlugin.js"; +import { reactionRolesPluginInfo } from "./ReactionRoles/info.js"; +import { RemindersPlugin } from "./Reminders/RemindersPlugin.js"; +import { remindersPluginInfo } from "./Reminders/info.js"; +import { RoleButtonsPlugin } from "./RoleButtons/RoleButtonsPlugin.js"; +import { roleButtonsPluginInfo } from "./RoleButtons/info.js"; +import { RoleManagerPlugin } from "./RoleManager/RoleManagerPlugin.js"; +import { roleManagerPluginInfo } from "./RoleManager/info.js"; +import { RolesPlugin } from "./Roles/RolesPlugin.js"; +import { rolesPluginInfo } from "./Roles/info.js"; +import { SelfGrantableRolesPlugin } from "./SelfGrantableRoles/SelfGrantableRolesPlugin.js"; +import { selfGrantableRolesPluginInfo } from "./SelfGrantableRoles/info.js"; +import { SlowmodePlugin } from "./Slowmode/SlowmodePlugin.js"; +import { slowmodePluginInfo } from "./Slowmode/info.js"; +import { SpamPlugin } from "./Spam/SpamPlugin.js"; +import { spamPluginInfo } from "./Spam/info.js"; +import { StarboardPlugin } from "./Starboard/StarboardPlugin.js"; +import { starboardPluginInfo } from "./Starboard/info.js"; +import { TagsPlugin } from "./Tags/TagsPlugin.js"; +import { tagsPluginInfo } from "./Tags/info.js"; +import { TimeAndDatePlugin } from "./TimeAndDate/TimeAndDatePlugin.js"; +import { timeAndDatePluginInfo } from "./TimeAndDate/info.js"; +import { UsernameSaverPlugin } from "./UsernameSaver/UsernameSaverPlugin.js"; +import { usernameSaverPluginInfo } from "./UsernameSaver/info.js"; +import { UtilityPlugin } from "./Utility/UtilityPlugin.js"; +import { utilityPluginInfo } from "./Utility/info.js"; +import { WelcomeMessagePlugin } from "./WelcomeMessage/WelcomeMessagePlugin.js"; +import { welcomeMessagePluginInfo } from "./WelcomeMessage/info.js"; export const guildPluginInfo: Record = { [AutoDeletePlugin.name]: autoDeletePluginInfo, diff --git a/backend/src/regExpRunners.ts b/backend/src/regExpRunners.ts index 0395a11c..9ad53547 100644 --- a/backend/src/regExpRunners.ts +++ b/backend/src/regExpRunners.ts @@ -1,4 +1,4 @@ -import { RegExpRunner } from "./RegExpRunner"; +import { RegExpRunner } from "./RegExpRunner.js"; interface RunnerInfo { users: number; diff --git a/backend/src/restCallStats.ts b/backend/src/restCallStats.ts index a6d5c8ea..9af6230b 100644 --- a/backend/src/restCallStats.ts +++ b/backend/src/restCallStats.ts @@ -1,4 +1,4 @@ -import { sorter } from "./utils"; +import { sorter } from "./utils.js"; Error.stackTraceLimit = Infinity; diff --git a/backend/src/staff.ts b/backend/src/staff.ts index 6950ee33..c11d6d30 100644 --- a/backend/src/staff.ts +++ b/backend/src/staff.ts @@ -1,4 +1,4 @@ -import { env } from "./env"; +import { env } from "./env.js"; /** * Zeppelin staff have full access to the dashboard diff --git a/backend/src/templateFormatter.test.ts b/backend/src/templateFormatter.test.ts index 1713f839..f906e054 100644 --- a/backend/src/templateFormatter.test.ts +++ b/backend/src/templateFormatter.test.ts @@ -1,5 +1,5 @@ import test from "ava"; -import { parseTemplate, renderParsedTemplate, renderTemplate, TemplateSafeValueContainer } from "./templateFormatter"; +import { parseTemplate, renderParsedTemplate, renderTemplate, TemplateSafeValueContainer } from "./templateFormatter.js"; test("Parses plain string templates correctly", (t) => { const result = parseTemplate("foo bar baz"); diff --git a/backend/src/templateFormatter.ts b/backend/src/templateFormatter.ts index 299efb2e..db053d3e 100644 --- a/backend/src/templateFormatter.ts +++ b/backend/src/templateFormatter.ts @@ -1,5 +1,5 @@ import seedrandom from "seedrandom"; -import { get, has } from "./utils"; +import { get, has } from "./utils.js"; const TEMPLATE_CACHE_SIZE = 200; const templateCache: Map = new Map(); diff --git a/backend/src/threadsSignalFix.ts b/backend/src/threadsSignalFix.ts index 86f53067..46ffce82 100644 --- a/backend/src/threadsSignalFix.ts +++ b/backend/src/threadsSignalFix.ts @@ -6,7 +6,7 @@ * - This is imported as early as possible to avoid removing our own signal handlers */ import "threads"; -import { env } from "./env"; +import { env } from "./env.js"; if (!env.DEBUG) { process.removeAllListeners("SIGINT"); process.removeAllListeners("SIGTERM"); diff --git a/backend/src/types.ts b/backend/src/types.ts index 7453ded2..a48f222b 100644 --- a/backend/src/types.ts +++ b/backend/src/types.ts @@ -1,6 +1,6 @@ import { Knub } from "knub"; import z, { ZodTypeAny } from "zod"; -import { zSnowflake } from "./utils"; +import { zSnowflake } from "./utils.js"; export const zZeppelinGuildConfig = z.strictObject({ // From BaseConfig diff --git a/backend/src/utils.test.ts b/backend/src/utils.test.ts index 461be47b..2c1627d6 100644 --- a/backend/src/utils.test.ts +++ b/backend/src/utils.test.ts @@ -1,7 +1,7 @@ import test from "ava"; import z from "zod"; -import { convertDelayStringToMS, convertMSToDelayString, getUrlsInString, zAllowedMentions } from "./utils"; -import { ErisAllowedMentionFormat } from "./utils/erisAllowedMentionsToDjsMentionOptions"; +import { convertDelayStringToMS, convertMSToDelayString, getUrlsInString, zAllowedMentions } from "./utils.js"; +import { ErisAllowedMentionFormat } from "./utils/erisAllowedMentionsToDjsMentionOptions.js"; type AssertEquals = TActual extends TExpected ? true : false; diff --git a/backend/src/utils.ts b/backend/src/utils.ts index 7aead1a5..5930e27e 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -36,12 +36,12 @@ import tlds from "tlds"; import tmp from "tmp"; import { URL } from "url"; import { z, ZodEffects, ZodError, ZodRecord, ZodString } from "zod"; -import { ISavedMessageAttachmentData, SavedMessage } from "./data/entities/SavedMessage"; -import { getProfiler } from "./profiler"; -import { SimpleCache } from "./SimpleCache"; -import { sendDM } from "./utils/sendDM"; -import { Brand } from "./utils/typeUtils"; -import { waitForButtonConfirm } from "./utils/waitForInteraction"; +import { ISavedMessageAttachmentData, SavedMessage } from "./data/entities/SavedMessage.js"; +import { getProfiler } from "./profiler.js"; +import { SimpleCache } from "./SimpleCache.js"; +import { sendDM } from "./utils/sendDM.js"; +import { Brand } from "./utils/typeUtils.js"; +import { waitForButtonConfirm } from "./utils/waitForInteraction.js"; const fsp = fs.promises; diff --git a/backend/src/utils/MessageBuffer.ts b/backend/src/utils/MessageBuffer.ts index ea0a0a0e..ab1380df 100644 --- a/backend/src/utils/MessageBuffer.ts +++ b/backend/src/utils/MessageBuffer.ts @@ -1,5 +1,5 @@ -import { StrictMessageContent } from "../utils"; -import { calculateEmbedSize } from "./calculateEmbedSize"; +import { StrictMessageContent } from "../utils.js"; +import { calculateEmbedSize } from "./calculateEmbedSize.js"; import Timeout = NodeJS.Timeout; type ConsumeFn = (part: StrictMessageContent) => void; diff --git a/backend/src/utils/async.ts b/backend/src/utils/async.ts index 4c8e9bf2..988f3072 100644 --- a/backend/src/utils/async.ts +++ b/backend/src/utils/async.ts @@ -1,4 +1,4 @@ -import { Awaitable } from "./typeUtils"; +import { Awaitable } from "./typeUtils.js"; export async function asyncReduce( arr: T[], diff --git a/backend/src/utils/canAssignRole.ts b/backend/src/utils/canAssignRole.ts index 96ec92e4..caa7a791 100644 --- a/backend/src/utils/canAssignRole.ts +++ b/backend/src/utils/canAssignRole.ts @@ -1,6 +1,6 @@ import { Guild, GuildMember, PermissionsBitField, Role, Snowflake } from "discord.js"; -import { getMissingPermissions } from "./getMissingPermissions"; -import { hasDiscordPermissions } from "./hasDiscordPermissions"; +import { getMissingPermissions } from "./getMissingPermissions.js"; +import { hasDiscordPermissions } from "./hasDiscordPermissions.js"; export function canAssignRole(guild: Guild, member: GuildMember, roleId: string) { if (getMissingPermissions(member.permissions, PermissionsBitField.Flags.ManageRoles)) { diff --git a/backend/src/utils/canReadChannel.ts b/backend/src/utils/canReadChannel.ts index 043a72d2..c99cb672 100644 --- a/backend/src/utils/canReadChannel.ts +++ b/backend/src/utils/canReadChannel.ts @@ -1,6 +1,6 @@ import { GuildMember, GuildTextBasedChannel } from "discord.js"; -import { getMissingChannelPermissions } from "./getMissingChannelPermissions"; -import { readChannelPermissions } from "./readChannelPermissions"; +import { getMissingChannelPermissions } from "./getMissingChannelPermissions.js"; +import { readChannelPermissions } from "./readChannelPermissions.js"; export function canReadChannel(channel: GuildTextBasedChannel, member: GuildMember) { // Not missing permissions required to read the channel = can read channel diff --git a/backend/src/utils/createPaginatedMessage.ts b/backend/src/utils/createPaginatedMessage.ts index e1be4ea4..aebf165a 100644 --- a/backend/src/utils/createPaginatedMessage.ts +++ b/backend/src/utils/createPaginatedMessage.ts @@ -9,9 +9,9 @@ import { PartialUser, User, } from "discord.js"; -import { sendContextResponse } from "../pluginUtils"; -import { MINUTES, noop } from "../utils"; -import { Awaitable } from "./typeUtils"; +import { sendContextResponse } from "../pluginUtils.js"; +import { MINUTES, noop } from "../utils.js"; +import { Awaitable } from "./typeUtils.js"; import Timeout = NodeJS.Timeout; export type LoadPageFn = (page: number) => Awaitable; diff --git a/backend/src/utils/crypt.test.ts b/backend/src/utils/crypt.test.ts index c9652a97..ef9cb979 100644 --- a/backend/src/utils/crypt.test.ts +++ b/backend/src/utils/crypt.test.ts @@ -1,5 +1,5 @@ import test from "ava"; -import { decrypt, encrypt } from "./crypt"; +import { decrypt, encrypt } from "./crypt.js"; test("encrypt() followed by decrypt()", async (t) => { const original = "banana 123 👀 💕"; // Includes emojis to verify utf8 stuff works diff --git a/backend/src/utils/crypt.ts b/backend/src/utils/crypt.ts index 5d18e028..4db9241e 100644 --- a/backend/src/utils/crypt.ts +++ b/backend/src/utils/crypt.ts @@ -1,7 +1,7 @@ import { Pool, spawn, Worker } from "threads"; -import { env } from "../env"; -import "../threadsSignalFix"; -import { MINUTES } from "../utils"; +import { env } from "../env.js"; +import "../threadsSignalFix.js"; +import { MINUTES } from "../utils.js"; const pool = Pool(() => spawn(new Worker("./cryptWorker"), { timeout: 10 * MINUTES }), 8); diff --git a/backend/src/utils/cryptHelpers.ts b/backend/src/utils/cryptHelpers.ts index c0920436..d740dcc4 100644 --- a/backend/src/utils/cryptHelpers.ts +++ b/backend/src/utils/cryptHelpers.ts @@ -1,4 +1,4 @@ -import { decrypt, encrypt } from "./crypt"; +import { decrypt, encrypt } from "./crypt.js"; export async function encryptJson(obj: any): Promise { const serialized = JSON.stringify(obj); diff --git a/backend/src/utils/easyProfiler.ts b/backend/src/utils/easyProfiler.ts index 28918526..d34e2571 100644 --- a/backend/src/utils/easyProfiler.ts +++ b/backend/src/utils/easyProfiler.ts @@ -1,6 +1,6 @@ import type { Knub } from "knub"; import { performance } from "perf_hooks"; -import { noop, SECONDS } from "../utils"; +import { noop, SECONDS } from "../utils.js"; type Profiler = Knub["profiler"]; diff --git a/backend/src/utils/findMatchingAuditLogEntry.ts b/backend/src/utils/findMatchingAuditLogEntry.ts index 70e8e426..ce83010d 100644 --- a/backend/src/utils/findMatchingAuditLogEntry.ts +++ b/backend/src/utils/findMatchingAuditLogEntry.ts @@ -1,5 +1,5 @@ import { AuditLogEvent, Guild, GuildAuditLogsEntry } from "discord.js"; -import { SECONDS, sleep } from "../utils"; +import { SECONDS, sleep } from "../utils.js"; const BATCH_DEBOUNCE_TIME = 2 * SECONDS; const BATCH_FETCH_COUNT_INCREMENT = 10; diff --git a/backend/src/utils/getChunkedEmbedFields.ts b/backend/src/utils/getChunkedEmbedFields.ts index 062f6224..2f93ed67 100644 --- a/backend/src/utils/getChunkedEmbedFields.ts +++ b/backend/src/utils/getChunkedEmbedFields.ts @@ -1,5 +1,5 @@ import { EmbedField } from "discord.js"; -import { chunkMessageLines, emptyEmbedValue } from "../utils"; +import { chunkMessageLines, emptyEmbedValue } from "../utils.js"; export function getChunkedEmbedFields(name: string, value: string): EmbedField[] { const fields: EmbedField[] = []; diff --git a/backend/src/utils/getMissingChannelPermissions.ts b/backend/src/utils/getMissingChannelPermissions.ts index 25f1e9e7..2410968a 100644 --- a/backend/src/utils/getMissingChannelPermissions.ts +++ b/backend/src/utils/getMissingChannelPermissions.ts @@ -1,5 +1,5 @@ import { GuildMember, GuildTextBasedChannel } from "discord.js"; -import { getMissingPermissions } from "./getMissingPermissions"; +import { getMissingPermissions } from "./getMissingPermissions.js"; /** * @param requiredPermissions Bitmask of required permissions diff --git a/backend/src/utils/loadYamlSafely.ts b/backend/src/utils/loadYamlSafely.ts index 6960a0bf..07fdb66e 100644 --- a/backend/src/utils/loadYamlSafely.ts +++ b/backend/src/utils/loadYamlSafely.ts @@ -1,5 +1,5 @@ import yaml from "js-yaml"; -import { validateNoObjectAliases } from "./validateNoObjectAliases"; +import { validateNoObjectAliases } from "./validateNoObjectAliases.js"; /** * Loads a YAML file safely while removing object anchors/aliases (including arrays) diff --git a/backend/src/utils/lockNameHelpers.ts b/backend/src/utils/lockNameHelpers.ts index 81f3bc04..f01553c6 100644 --- a/backend/src/utils/lockNameHelpers.ts +++ b/backend/src/utils/lockNameHelpers.ts @@ -1,5 +1,5 @@ import { GuildMember, Message, User } from "discord.js"; -import { SavedMessage } from "../data/entities/SavedMessage"; +import { SavedMessage } from "../data/entities/SavedMessage.js"; export function allStarboardsLock() { return `starboards`; diff --git a/backend/src/utils/mergeRegexes.ts b/backend/src/utils/mergeRegexes.ts index b503d12e..0aeea143 100644 --- a/backend/src/utils/mergeRegexes.ts +++ b/backend/src/utils/mergeRegexes.ts @@ -1,4 +1,4 @@ -import { categorize } from "./categorize"; +import { categorize } from "./categorize.js"; const hasBackreference = /(?:^|[^\\]|[\\]{2})\\\d+/; diff --git a/backend/src/utils/messageIsEmpty.ts b/backend/src/utils/messageIsEmpty.ts index 4721f7eb..d4c20ba6 100644 --- a/backend/src/utils/messageIsEmpty.ts +++ b/backend/src/utils/messageIsEmpty.ts @@ -1,6 +1,6 @@ import { MessageCreateOptions } from "discord.js"; import { StrictMessageContent } from "../utils.js"; -import { messageHasContent } from "./messageHasContent"; +import { messageHasContent } from "./messageHasContent.js"; export function messageIsEmpty(content: string | MessageCreateOptions | StrictMessageContent): boolean { return !messageHasContent(content); diff --git a/backend/src/utils/missingPermissionError.ts b/backend/src/utils/missingPermissionError.ts index e19ecb9b..136f7530 100644 --- a/backend/src/utils/missingPermissionError.ts +++ b/backend/src/utils/missingPermissionError.ts @@ -1,4 +1,4 @@ -import { getPermissionNames } from "./getPermissionNames"; +import { getPermissionNames } from "./getPermissionNames.js"; export function missingPermissionError(missingPermissions: number | bigint): string { const permissionNames = getPermissionNames(missingPermissions); diff --git a/backend/src/utils/normalizeText.test.ts b/backend/src/utils/normalizeText.test.ts index cd5a139c..549ee062 100644 --- a/backend/src/utils/normalizeText.test.ts +++ b/backend/src/utils/normalizeText.test.ts @@ -1,5 +1,5 @@ import test from "ava"; -import { normalizeText } from "./normalizeText"; +import { normalizeText } from "./normalizeText.js"; test("Replaces special characters", (t) => { const from = "𝗧:regional_indicator_e:ᔕ7 𝗧:regional_indicator_e:ᔕ7 𝗧:regional_indicator_e:ᔕ7"; diff --git a/backend/src/utils/parseCustomId.ts b/backend/src/utils/parseCustomId.ts index b2ca1009..772da2da 100644 --- a/backend/src/utils/parseCustomId.ts +++ b/backend/src/utils/parseCustomId.ts @@ -1,4 +1,4 @@ -import { logger } from "../logger"; +import { logger } from "../logger.js"; const customIdFormat = /^([^:]+):\d+:(.*)$/; diff --git a/backend/src/utils/permissionNames.ts b/backend/src/utils/permissionNames.ts index ca4922de..e888ab3c 100644 --- a/backend/src/utils/permissionNames.ts +++ b/backend/src/utils/permissionNames.ts @@ -1,5 +1,5 @@ import type { PermissionFlagsBits } from "discord.js"; -import { EMPTY_CHAR } from "../utils"; +import { EMPTY_CHAR } from "../utils.js"; export const PERMISSION_NAMES = { AddReactions: "Add Reactions", diff --git a/backend/src/utils/resolveChannelIds.ts b/backend/src/utils/resolveChannelIds.ts index 7f3bf138..5a282187 100644 --- a/backend/src/utils/resolveChannelIds.ts +++ b/backend/src/utils/resolveChannelIds.ts @@ -1,7 +1,7 @@ import { CategoryChannel, Channel } from "discord.js"; -import { isDmChannel } from "./isDmChannel"; -import { isGuildChannel } from "./isGuildChannel"; -import { isThreadChannel } from "./isThreadChannel"; +import { isDmChannel } from "./isDmChannel.js"; +import { isGuildChannel } from "./isGuildChannel.js"; +import { isThreadChannel } from "./isThreadChannel.js"; type ResolvedChannelIds = { category: string | null; diff --git a/backend/src/utils/resolveMessageTarget.ts b/backend/src/utils/resolveMessageTarget.ts index 2e3258a4..cb9dccfe 100644 --- a/backend/src/utils/resolveMessageTarget.ts +++ b/backend/src/utils/resolveMessageTarget.ts @@ -1,7 +1,7 @@ import { GuildTextBasedChannel, Snowflake } from "discord.js"; import { GuildPluginData } from "knub"; -import { getChannelIdFromMessageId } from "../data/getChannelIdFromMessageId"; -import { isSnowflake } from "../utils"; +import { getChannelIdFromMessageId } from "../data/getChannelIdFromMessageId.js"; +import { isSnowflake } from "../utils.js"; const channelAndMessageIdRegex = /^(\d+)[-/](\d+)$/; const messageLinkRegex = /^https:\/\/(?:\w+\.)?discord(?:app)?\.com\/channels\/\d+\/(\d+)\/(\d+)$/i; diff --git a/backend/src/utils/sendDM.ts b/backend/src/utils/sendDM.ts index bfcfe97e..f1ca6fc6 100644 --- a/backend/src/utils/sendDM.ts +++ b/backend/src/utils/sendDM.ts @@ -1,6 +1,6 @@ import { MessagePayload, User } from "discord.js"; -import { logger } from "../logger"; -import { HOURS, createChunkedMessage, isDiscordAPIError } from "../utils"; +import { logger } from "../logger.js"; +import { HOURS, createChunkedMessage, isDiscordAPIError } from "../utils.js"; import Timeout = NodeJS.Timeout; let dmsDisabled = false; diff --git a/backend/src/utils/snowflakeToTimestamp.ts b/backend/src/utils/snowflakeToTimestamp.ts index 09494eed..b1442235 100644 --- a/backend/src/utils/snowflakeToTimestamp.ts +++ b/backend/src/utils/snowflakeToTimestamp.ts @@ -1,4 +1,4 @@ -import { isValidSnowflake } from "../utils"; +import { isValidSnowflake } from "../utils.js"; /** * @return Unix timestamp in milliseconds diff --git a/backend/src/utils/templateSafeObjects.ts b/backend/src/utils/templateSafeObjects.ts index 06ed04b1..3a65aa8d 100644 --- a/backend/src/utils/templateSafeObjects.ts +++ b/backend/src/utils/templateSafeObjects.ts @@ -13,20 +13,20 @@ import { User, } from "discord.js"; import { GuildPluginData } from "knub"; -import { Case } from "../data/entities/Case"; +import { Case } from "../data/entities/Case.js"; import { ISavedMessageAttachmentData, ISavedMessageData, ISavedMessageEmbedData, ISavedMessageStickerData, SavedMessage, -} from "../data/entities/SavedMessage"; +} from "../data/entities/SavedMessage.js"; import { TemplateSafeValueContainer, TypedTemplateSafeValueContainer, ingestDataIntoTemplateSafeValueContainer, -} from "../templateFormatter"; -import { UnknownUser, renderUsername } from "../utils"; +} from "../templateFormatter.js"; +import { UnknownUser, renderUsername } from "../utils.js"; type InputProps = Omit< { diff --git a/backend/src/utils/validateNoObjectAliases.test.ts b/backend/src/utils/validateNoObjectAliases.test.ts index b418f72b..b56159ef 100644 --- a/backend/src/utils/validateNoObjectAliases.test.ts +++ b/backend/src/utils/validateNoObjectAliases.test.ts @@ -1,5 +1,5 @@ import test from "ava"; -import { ObjectAliasError, validateNoObjectAliases } from "./validateNoObjectAliases"; +import { ObjectAliasError, validateNoObjectAliases } from "./validateNoObjectAliases.js"; test("validateNoObjectAliases() disallows object aliases at top level", (t) => { const obj: any = { diff --git a/backend/src/utils/waitForInteraction.ts b/backend/src/utils/waitForInteraction.ts index 1486bef3..6cf9ad07 100644 --- a/backend/src/utils/waitForInteraction.ts +++ b/backend/src/utils/waitForInteraction.ts @@ -11,8 +11,8 @@ import { } from "discord.js"; import moment from "moment"; import { v4 as uuidv4 } from "uuid"; -import { isContextInteraction } from "../pluginUtils"; -import { noop } from "../utils"; +import { isContextInteraction } from "../pluginUtils.js"; +import { noop } from "../utils.js"; export async function waitForButtonConfirm( context: Message | User | ChatInputCommandInteraction, diff --git a/backend/src/utils/zColor.ts b/backend/src/utils/zColor.ts index 1bc3ae92..4961b67d 100644 --- a/backend/src/utils/zColor.ts +++ b/backend/src/utils/zColor.ts @@ -1,6 +1,6 @@ import z from "zod"; -import { parseColor } from "./parseColor"; -import { rgbToInt } from "./rgbToInt"; +import { parseColor } from "./parseColor.js"; +import { rgbToInt } from "./rgbToInt.js"; export const zColor = z.string().transform((val, ctx) => { const parsedColor = parseColor(val); diff --git a/backend/src/utils/zValidTimezone.ts b/backend/src/utils/zValidTimezone.ts index b83c47c1..7757de05 100644 --- a/backend/src/utils/zValidTimezone.ts +++ b/backend/src/utils/zValidTimezone.ts @@ -1,5 +1,5 @@ import { ZodString } from "zod"; -import { isValidTimezone } from "./isValidTimezone"; +import { isValidTimezone } from "./isValidTimezone.js"; export function zValidTimezone(z: Z) { return z.refine((val) => isValidTimezone(val), { diff --git a/backend/src/validateActiveConfigs.ts b/backend/src/validateActiveConfigs.ts index f985fd14..aff64fd4 100644 --- a/backend/src/validateActiveConfigs.ts +++ b/backend/src/validateActiveConfigs.ts @@ -1,9 +1,9 @@ import { YAMLException } from "js-yaml"; -import { validateGuildConfig } from "./configValidator"; -import { Configs } from "./data/Configs"; -import { connect, disconnect } from "./data/db"; -import { loadYamlSafely } from "./utils/loadYamlSafely"; -import { ObjectAliasError } from "./utils/validateNoObjectAliases"; +import { validateGuildConfig } from "./configValidator.js"; +import { Configs } from "./data/Configs.js"; +import { connect, disconnect } from "./data/db.js"; +import { loadYamlSafely } from "./utils/loadYamlSafely.js"; +import { ObjectAliasError } from "./utils/validateNoObjectAliases.js"; function writeError(key: string, error: string) { const indented = error