refactor: replace io-ts with zod
This commit is contained in:
parent
fafaefa1fb
commit
28692962bc
161 changed files with 1450 additions and 2105 deletions
backend/src/plugins/Automod/triggers
antiraidLevel.tsanyMessage.tsavailableTriggers.tsban.tscounterTrigger.tsexampleTrigger.tskick.tsmatchAttachmentType.tsmatchInvites.tsmatchLinks.tsmatchMimeType.tsmatchRegex.tsmatchWords.tsmemberJoin.tsmemberJoinSpam.tsmemberLeave.tsmute.tsnote.tsroleAdded.tsroleRemoved.tsthreadArchive.tsthreadCreate.tsthreadCreateSpam.tsthreadDelete.tsthreadUnarchive.tsunban.tsunmute.tswarn.ts
|
@ -1,15 +1,14 @@
|
|||
import * as t from "io-ts";
|
||||
import { tNullable } from "../../../utils";
|
||||
import { automodTrigger } from "../helpers";
|
||||
import z from "zod";
|
||||
|
||||
interface AntiraidLevelTriggerResult {}
|
||||
|
||||
export const AntiraidLevelTrigger = automodTrigger<AntiraidLevelTriggerResult>()({
|
||||
configType: t.type({
|
||||
level: tNullable(t.string),
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
level: z.nullable(z.string().max(100)),
|
||||
});
|
||||
|
||||
defaultConfig: {},
|
||||
export const AntiraidLevelTrigger = automodTrigger<AntiraidLevelTriggerResult>()({
|
||||
configSchema,
|
||||
|
||||
async match({ triggerConfig, context }) {
|
||||
if (!context.antiraid) {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { Snowflake } from "discord.js";
|
||||
import * as t from "io-ts";
|
||||
import { verboseChannelMention } from "../../../utils";
|
||||
import { automodTrigger } from "../helpers";
|
||||
import z from "zod";
|
||||
|
||||
interface AnyMessageResultType {}
|
||||
|
||||
export const AnyMessageTrigger = automodTrigger<AnyMessageResultType>()({
|
||||
configType: t.type({}),
|
||||
const configSchema = z.strictObject({});
|
||||
|
||||
defaultConfig: {},
|
||||
export const AnyMessageTrigger = automodTrigger<AnyMessageResultType>()({
|
||||
configSchema,
|
||||
|
||||
async match({ context }) {
|
||||
if (!context.message) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import * as t from "io-ts";
|
||||
import { AutomodTriggerBlueprint } from "../helpers";
|
||||
import { AntiraidLevelTrigger } from "./antiraidLevel";
|
||||
import { AnyMessageTrigger } from "./anyMessage";
|
||||
|
@ -45,6 +44,7 @@ export const availableTriggers: Record<string, AutomodTriggerBlueprint<any, any>
|
|||
match_attachment_type: MatchAttachmentTypeTrigger,
|
||||
match_mime_type: MatchMimeTypeTrigger,
|
||||
member_join: MemberJoinTrigger,
|
||||
member_leave: MemberLeaveTrigger,
|
||||
role_added: RoleAddedTrigger,
|
||||
role_removed: RoleRemovedTrigger,
|
||||
|
||||
|
@ -76,46 +76,3 @@ export const availableTriggers: Record<string, AutomodTriggerBlueprint<any, any>
|
|||
thread_archive: ThreadArchiveTrigger,
|
||||
thread_unarchive: ThreadUnarchiveTrigger,
|
||||
};
|
||||
|
||||
export const AvailableTriggers = t.type({
|
||||
any_message: AnyMessageTrigger.configType,
|
||||
|
||||
match_words: MatchWordsTrigger.configType,
|
||||
match_regex: MatchRegexTrigger.configType,
|
||||
match_invites: MatchInvitesTrigger.configType,
|
||||
match_links: MatchLinksTrigger.configType,
|
||||
match_attachment_type: MatchAttachmentTypeTrigger.configType,
|
||||
match_mime_type: MatchMimeTypeTrigger.configType,
|
||||
member_join: MemberJoinTrigger.configType,
|
||||
member_leave: MemberLeaveTrigger.configType,
|
||||
role_added: RoleAddedTrigger.configType,
|
||||
role_removed: RoleRemovedTrigger.configType,
|
||||
|
||||
message_spam: MessageSpamTrigger.configType,
|
||||
mention_spam: MentionSpamTrigger.configType,
|
||||
link_spam: LinkSpamTrigger.configType,
|
||||
attachment_spam: AttachmentSpamTrigger.configType,
|
||||
emoji_spam: EmojiSpamTrigger.configType,
|
||||
line_spam: LineSpamTrigger.configType,
|
||||
character_spam: CharacterSpamTrigger.configType,
|
||||
member_join_spam: MemberJoinSpamTrigger.configType,
|
||||
sticker_spam: StickerSpamTrigger.configType,
|
||||
thread_create_spam: ThreadCreateSpamTrigger.configType,
|
||||
|
||||
counter_trigger: CounterTrigger.configType,
|
||||
|
||||
note: NoteTrigger.configType,
|
||||
warn: WarnTrigger.configType,
|
||||
mute: MuteTrigger.configType,
|
||||
unmute: UnmuteTrigger.configType,
|
||||
kick: KickTrigger.configType,
|
||||
ban: BanTrigger.configType,
|
||||
unban: UnbanTrigger.configType,
|
||||
|
||||
antiraid_level: AntiraidLevelTrigger.configType,
|
||||
|
||||
thread_create: ThreadCreateTrigger.configType,
|
||||
thread_delete: ThreadDeleteTrigger.configType,
|
||||
thread_archive: ThreadArchiveTrigger.configType,
|
||||
thread_unarchive: ThreadUnarchiveTrigger.configType,
|
||||
});
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
interface BanTriggerResultType {}
|
||||
|
||||
export const BanTrigger = automodTrigger<BanTriggerResultType>()({
|
||||
configType: t.type({
|
||||
manual: t.boolean,
|
||||
automatic: t.boolean,
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
manual: z.boolean().default(true),
|
||||
automatic: z.boolean().default(true),
|
||||
});
|
||||
|
||||
defaultConfig: {
|
||||
manual: true,
|
||||
automatic: true,
|
||||
},
|
||||
export const BanTrigger = automodTrigger<BanTriggerResultType>()({
|
||||
configSchema,
|
||||
|
||||
async match({ context, triggerConfig }) {
|
||||
if (context.modAction?.type !== "ban") {
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
import * as t from "io-ts";
|
||||
import { tNullable } from "../../../utils";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
// tslint:disable-next-line
|
||||
interface CounterTriggerResult {}
|
||||
|
||||
export const CounterTrigger = automodTrigger<CounterTriggerResult>()({
|
||||
configType: t.type({
|
||||
counter: t.string,
|
||||
trigger: t.string,
|
||||
reverse: tNullable(t.boolean),
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
counter: z.string().max(100),
|
||||
trigger: z.string().max(100),
|
||||
reverse: z.boolean().optional(),
|
||||
});
|
||||
|
||||
defaultConfig: {},
|
||||
export const CounterTrigger = automodTrigger<CounterTriggerResult>()({
|
||||
configSchema,
|
||||
|
||||
async match({ triggerConfig, context }) {
|
||||
if (!context.counterTrigger) {
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
interface ExampleMatchResultType {
|
||||
isBanana: boolean;
|
||||
}
|
||||
|
||||
export const ExampleTrigger = automodTrigger<ExampleMatchResultType>()({
|
||||
configType: t.type({
|
||||
allowedFruits: t.array(t.string),
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
allowedFruits: z.array(z.string().max(100)).max(50).default(["peach", "banana"]),
|
||||
});
|
||||
|
||||
defaultConfig: {
|
||||
allowedFruits: ["peach", "banana"],
|
||||
},
|
||||
export const ExampleTrigger = automodTrigger<ExampleMatchResultType>()({
|
||||
configSchema,
|
||||
|
||||
async match({ triggerConfig, context }) {
|
||||
const foundFruit = triggerConfig.allowedFruits.find((fruit) => context.message?.data.content === fruit);
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
interface KickTriggerResultType {}
|
||||
|
||||
export const KickTrigger = automodTrigger<KickTriggerResultType>()({
|
||||
configType: t.type({
|
||||
manual: t.boolean,
|
||||
automatic: t.boolean,
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
manual: z.boolean().default(true),
|
||||
automatic: z.boolean().default(true),
|
||||
});
|
||||
|
||||
defaultConfig: {
|
||||
manual: true,
|
||||
automatic: true,
|
||||
},
|
||||
export const KickTrigger = automodTrigger<KickTriggerResultType>()({
|
||||
configSchema,
|
||||
|
||||
async match({ context, triggerConfig }) {
|
||||
if (context.modAction?.type !== "kick") {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { escapeInlineCode, Snowflake } from "discord.js";
|
||||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { asSingleLine, messageSummary, verboseChannelMention } from "../../../utils";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
|
@ -8,20 +8,31 @@ interface MatchResultType {
|
|||
mode: "blacklist" | "whitelist";
|
||||
}
|
||||
|
||||
export const MatchAttachmentTypeTrigger = automodTrigger<MatchResultType>()({
|
||||
configType: t.type({
|
||||
filetype_blacklist: t.array(t.string),
|
||||
blacklist_enabled: t.boolean,
|
||||
filetype_whitelist: t.array(t.string),
|
||||
whitelist_enabled: t.boolean,
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
filetype_blacklist: z.array(z.string().max(32)).max(255).default([]),
|
||||
blacklist_enabled: z.boolean().default(false),
|
||||
filetype_whitelist: z.array(z.string().max(32)).max(255).default([]),
|
||||
whitelist_enabled: z.boolean().default(false),
|
||||
}).transform((parsed, ctx) => {
|
||||
if (parsed.blacklist_enabled && parsed.whitelist_enabled) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: "Cannot have both blacklist and whitelist enabled",
|
||||
});
|
||||
return z.NEVER;
|
||||
}
|
||||
if (! parsed.blacklist_enabled && ! parsed.whitelist_enabled) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: "Must have either blacklist or whitelist enabled",
|
||||
});
|
||||
return z.NEVER;
|
||||
}
|
||||
return parsed;
|
||||
});
|
||||
|
||||
defaultConfig: {
|
||||
filetype_blacklist: [],
|
||||
blacklist_enabled: false,
|
||||
filetype_whitelist: [],
|
||||
whitelist_enabled: false,
|
||||
},
|
||||
export const MatchAttachmentTypeTrigger = automodTrigger<MatchResultType>()({
|
||||
configSchema,
|
||||
|
||||
async match({ context, triggerConfig: trigger }) {
|
||||
if (!context.message) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as t from "io-ts";
|
||||
import { getInviteCodesInString, GuildInvite, isGuildInvite, resolveInvite, tNullable } from "../../../utils";
|
||||
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";
|
||||
|
@ -10,30 +10,22 @@ interface MatchResultType {
|
|||
invite?: GuildInvite;
|
||||
}
|
||||
|
||||
export const MatchInvitesTrigger = automodTrigger<MatchResultType>()({
|
||||
configType: t.type({
|
||||
include_guilds: tNullable(t.array(t.string)),
|
||||
exclude_guilds: tNullable(t.array(t.string)),
|
||||
include_invite_codes: tNullable(t.array(t.string)),
|
||||
exclude_invite_codes: tNullable(t.array(t.string)),
|
||||
allow_group_dm_invites: t.boolean,
|
||||
match_messages: t.boolean,
|
||||
match_embeds: t.boolean,
|
||||
match_visible_names: t.boolean,
|
||||
match_usernames: t.boolean,
|
||||
match_nicknames: t.boolean,
|
||||
match_custom_status: t.boolean,
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
include_guilds: z.array(zSnowflake).max(255).optional(),
|
||||
exclude_guilds: z.array(zSnowflake).max(255).optional(),
|
||||
include_invite_codes: z.array(z.string().max(32)).max(255).optional(),
|
||||
exclude_invite_codes: z.array(z.string().max(32)).max(255).optional(),
|
||||
allow_group_dm_invites: z.boolean().default(false),
|
||||
match_messages: z.boolean().default(true),
|
||||
match_embeds: z.boolean().default(false),
|
||||
match_visible_names: z.boolean().default(false),
|
||||
match_usernames: z.boolean().default(false),
|
||||
match_nicknames: z.boolean().default(false),
|
||||
match_custom_status: z.boolean().default(false),
|
||||
});
|
||||
|
||||
defaultConfig: {
|
||||
allow_group_dm_invites: false,
|
||||
match_messages: true,
|
||||
match_embeds: false,
|
||||
match_visible_names: false,
|
||||
match_usernames: false,
|
||||
match_nicknames: false,
|
||||
match_custom_status: false,
|
||||
},
|
||||
export const MatchInvitesTrigger = automodTrigger<MatchResultType>()({
|
||||
configSchema,
|
||||
|
||||
async match({ pluginData, context, triggerConfig: trigger }) {
|
||||
if (!context.message) {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { escapeInlineCode } from "discord.js";
|
||||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { allowTimeout } from "../../../RegExpRunner";
|
||||
import { phishermanDomainIsSafe } from "../../../data/Phisherman";
|
||||
import { getUrlsInString, tNullable } from "../../../utils";
|
||||
import { getUrlsInString, zRegex } from "../../../utils";
|
||||
import { mergeRegexes } from "../../../utils/mergeRegexes";
|
||||
import { mergeWordsIntoRegex } from "../../../utils/mergeWordsIntoRegex";
|
||||
import { TRegex } from "../../../validatorUtils";
|
||||
import { PhishermanPlugin } from "../../Phisherman/PhishermanPlugin";
|
||||
import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary";
|
||||
import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage";
|
||||
|
@ -21,40 +20,29 @@ const regexCache = new WeakMap<any, RegExp[]>();
|
|||
|
||||
const quickLinkCheck = /^https?:\/\//i;
|
||||
|
||||
export const MatchLinksTrigger = automodTrigger<MatchResultType>()({
|
||||
configType: t.type({
|
||||
include_domains: tNullable(t.array(t.string)),
|
||||
exclude_domains: tNullable(t.array(t.string)),
|
||||
include_subdomains: t.boolean,
|
||||
include_words: tNullable(t.array(t.string)),
|
||||
exclude_words: tNullable(t.array(t.string)),
|
||||
include_regex: tNullable(t.array(TRegex)),
|
||||
exclude_regex: tNullable(t.array(TRegex)),
|
||||
phisherman: tNullable(
|
||||
t.type({
|
||||
include_suspected: tNullable(t.boolean),
|
||||
include_verified: tNullable(t.boolean),
|
||||
}),
|
||||
),
|
||||
only_real_links: t.boolean,
|
||||
match_messages: t.boolean,
|
||||
match_embeds: t.boolean,
|
||||
match_visible_names: t.boolean,
|
||||
match_usernames: t.boolean,
|
||||
match_nicknames: t.boolean,
|
||||
match_custom_status: t.boolean,
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
include_domains: z.array(z.string().max(255)).max(255).optional(),
|
||||
exclude_domains: z.array(z.string().max(255)).max(255).optional(),
|
||||
include_subdomains: z.boolean().default(true),
|
||||
include_words: z.array(z.string().max(2000)).max(512).optional(),
|
||||
exclude_words: z.array(z.string().max(2000)).max(512).optional(),
|
||||
include_regex: z.array(zRegex(z.string().max(2000))).max(512).optional(),
|
||||
exclude_regex: z.array(zRegex(z.string().max(2000))).max(512).optional(),
|
||||
phisherman: z.strictObject({
|
||||
include_suspected: z.boolean().optional(),
|
||||
include_verified: z.boolean().optional(),
|
||||
}).optional(),
|
||||
only_real_links: z.boolean(),
|
||||
match_messages: z.boolean().default(true),
|
||||
match_embeds: z.boolean().default(true),
|
||||
match_visible_names: z.boolean().default(false),
|
||||
match_usernames: z.boolean().default(false),
|
||||
match_nicknames: z.boolean().default(false),
|
||||
match_custom_status: z.boolean().default(false),
|
||||
});
|
||||
|
||||
defaultConfig: {
|
||||
include_subdomains: true,
|
||||
match_messages: true,
|
||||
match_embeds: false,
|
||||
match_visible_names: false,
|
||||
match_usernames: false,
|
||||
match_nicknames: false,
|
||||
match_custom_status: false,
|
||||
only_real_links: true,
|
||||
},
|
||||
export const MatchLinksTrigger = automodTrigger<MatchResultType>()({
|
||||
configSchema,
|
||||
|
||||
async match({ pluginData, context, triggerConfig: trigger }) {
|
||||
if (!context.message) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { escapeInlineCode } from "discord.js";
|
||||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { asSingleLine, messageSummary, verboseChannelMention } from "../../../utils";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
|
@ -8,20 +8,31 @@ interface MatchResultType {
|
|||
mode: "blacklist" | "whitelist";
|
||||
}
|
||||
|
||||
export const MatchMimeTypeTrigger = automodTrigger<MatchResultType>()({
|
||||
configType: t.type({
|
||||
mime_type_blacklist: t.array(t.string),
|
||||
blacklist_enabled: t.boolean,
|
||||
mime_type_whitelist: t.array(t.string),
|
||||
whitelist_enabled: t.boolean,
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
mime_type_blacklist: z.array(z.string().max(255)).max(255).default([]),
|
||||
blacklist_enabled: z.boolean().default(false),
|
||||
mime_type_whitelist: z.array(z.string().max(255)).max(255).default([]),
|
||||
whitelist_enabled: z.boolean().default(false),
|
||||
}).transform((parsed, ctx) => {
|
||||
if (parsed.blacklist_enabled && parsed.whitelist_enabled) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: "Cannot have both blacklist and whitelist enabled",
|
||||
});
|
||||
return z.NEVER;
|
||||
}
|
||||
if (! parsed.blacklist_enabled && ! parsed.whitelist_enabled) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: "Must have either blacklist or whitelist enabled",
|
||||
});
|
||||
return z.NEVER;
|
||||
}
|
||||
return parsed;
|
||||
});
|
||||
|
||||
defaultConfig: {
|
||||
mime_type_blacklist: [],
|
||||
blacklist_enabled: false,
|
||||
mime_type_whitelist: [],
|
||||
whitelist_enabled: false,
|
||||
},
|
||||
export const MatchMimeTypeTrigger = automodTrigger<MatchResultType>()({
|
||||
configSchema,
|
||||
|
||||
async match({ context, triggerConfig: trigger }) {
|
||||
if (!context.message) return;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import * as t from "io-ts";
|
||||
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 { TRegex } from "../../../validatorUtils";
|
||||
import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary";
|
||||
import { MatchableTextType, matchMultipleTextTypesOnMessage } from "../functions/matchMultipleTextTypesOnMessage";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
@ -13,33 +13,23 @@ interface MatchResultType {
|
|||
type: MatchableTextType;
|
||||
}
|
||||
|
||||
const configSchema = z.strictObject({
|
||||
patterns: z.array(zRegex(z.string().max(2000))).max(512),
|
||||
case_sensitive: z.boolean().default(false),
|
||||
normalize: z.boolean().default(false),
|
||||
strip_markdown: z.boolean().default(false),
|
||||
match_messages: z.boolean().default(true),
|
||||
match_embeds: z.boolean().default(false),
|
||||
match_visible_names: z.boolean().default(false),
|
||||
match_usernames: z.boolean().default(false),
|
||||
match_nicknames: z.boolean().default(false),
|
||||
match_custom_status: z.boolean().default(false),
|
||||
});
|
||||
|
||||
const regexCache = new WeakMap<any, RegExp[]>();
|
||||
|
||||
export const MatchRegexTrigger = automodTrigger<MatchResultType>()({
|
||||
configType: t.type({
|
||||
patterns: t.array(TRegex),
|
||||
case_sensitive: t.boolean,
|
||||
normalize: t.boolean,
|
||||
strip_markdown: t.boolean,
|
||||
match_messages: t.boolean,
|
||||
match_embeds: t.boolean,
|
||||
match_visible_names: t.boolean,
|
||||
match_usernames: t.boolean,
|
||||
match_nicknames: t.boolean,
|
||||
match_custom_status: t.boolean,
|
||||
}),
|
||||
|
||||
defaultConfig: {
|
||||
case_sensitive: false,
|
||||
normalize: false,
|
||||
strip_markdown: false,
|
||||
match_messages: true,
|
||||
match_embeds: false,
|
||||
match_visible_names: false,
|
||||
match_usernames: false,
|
||||
match_nicknames: false,
|
||||
match_custom_status: false,
|
||||
},
|
||||
configSchema,
|
||||
|
||||
async match({ pluginData, context, triggerConfig: trigger }) {
|
||||
if (!context.message) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import escapeStringRegexp from "escape-string-regexp";
|
||||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { normalizeText } from "../../../utils/normalizeText";
|
||||
import { stripMarkdown } from "../../../utils/stripMarkdown";
|
||||
import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary";
|
||||
|
@ -13,37 +13,24 @@ interface MatchResultType {
|
|||
|
||||
const regexCache = new WeakMap<any, RegExp[]>();
|
||||
|
||||
export const MatchWordsTrigger = automodTrigger<MatchResultType>()({
|
||||
configType: t.type({
|
||||
words: t.array(t.string),
|
||||
case_sensitive: t.boolean,
|
||||
only_full_words: t.boolean,
|
||||
normalize: t.boolean,
|
||||
loose_matching: t.boolean,
|
||||
loose_matching_threshold: t.number,
|
||||
strip_markdown: t.boolean,
|
||||
match_messages: t.boolean,
|
||||
match_embeds: t.boolean,
|
||||
match_visible_names: t.boolean,
|
||||
match_usernames: t.boolean,
|
||||
match_nicknames: t.boolean,
|
||||
match_custom_status: t.boolean,
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
words: z.array(z.string().max(2000)).max(512),
|
||||
case_sensitive: z.boolean().default(false),
|
||||
only_full_words: z.boolean().default(true),
|
||||
normalize: z.boolean().default(false),
|
||||
loose_matching: z.boolean().default(false),
|
||||
loose_matching_threshold: z.number().int().default(4),
|
||||
strip_markdown: z.boolean().default(false),
|
||||
match_messages: z.boolean().default(true),
|
||||
match_embeds: z.boolean().default(false),
|
||||
match_visible_names: z.boolean().default(false),
|
||||
match_usernames: z.boolean().default(false),
|
||||
match_nicknames: z.boolean().default(false),
|
||||
match_custom_status: z.boolean().default(false),
|
||||
});
|
||||
|
||||
defaultConfig: {
|
||||
case_sensitive: false,
|
||||
only_full_words: true,
|
||||
normalize: false,
|
||||
loose_matching: false,
|
||||
loose_matching_threshold: 4,
|
||||
strip_markdown: false,
|
||||
match_messages: true,
|
||||
match_embeds: false,
|
||||
match_visible_names: false,
|
||||
match_usernames: false,
|
||||
match_nicknames: false,
|
||||
match_custom_status: false,
|
||||
},
|
||||
export const MatchWordsTrigger = automodTrigger<MatchResultType>()({
|
||||
configSchema,
|
||||
|
||||
async match({ pluginData, context, triggerConfig: trigger }) {
|
||||
if (!context.message) {
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
import * as t from "io-ts";
|
||||
import { convertDelayStringToMS, tDelayString } from "../../../utils";
|
||||
import z from "zod";
|
||||
import { convertDelayStringToMS, zDelayString } from "../../../utils";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
export const MemberJoinTrigger = automodTrigger<unknown>()({
|
||||
configType: t.type({
|
||||
only_new: t.boolean,
|
||||
new_threshold: tDelayString,
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
only_new: z.boolean().default(false),
|
||||
new_threshold: zDelayString.default("1h"),
|
||||
});
|
||||
|
||||
defaultConfig: {
|
||||
only_new: false,
|
||||
new_threshold: "1h",
|
||||
},
|
||||
export const MemberJoinTrigger = automodTrigger<unknown>()({
|
||||
configSchema,
|
||||
|
||||
async match({ context, triggerConfig }) {
|
||||
if (!context.joined || !context.member) {
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import * as t from "io-ts";
|
||||
import { convertDelayStringToMS, tDelayString } from "../../../utils";
|
||||
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";
|
||||
|
||||
export const MemberJoinSpamTrigger = automodTrigger<unknown>()({
|
||||
configType: t.type({
|
||||
amount: t.number,
|
||||
within: tDelayString,
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
amount: z.number().int(),
|
||||
within: zDelayString,
|
||||
});
|
||||
|
||||
defaultConfig: {},
|
||||
export const MemberJoinSpamTrigger = automodTrigger<unknown>()({
|
||||
configSchema,
|
||||
|
||||
async match({ pluginData, context, triggerConfig }) {
|
||||
if (!context.joined || !context.member) {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
export const MemberLeaveTrigger = automodTrigger<unknown>()({
|
||||
configType: t.type({}),
|
||||
const configSchema = z.strictObject({});
|
||||
|
||||
defaultConfig: {},
|
||||
export const MemberLeaveTrigger = automodTrigger<unknown>()({
|
||||
configSchema,
|
||||
|
||||
async match({ context }) {
|
||||
if (!context.joined || !context.member) {
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
interface MuteTriggerResultType {}
|
||||
|
||||
export const MuteTrigger = automodTrigger<MuteTriggerResultType>()({
|
||||
configType: t.type({
|
||||
manual: t.boolean,
|
||||
automatic: t.boolean,
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
manual: z.boolean().default(true),
|
||||
automatic: z.boolean().default(true),
|
||||
});
|
||||
|
||||
defaultConfig: {
|
||||
manual: true,
|
||||
automatic: true,
|
||||
},
|
||||
export const MuteTrigger = automodTrigger<MuteTriggerResultType>()({
|
||||
configSchema,
|
||||
|
||||
async match({ context, triggerConfig }) {
|
||||
if (context.modAction?.type !== "mute") {
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
interface NoteTriggerResultType {}
|
||||
|
||||
const configSchema = z.strictObject({});
|
||||
|
||||
export const NoteTrigger = automodTrigger<NoteTriggerResultType>()({
|
||||
configType: t.type({}),
|
||||
defaultConfig: {},
|
||||
configSchema,
|
||||
|
||||
async match({ context }) {
|
||||
if (context.modAction?.type !== "note") {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Snowflake } from "discord.js";
|
||||
import * as t from "io-ts";
|
||||
import { renderUserUsername } from "../../../utils";
|
||||
import z from "zod";
|
||||
import { renderUserUsername, zSnowflake } from "../../../utils";
|
||||
import { consumeIgnoredRoleChange } from "../functions/ignoredRoleChanges";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
|
@ -8,10 +8,13 @@ interface RoleAddedMatchResult {
|
|||
matchedRoleId: string;
|
||||
}
|
||||
|
||||
export const RoleAddedTrigger = automodTrigger<RoleAddedMatchResult>()({
|
||||
configType: t.union([t.string, t.array(t.string)]),
|
||||
const configSchema = z.union([
|
||||
zSnowflake,
|
||||
z.array(zSnowflake).max(255),
|
||||
]).default([]);
|
||||
|
||||
defaultConfig: "",
|
||||
export const RoleAddedTrigger = automodTrigger<RoleAddedMatchResult>()({
|
||||
configSchema,
|
||||
|
||||
async match({ triggerConfig, context, pluginData }) {
|
||||
if (!context.member || !context.rolesChanged || context.rolesChanged.added!.length === 0) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Snowflake } from "discord.js";
|
||||
import * as t from "io-ts";
|
||||
import { renderUserUsername } from "../../../utils";
|
||||
import z from "zod";
|
||||
import { renderUserUsername, zSnowflake } from "../../../utils";
|
||||
import { consumeIgnoredRoleChange } from "../functions/ignoredRoleChanges";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
|
@ -8,10 +8,13 @@ interface RoleAddedMatchResult {
|
|||
matchedRoleId: string;
|
||||
}
|
||||
|
||||
export const RoleRemovedTrigger = automodTrigger<RoleAddedMatchResult>()({
|
||||
configType: t.union([t.string, t.array(t.string)]),
|
||||
const configSchema = z.union([
|
||||
zSnowflake,
|
||||
z.array(zSnowflake).max(255),
|
||||
]).default([]);
|
||||
|
||||
defaultConfig: "",
|
||||
export const RoleRemovedTrigger = automodTrigger<RoleAddedMatchResult>()({
|
||||
configSchema,
|
||||
|
||||
async match({ triggerConfig, context, pluginData }) {
|
||||
if (!context.member || !context.rolesChanged || context.rolesChanged.removed!.length === 0) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { User, escapeBold, type Snowflake } from "discord.js";
|
||||
import * as t from "io-ts";
|
||||
import { tNullable } from "../../../utils";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
interface ThreadArchiveResult {
|
||||
|
@ -11,12 +10,12 @@ interface ThreadArchiveResult {
|
|||
matchedThreadOwner: User | undefined;
|
||||
}
|
||||
|
||||
export const ThreadArchiveTrigger = automodTrigger<ThreadArchiveResult>()({
|
||||
configType: t.type({
|
||||
locked: tNullable(t.boolean),
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
locked: z.boolean().optional(),
|
||||
});
|
||||
|
||||
defaultConfig: {},
|
||||
export const ThreadArchiveTrigger = automodTrigger<ThreadArchiveResult>()({
|
||||
configSchema,
|
||||
|
||||
async match({ context, triggerConfig }) {
|
||||
if (!context.threadChange?.archived) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { User, escapeBold, type Snowflake } from "discord.js";
|
||||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
interface ThreadCreateResult {
|
||||
|
@ -10,9 +10,10 @@ interface ThreadCreateResult {
|
|||
matchedThreadOwner: User | undefined;
|
||||
}
|
||||
|
||||
const configSchema = z.strictObject({});
|
||||
|
||||
export const ThreadCreateTrigger = automodTrigger<ThreadCreateResult>()({
|
||||
configType: t.type({}),
|
||||
defaultConfig: {},
|
||||
configSchema,
|
||||
|
||||
async match({ context }) {
|
||||
if (!context.threadChange?.created) {
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import * as t from "io-ts";
|
||||
import { convertDelayStringToMS, tDelayString } from "../../../utils";
|
||||
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";
|
||||
|
||||
export const ThreadCreateSpamTrigger = automodTrigger<unknown>()({
|
||||
configType: t.type({
|
||||
amount: t.number,
|
||||
within: tDelayString,
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
amount: z.number().int(),
|
||||
within: zDelayString,
|
||||
});
|
||||
|
||||
defaultConfig: {},
|
||||
export const ThreadCreateSpamTrigger = automodTrigger<unknown>()({
|
||||
configSchema,
|
||||
|
||||
async match({ pluginData, context, triggerConfig }) {
|
||||
if (!context.threadChange?.created) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { User, escapeBold, type Snowflake } from "discord.js";
|
||||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
interface ThreadDeleteResult {
|
||||
|
@ -10,9 +10,10 @@ interface ThreadDeleteResult {
|
|||
matchedThreadOwner: User | undefined;
|
||||
}
|
||||
|
||||
const configSchema = z.strictObject({});
|
||||
|
||||
export const ThreadDeleteTrigger = automodTrigger<ThreadDeleteResult>()({
|
||||
configType: t.type({}),
|
||||
defaultConfig: {},
|
||||
configSchema,
|
||||
|
||||
async match({ context }) {
|
||||
if (!context.threadChange?.deleted) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { User, escapeBold, type Snowflake } from "discord.js";
|
||||
import * as t from "io-ts";
|
||||
import { tNullable } from "../../../utils";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
interface ThreadUnarchiveResult {
|
||||
|
@ -11,12 +10,12 @@ interface ThreadUnarchiveResult {
|
|||
matchedThreadOwner: User | undefined;
|
||||
}
|
||||
|
||||
export const ThreadUnarchiveTrigger = automodTrigger<ThreadUnarchiveResult>()({
|
||||
configType: t.type({
|
||||
locked: tNullable(t.boolean),
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
locked: z.boolean().optional(),
|
||||
});
|
||||
|
||||
defaultConfig: {},
|
||||
export const ThreadUnarchiveTrigger = automodTrigger<ThreadUnarchiveResult>()({
|
||||
configSchema,
|
||||
|
||||
async match({ context, triggerConfig }) {
|
||||
if (!context.threadChange?.unarchived) {
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
interface UnbanTriggerResultType {}
|
||||
|
||||
const configSchema = z.strictObject({});
|
||||
|
||||
export const UnbanTrigger = automodTrigger<UnbanTriggerResultType>()({
|
||||
configType: t.type({}),
|
||||
defaultConfig: {},
|
||||
configSchema,
|
||||
|
||||
async match({ context }) {
|
||||
if (context.modAction?.type !== "unban") {
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
interface UnmuteTriggerResultType {}
|
||||
|
||||
const configSchema = z.strictObject({});
|
||||
|
||||
export const UnmuteTrigger = automodTrigger<UnmuteTriggerResultType>()({
|
||||
configType: t.type({}),
|
||||
defaultConfig: {},
|
||||
configSchema,
|
||||
|
||||
async match({ context }) {
|
||||
if (context.modAction?.type !== "unmute") {
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
import * as t from "io-ts";
|
||||
import z from "zod";
|
||||
import { automodTrigger } from "../helpers";
|
||||
|
||||
// tslint:disable-next-line:no-empty-interface
|
||||
interface WarnTriggerResultType {}
|
||||
|
||||
export const WarnTrigger = automodTrigger<WarnTriggerResultType>()({
|
||||
configType: t.type({
|
||||
manual: t.boolean,
|
||||
automatic: t.boolean,
|
||||
}),
|
||||
const configSchema = z.strictObject({
|
||||
manual: z.boolean().default(true),
|
||||
automatic: z.boolean().default(true),
|
||||
});
|
||||
|
||||
defaultConfig: {
|
||||
manual: true,
|
||||
automatic: true,
|
||||
},
|
||||
export const WarnTrigger = automodTrigger<WarnTriggerResultType>()({
|
||||
configSchema,
|
||||
|
||||
async match({ context, triggerConfig }) {
|
||||
if (context.modAction?.type !== "warn") {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue