diff --git a/backend/src/plugins/Automod/actions/addRoles.ts b/backend/src/plugins/Automod/actions/addRoles.ts index 47b55c2c..05829a12 100644 --- a/backend/src/plugins/Automod/actions/addRoles.ts +++ b/backend/src/plugins/Automod/actions/addRoles.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; -import { asyncMap, resolveMember, tNullable } from "../../../utils"; +import { asyncMap, resolveMember, tNullable, unique } from "../../../utils"; import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; @@ -9,11 +9,10 @@ export const AddRolesAction = automodAction({ configType: t.array(t.string), async apply({ pluginData, contexts, actionConfig }) { - const members = contexts.map(c => c.member).filter(Boolean); - const uniqueMembers = new Set(members); + const members = unique(contexts.map(c => c.member).filter(Boolean)); await Promise.all( - Array.from(uniqueMembers.values()).map(async member => { + members.map(async member => { const memberRoles = new Set(member.roles); for (const roleId of actionConfig) { memberRoles.add(roleId); diff --git a/backend/src/plugins/Automod/actions/ban.ts b/backend/src/plugins/Automod/actions/ban.ts index 2fd2e025..4a0bf3c0 100644 --- a/backend/src/plugins/Automod/actions/ban.ts +++ b/backend/src/plugins/Automod/actions/ban.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; -import { asyncMap, resolveMember, tNullable } from "../../../utils"; +import { asyncMap, resolveMember, tNullable, unique } from "../../../utils"; import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; @@ -25,7 +25,7 @@ export const BanAction = automodAction({ ], }; - const userIdsToBan = contexts.map(c => c.user?.id).filter(Boolean); + const userIdsToBan = unique(contexts.map(c => c.user?.id).filter(Boolean)); const modActions = pluginData.getPlugin(ModActionsPlugin); for (const userId of userIdsToBan) { diff --git a/backend/src/plugins/Automod/actions/changeNickname.ts b/backend/src/plugins/Automod/actions/changeNickname.ts index 46358aa2..b3bf512b 100644 --- a/backend/src/plugins/Automod/actions/changeNickname.ts +++ b/backend/src/plugins/Automod/actions/changeNickname.ts @@ -2,6 +2,7 @@ import * as t from "io-ts"; import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; import { LogsPlugin } from "../../Logs/LogsPlugin"; +import { unique } from "../../../utils"; export const ChangeNicknameAction = automodAction({ configType: t.type({ @@ -9,10 +10,9 @@ export const ChangeNicknameAction = automodAction({ }), async apply({ pluginData, contexts, actionConfig }) { - const members = contexts.map(c => c.member).filter(Boolean); - const uniqueMembers = new Set(members); + const members = unique(contexts.map(c => c.member).filter(Boolean)); - for (const member of uniqueMembers) { + for (const member of members) { if (pluginData.state.recentNicknameChanges.has(member.id)) continue; member.edit({ nick: actionConfig.name }).catch(err => { diff --git a/backend/src/plugins/Automod/actions/kick.ts b/backend/src/plugins/Automod/actions/kick.ts index 88c6e488..5b9044f1 100644 --- a/backend/src/plugins/Automod/actions/kick.ts +++ b/backend/src/plugins/Automod/actions/kick.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; -import { asyncMap, resolveMember, tNullable } from "../../../utils"; +import { asyncMap, resolveMember, tNullable, unique } from "../../../utils"; import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; @@ -23,7 +23,7 @@ export const KickAction = automodAction({ ], }; - const userIdsToKick = contexts.map(c => c.user?.id).filter(Boolean); + const userIdsToKick = unique(contexts.map(c => c.user?.id).filter(Boolean)); const membersToKick = await asyncMap(userIdsToKick, id => resolveMember(pluginData.client, pluginData.guild, id)); const modActions = pluginData.getPlugin(ModActionsPlugin); diff --git a/backend/src/plugins/Automod/actions/mute.ts b/backend/src/plugins/Automod/actions/mute.ts index 9ae042eb..a11ac218 100644 --- a/backend/src/plugins/Automod/actions/mute.ts +++ b/backend/src/plugins/Automod/actions/mute.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; -import { asyncMap, convertDelayStringToMS, resolveMember, tDelayString, tNullable } from "../../../utils"; +import { asyncMap, convertDelayStringToMS, resolveMember, tDelayString, tNullable, unique } from "../../../utils"; import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; import { MutesPlugin } from "../../Mutes/MutesPlugin"; @@ -26,7 +26,7 @@ export const MuteAction = automodAction({ ], }; - const userIdsToMute = contexts.map(c => c.user?.id).filter(Boolean); + const userIdsToMute = unique(contexts.map(c => c.user?.id).filter(Boolean)); const mutes = pluginData.getPlugin(MutesPlugin); for (const userId of userIdsToMute) { diff --git a/backend/src/plugins/Automod/actions/removeRoles.ts b/backend/src/plugins/Automod/actions/removeRoles.ts index fd27bb1d..5b692c89 100644 --- a/backend/src/plugins/Automod/actions/removeRoles.ts +++ b/backend/src/plugins/Automod/actions/removeRoles.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; -import { asyncMap, resolveMember, tNullable } from "../../../utils"; +import { asyncMap, resolveMember, tNullable, unique } from "../../../utils"; import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; @@ -9,11 +9,10 @@ export const RemoveRolesAction = automodAction({ configType: t.array(t.string), async apply({ pluginData, contexts, actionConfig }) { - const members = contexts.map(c => c.member).filter(Boolean); - const uniqueMembers = new Set(members); + const members = unique(contexts.map(c => c.member).filter(Boolean)); await Promise.all( - Array.from(uniqueMembers.values()).map(async member => { + members.map(async member => { const memberRoles = new Set(member.roles); for (const roleId of actionConfig) { memberRoles.delete(roleId); diff --git a/backend/src/plugins/Automod/actions/reply.ts b/backend/src/plugins/Automod/actions/reply.ts index 85353820..66a164f9 100644 --- a/backend/src/plugins/Automod/actions/reply.ts +++ b/backend/src/plugins/Automod/actions/reply.ts @@ -8,6 +8,7 @@ import { tDelayString, tMessageContent, tNullable, + unique, } from "../../../utils"; import { TextChannel } from "eris"; import { AutomodContext } from "../types"; @@ -37,7 +38,7 @@ export const ReplyAction = automodAction({ }, new Map()); for (const [channelId, _contexts] of contextsByChannelId.entries()) { - const users = Array.from(new Set(_contexts.map(c => c.user).filter(Boolean))); + const users = unique(Array.from(new Set(_contexts.map(c => c.user).filter(Boolean)))); const user = users[0]; const renderReplyText = async str => diff --git a/backend/src/plugins/Automod/actions/warn.ts b/backend/src/plugins/Automod/actions/warn.ts index 7e17c841..279ba1dc 100644 --- a/backend/src/plugins/Automod/actions/warn.ts +++ b/backend/src/plugins/Automod/actions/warn.ts @@ -1,7 +1,7 @@ import * as t from "io-ts"; import { automodAction } from "../helpers"; import { LogType } from "../../../data/LogType"; -import { asyncMap, resolveMember, tNullable } from "../../../utils"; +import { asyncMap, resolveMember, tNullable, unique } from "../../../utils"; import { resolveActionContactMethods } from "../functions/resolveActionContactMethods"; import { ModActionsPlugin } from "../../ModActions/ModActionsPlugin"; @@ -23,7 +23,7 @@ export const WarnAction = automodAction({ ], }; - const userIdsToWarn = contexts.map(c => c.user?.id).filter(Boolean); + const userIdsToWarn = unique(contexts.map(c => c.user?.id).filter(Boolean)); const membersToWarn = await asyncMap(userIdsToWarn, id => resolveMember(pluginData.client, pluginData.guild, id)); const modActions = pluginData.getPlugin(ModActionsPlugin); diff --git a/backend/src/utils.ts b/backend/src/utils.ts index 967c3a3d..3106a3a6 100644 --- a/backend/src/utils.ts +++ b/backend/src/utils.ts @@ -423,9 +423,11 @@ interface MatchedURL extends url.URL { input: string; } -export function getUrlsInString(str: string, unique = false): MatchedURL[] { +export function getUrlsInString(str: string, onlyUnique = false): MatchedURL[] { let matches = str.match(urlRegex) || []; - if (unique) matches = Array.from(new Set(matches)); + if (onlyUnique) { + matches = unique(matches); + } return matches.reduce((urls, match) => { const withProtocol = protocolRegex.test(match) ? match : `https://${match}`; @@ -1230,3 +1232,7 @@ export function isGuildInvite(invite: AnyInvite): invite is GuildInvite { export function asyncMap(arr: T[], fn: (item: T) => Promise): Promise { return Promise.all(arr.map((item, index) => fn(item))); } + +export function unique(arr: T[]): T[] { + return Array.from(new Set(arr)); +}