diff --git a/backend/src/plugins/Automod/functions/applyCooldown.ts b/backend/src/plugins/Automod/functions/applyCooldown.ts index ff1bc44d..e0f93977 100644 --- a/backend/src/plugins/Automod/functions/applyCooldown.ts +++ b/backend/src/plugins/Automod/functions/applyCooldown.ts @@ -2,8 +2,8 @@ import { GuildPluginData } from "knub"; 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}`; +export function applyCooldown(pluginData: GuildPluginData, rule: TRule, ruleName: string, context: AutomodContext) { + const cooldownKey = `${ruleName}-${context.user?.id}`; const cooldownTime = convertDelayStringToMS(rule.cooldown, "s"); if (cooldownTime) pluginData.state.cooldownManager.setCooldown(cooldownKey, cooldownTime); diff --git a/backend/src/plugins/Automod/functions/checkCooldown.ts b/backend/src/plugins/Automod/functions/checkCooldown.ts index 0f45485f..b7e0902e 100644 --- a/backend/src/plugins/Automod/functions/checkCooldown.ts +++ b/backend/src/plugins/Automod/functions/checkCooldown.ts @@ -1,8 +1,8 @@ import { GuildPluginData } from "knub"; import { AutomodContext, AutomodPluginType, TRule } from "../types.js"; -export function checkCooldown(pluginData: GuildPluginData, rule: TRule, context: AutomodContext) { - const cooldownKey = `${rule.name}-${context.user?.id}`; +export function checkCooldown(pluginData: GuildPluginData, rule: TRule, ruleName: string, context: AutomodContext) { + const cooldownKey = `${ruleName}-${context.user?.id}`; return pluginData.state.cooldownManager.isOnCooldown(cooldownKey); } diff --git a/backend/src/plugins/Automod/functions/runAutomod.ts b/backend/src/plugins/Automod/functions/runAutomod.ts index 63e5128f..f17c8d1a 100644 --- a/backend/src/plugins/Automod/functions/runAutomod.ts +++ b/backend/src/plugins/Automod/functions/runAutomod.ts @@ -49,7 +49,7 @@ export async function runAutomod(pluginData: GuildPluginData, } if (!rule.affects_self && userId && userId === pluginData.client.user?.id) continue; - if (rule.cooldown && checkCooldown(pluginData, rule, context)) { + if (rule.cooldown && checkCooldown(pluginData, rule, ruleName, context)) { continue; } @@ -87,7 +87,7 @@ export async function runAutomod(pluginData: GuildPluginData, } if (matchResult) { - if (rule.cooldown) applyCooldown(pluginData, rule, context); + if (rule.cooldown) applyCooldown(pluginData, rule, ruleName, context); contexts = [context, ...(matchResult.extraContexts || [])]; diff --git a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts index 5c871cc5..09e8ea2f 100644 --- a/backend/src/plugins/Automod/triggers/matchAttachmentType.ts +++ b/backend/src/plugins/Automod/triggers/matchAttachmentType.ts @@ -9,30 +9,23 @@ interface MatchResultType { mode: "blacklist" | "whitelist"; } -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; - }); +const baseConfig = z.strictObject({ + filetype_blacklist: z.array(z.string().max(32)).max(255).default([]), + filetype_whitelist: z.array(z.string().max(32)).max(255).default([]), +}); +const configWithWhitelist = baseConfig.merge(z.strictObject({ + whitelist_enabled: z.literal(true), + blacklist_enabled: z.literal(false).default(false), +})); +const configWithBlacklist = baseConfig.merge(z.strictObject({ + blacklist_enabled: z.literal(true), + whitelist_enabled: z.literal(false).default(false), +})); + +const configSchema = z.union([ + configWithWhitelist, + configWithBlacklist, +]); export const MatchAttachmentTypeTrigger = automodTrigger()({ configSchema, diff --git a/backend/src/plugins/Automod/triggers/matchMimeType.ts b/backend/src/plugins/Automod/triggers/matchMimeType.ts index 725665e4..684e8c8f 100644 --- a/backend/src/plugins/Automod/triggers/matchMimeType.ts +++ b/backend/src/plugins/Automod/triggers/matchMimeType.ts @@ -8,30 +8,23 @@ interface MatchResultType { mode: "blacklist" | "whitelist"; } -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; - }); +const baseConfig = z.strictObject({ + mime_type_blacklist: z.array(z.string().max(32)).max(255).default([]), + mime_type_whitelist: z.array(z.string().max(32)).max(255).default([]), +}); +const configWithWhitelist = baseConfig.merge(z.strictObject({ + whitelist_enabled: z.literal(true), + blacklist_enabled: z.literal(false).default(false), +})); +const configWithBlacklist = baseConfig.merge(z.strictObject({ + blacklist_enabled: z.literal(true), + whitelist_enabled: z.literal(false).default(false), +})); + +const configSchema = z.union([ + configWithWhitelist, + configWithBlacklist, +]); export const MatchMimeTypeTrigger = automodTrigger()({ configSchema, diff --git a/backend/src/plugins/Automod/types.ts b/backend/src/plugins/Automod/types.ts index 565f0470..316234f9 100644 --- a/backend/src/plugins/Automod/types.ts +++ b/backend/src/plugins/Automod/types.ts @@ -46,22 +46,6 @@ const zActionsMap = z const zRule = z.strictObject({ enabled: z.boolean().default(true), - // Typed as "never" because you are not expected to supply this directly. - // The transform instead picks it up from the property key and the output type is a string. - name: z - .never() - .optional() - .transform((_, ctx) => { - const ruleName = String(ctx.path[ctx.path.length - 2]).trim(); - if (!ruleName) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Automod rules must have names", - }); - return z.NEVER; - } - return ruleName; - }), pretty_name: z.string().optional(), presets: z.array(z.string().max(100)).max(25).default([]), affects_bots: z.boolean().default(false), @@ -69,9 +53,7 @@ const zRule = z.strictObject({ cooldown: zDelayString.nullable().default(null), allow_further_rules: z.boolean().default(false), triggers: z.array(zTriggersMap), - actions: zActionsMap.refine((v) => !(v.clean && v.start_thread), { - message: "Cannot have both clean and start_thread active at the same time", - }), + actions: zActionsMap, }); export type TRule = z.infer; diff --git a/backend/src/plugins/Counters/CountersPlugin.ts b/backend/src/plugins/Counters/CountersPlugin.ts index fd1f85bb..2a2b02f7 100644 --- a/backend/src/plugins/Counters/CountersPlugin.ts +++ b/backend/src/plugins/Counters/CountersPlugin.ts @@ -97,20 +97,20 @@ export const CountersPlugin = guildPlugin()({ // Initialize and store the IDs of each of the counters internally state.counterIds = {}; const config = pluginData.config.get(); - for (const counter of Object.values(config.counters)) { - const dbCounter = await state.counters.findOrCreateCounter(counter.name, counter.per_channel, counter.per_user); - state.counterIds[counter.name] = dbCounter.id; + for (const [counterName, counter] of Object.entries(config.counters)) { + const dbCounter = await state.counters.findOrCreateCounter(counterName, counter.per_channel, counter.per_user); + state.counterIds[counterName] = dbCounter.id; const thisCounterTriggers: CounterTrigger[] = []; state.counterTriggersByCounterId.set(dbCounter.id, thisCounterTriggers); // Initialize triggers - for (const trigger of values(counter.triggers)) { + for (const [triggerName, trigger] of Object.entries(counter.triggers)) { const parsedCondition = parseCounterConditionString(trigger.condition)!; const parsedReverseCondition = parseCounterConditionString(trigger.reverse_condition)!; const counterTrigger = await state.counters.initCounterTrigger( dbCounter.id, - trigger.name, + triggerName, parsedCondition[0], parsedCondition[1], parsedReverseCondition[0], diff --git a/backend/src/plugins/Counters/commands/AddCounterCmd.ts b/backend/src/plugins/Counters/commands/AddCounterCmd.ts index 1c463132..1438ff59 100644 --- a/backend/src/plugins/Counters/commands/AddCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/AddCounterCmd.ts @@ -119,18 +119,17 @@ export const AddCounterCmd = guildPluginMessageCommand()({ await changeCounterValue(pluginData, args.counterName, channel?.id ?? null, user?.id ?? null, amount); const newValue = await pluginData.state.counters.getCurrentValue(counterId, channel?.id ?? null, user?.id ?? null); - const counterName = counter.name || args.counterName; if (channel && user) { message.channel.send( - `Added ${amount} to **${counterName}** for <@!${user.id}> in <#${channel.id}>. The value is now ${newValue}.`, + `Added ${amount} to **${args.counterName}** for <@!${user.id}> in <#${channel.id}>. The value is now ${newValue}.`, ); } else if (channel) { - message.channel.send(`Added ${amount} to **${counterName}** in <#${channel.id}>. The value is now ${newValue}.`); + message.channel.send(`Added ${amount} to **${args.counterName}** in <#${channel.id}>. The value is now ${newValue}.`); } else if (user) { - message.channel.send(`Added ${amount} to **${counterName}** for <@!${user.id}>. The value is now ${newValue}.`); + message.channel.send(`Added ${amount} to **${args.counterName}** for <@!${user.id}>. The value is now ${newValue}.`); } else { - message.channel.send(`Added ${amount} to **${counterName}**. The value is now ${newValue}.`); + message.channel.send(`Added ${amount} to **${args.counterName}**. The value is now ${newValue}.`); } }, }); diff --git a/backend/src/plugins/Counters/commands/CountersListCmd.ts b/backend/src/plugins/Counters/commands/CountersListCmd.ts index c92849fd..ece20727 100644 --- a/backend/src/plugins/Counters/commands/CountersListCmd.ts +++ b/backend/src/plugins/Counters/commands/CountersListCmd.ts @@ -12,14 +12,14 @@ export const CountersListCmd = guildPluginMessageCommand()({ async run({ pluginData, message }) { const config = await pluginData.config.getForMessage(message); - const countersToShow = Array.from(Object.values(config.counters)).filter((c) => c.can_view !== false); + const countersToShow = Object.entries(config.counters).filter(([, c]) => c.can_view !== false); if (!countersToShow.length) { void pluginData.state.common.sendErrorMessage(message, "No counters are configured for this server"); return; } - const counterLines = countersToShow.map((counter) => { - const title = counter.pretty_name ? `**${counter.pretty_name}** (\`${counter.name}\`)` : `\`${counter.name}\``; + const counterLines = countersToShow.map(([counterName, counter]) => { + const title = counter.pretty_name ? `**${counter.pretty_name}** (\`${counterName}\`)` : `\`${counterName}\``; const types: string[] = []; if (counter.per_user) types.push("per user"); diff --git a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts index 7925511d..732b41bb 100644 --- a/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts +++ b/backend/src/plugins/Counters/commands/ResetAllCounterValuesCmd.ts @@ -29,10 +29,9 @@ export const ResetAllCounterValuesCmd = guildPluginMessageCommand null); await resetAllCounterValues(pluginData, args.counterName); @@ -51,7 +50,7 @@ export const ResetAllCounterValuesCmd = guildPluginMessageCommand()({ } await setCounterValue(pluginData, args.counterName, channel?.id ?? null, user?.id ?? null, counter.initial_value); - const counterName = counter.name || args.counterName; if (channel && user) { - message.channel.send(`Reset **${counterName}** for <@!${user.id}> in <#${channel.id}>`); + message.channel.send(`Reset **${args.counterName}** for <@!${user.id}> in <#${channel.id}>`); } else if (channel) { - message.channel.send(`Reset **${counterName}** in <#${channel.id}>`); + message.channel.send(`Reset **${args.counterName}** in <#${channel.id}>`); } else if (user) { - message.channel.send(`Reset **${counterName}** for <@!${user.id}>`); + message.channel.send(`Reset **${args.counterName}** for <@!${user.id}>`); } else { - message.channel.send(`Reset **${counterName}**`); + message.channel.send(`Reset **${args.counterName}**`); } }, }); diff --git a/backend/src/plugins/Counters/commands/SetCounterCmd.ts b/backend/src/plugins/Counters/commands/SetCounterCmd.ts index 0be13b7e..21243341 100644 --- a/backend/src/plugins/Counters/commands/SetCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/SetCounterCmd.ts @@ -123,16 +123,15 @@ export const SetCounterCmd = guildPluginMessageCommand()({ } await setCounterValue(pluginData, args.counterName, channel?.id ?? null, user?.id ?? null, value); - const counterName = counter.name || args.counterName; if (channel && user) { - message.channel.send(`Set **${counterName}** for <@!${user.id}> in <#${channel.id}> to ${value}`); + message.channel.send(`Set **${args.counterName}** for <@!${user.id}> in <#${channel.id}> to ${value}`); } else if (channel) { - message.channel.send(`Set **${counterName}** in <#${channel.id}> to ${value}`); + message.channel.send(`Set **${args.counterName}** in <#${channel.id}> to ${value}`); } else if (user) { - message.channel.send(`Set **${counterName}** for <@!${user.id}> to ${value}`); + message.channel.send(`Set **${args.counterName}** for <@!${user.id}> to ${value}`); } else { - message.channel.send(`Set **${counterName}** to ${value}`); + message.channel.send(`Set **${args.counterName}** to ${value}`); } }, }); diff --git a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts index 3691d53f..d49e5ff8 100644 --- a/backend/src/plugins/Counters/commands/ViewCounterCmd.ts +++ b/backend/src/plugins/Counters/commands/ViewCounterCmd.ts @@ -95,16 +95,15 @@ export const ViewCounterCmd = guildPluginMessageCommand()({ const value = await pluginData.state.counters.getCurrentValue(counterId, channel?.id ?? null, user?.id ?? null); const finalValue = value ?? counter.initial_value; - const counterName = counter.name || args.counterName; if (channel && user) { - message.channel.send(`**${counterName}** for <@!${user.id}> in <#${channel.id}> is ${finalValue}`); + message.channel.send(`**${args.counterName}** for <@!${user.id}> in <#${channel.id}> is ${finalValue}`); } else if (channel) { - message.channel.send(`**${counterName}** in <#${channel.id}> is ${finalValue}`); + message.channel.send(`**${args.counterName}** in <#${channel.id}> is ${finalValue}`); } else if (user) { - message.channel.send(`**${counterName}** for <@!${user.id}> is ${finalValue}`); + message.channel.send(`**${args.counterName}** for <@!${user.id}> is ${finalValue}`); } else { - message.channel.send(`**${counterName}** is ${finalValue}`); + message.channel.send(`**${args.counterName}** is ${finalValue}`); } }, }); diff --git a/backend/src/plugins/Counters/functions/getPrettyNameForCounter.ts b/backend/src/plugins/Counters/functions/getPrettyNameForCounter.ts index 1da14282..3b4a290d 100644 --- a/backend/src/plugins/Counters/functions/getPrettyNameForCounter.ts +++ b/backend/src/plugins/Counters/functions/getPrettyNameForCounter.ts @@ -4,5 +4,5 @@ import { CountersPluginType } from "../types.js"; export function getPrettyNameForCounter(pluginData: GuildPluginData, counterName: string) { const config = pluginData.config.get(); const counter = config.counters[counterName]; - return counter ? counter.pretty_name || counter.name : "Unknown Counter"; + return counter ? counter.pretty_name || counterName : "Unknown Counter"; } diff --git a/backend/src/plugins/Counters/types.ts b/backend/src/plugins/Counters/types.ts index 39a903ca..8924791f 100644 --- a/backend/src/plugins/Counters/types.ts +++ b/backend/src/plugins/Counters/types.ts @@ -75,22 +75,6 @@ const zTriggerFromString = zBoundedCharacters(0, 100).transform((val, ctx) => { const zTriggerInput = z.union([zTrigger, zTriggerFromString]); export const zCounter = z.strictObject({ - // Typed as "never" because you are not expected to supply this directly. - // The transform instead picks it up from the property key and the output type is a string. - name: z - .never() - .optional() - .transform((_, ctx) => { - const ruleName = String(ctx.path[ctx.path.length - 2]).trim(); - if (!ruleName) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Counters must have names", - }); - return z.NEVER; - } - return ruleName; - }), pretty_name: zBoundedCharacters(0, 100).nullable().default(null), per_channel: z.boolean().default(false), per_user: z.boolean().default(false), diff --git a/backend/src/plugins/RoleButtons/functions/applyAllRoleButtons.ts b/backend/src/plugins/RoleButtons/functions/applyAllRoleButtons.ts index fb456cd3..c52e11ae 100644 --- a/backend/src/plugins/RoleButtons/functions/applyAllRoleButtons.ts +++ b/backend/src/plugins/RoleButtons/functions/applyAllRoleButtons.ts @@ -6,26 +6,26 @@ import { applyRoleButtons } from "./applyRoleButtons.js"; export async function applyAllRoleButtons(pluginData: GuildPluginData) { const savedRoleButtons = await pluginData.state.roleButtons.getSavedRoleButtons(); const config = pluginData.config.get(); - for (const buttons of Object.values(config.buttons)) { + for (const [configName, configItem] of Object.entries(config.buttons)) { // Use the hash of the config to quickly check if we need to update buttons - const hash = createHash("md5").update(JSON.stringify(buttons)).digest("hex"); - const savedButtonsItem = savedRoleButtons.find((bt) => bt.name === buttons.name); + const hash = createHash("md5").update(JSON.stringify(configItem)).digest("hex"); + const savedButtonsItem = savedRoleButtons.find((bt) => bt.name === configName); if (savedButtonsItem?.hash === hash) { // No changes continue; } if (savedButtonsItem) { - await pluginData.state.roleButtons.deleteRoleButtonItem(buttons.name); + await pluginData.state.roleButtons.deleteRoleButtonItem(configName); } - const applyResult = await applyRoleButtons(pluginData, buttons, savedButtonsItem ?? null); + const applyResult = await applyRoleButtons(pluginData, configItem, configName, savedButtonsItem ?? null); if (!applyResult) { return; } await pluginData.state.roleButtons.saveRoleButtonItem( - buttons.name, + configName, applyResult.channel_id, applyResult.message_id, hash, diff --git a/backend/src/plugins/RoleButtons/functions/applyRoleButtons.ts b/backend/src/plugins/RoleButtons/functions/applyRoleButtons.ts index 12d8bc3d..31bdbda4 100644 --- a/backend/src/plugins/RoleButtons/functions/applyRoleButtons.ts +++ b/backend/src/plugins/RoleButtons/functions/applyRoleButtons.ts @@ -8,6 +8,7 @@ import { createButtonComponents } from "./createButtonComponents.js"; export async function applyRoleButtons( pluginData: GuildPluginData, configItem: TRoleButtonsConfigItem, + configName: string, existingSavedButtons: RoleButtonsItem | null, ): Promise<{ channel_id: string; message_id: string } | null> { let message: Message; @@ -32,7 +33,7 @@ export async function applyRoleButtons( channel.messages.fetch(configItem.message.message_id).catch(() => null)); if (!messageCandidate) { pluginData.getPlugin(LogsPlugin).logBotAlert({ - body: `Message not found for role_buttons/${configItem.name}`, + body: `Message not found for role_buttons/${configName}`, }); return null; } @@ -45,7 +46,7 @@ export async function applyRoleButtons( : Boolean(configItem.message.content.content?.trim()) || configItem.message.content.embeds?.length; if (!contentIsValid) { pluginData.getPlugin(LogsPlugin).logBotAlert({ - body: `Invalid message content for role_buttons/${configItem.name}`, + body: `Invalid message content for role_buttons/${configName}`, }); return null; } @@ -58,7 +59,7 @@ export async function applyRoleButtons( } if (!channel || !channel?.isTextBased()) { pluginData.getPlugin(LogsPlugin).logBotAlert({ - body: `Text channel not found for role_buttons/${configItem.name}`, + body: `Text channel not found for role_buttons/${configName}`, }); return null; } @@ -89,7 +90,7 @@ export async function applyRoleButtons( candidateMessage = await channel.send(configItem.message.content as string | MessageCreateOptions); } catch (err) { pluginData.getPlugin(LogsPlugin).logBotAlert({ - body: `Error while posting message for role_buttons/${configItem.name}: ${String(err)}`, + body: `Error while posting message for role_buttons/${configName}: ${String(err)}`, }); return null; } @@ -100,16 +101,16 @@ export async function applyRoleButtons( if (message.author.id !== pluginData.client.user?.id) { pluginData.getPlugin(LogsPlugin).logBotAlert({ - body: `Error applying role buttons for role_buttons/${configItem.name}: target message must be posted by Zeppelin`, + body: `Error applying role buttons for role_buttons/${configName}: target message must be posted by Zeppelin`, }); return null; } // Apply role buttons - const components = createButtonComponents(configItem); + const components = createButtonComponents(configItem, configName); await message.edit({ components }).catch((err) => { pluginData.getPlugin(LogsPlugin).logBotAlert({ - body: `Error applying role buttons for role_buttons/${configItem.name}: ${String(err)}`, + body: `Error applying role buttons for role_buttons/${configName}: ${String(err)}`, }); return null; }); diff --git a/backend/src/plugins/RoleButtons/functions/createButtonComponents.ts b/backend/src/plugins/RoleButtons/functions/createButtonComponents.ts index 8b56d3a9..d8cac736 100644 --- a/backend/src/plugins/RoleButtons/functions/createButtonComponents.ts +++ b/backend/src/plugins/RoleButtons/functions/createButtonComponents.ts @@ -4,7 +4,7 @@ import { TRoleButtonsConfigItem } from "../types.js"; import { TooManyComponentsError } from "./TooManyComponentsError.js"; import { convertButtonStyleStringToEnum } from "./convertButtonStyleStringToEnum.js"; -export function createButtonComponents(configItem: TRoleButtonsConfigItem): Array> { +export function createButtonComponents(configItem: TRoleButtonsConfigItem, configName: string): Array> { const rows: Array> = []; let currentRow = new ActionRowBuilder(); @@ -17,7 +17,7 @@ export function createButtonComponents(configItem: TRoleButtonsConfigItem): Arra const button = new ButtonBuilder() .setLabel(option.label ?? "") .setStyle(convertButtonStyleStringToEnum(option.style) ?? ButtonStyle.Primary) - .setCustomId(buildCustomId("roleButtons", { name: configItem.name, index })); + .setCustomId(buildCustomId("roleButtons", { name: configName, index })); if (option.emoji) { button.setEmoji(option.emoji); diff --git a/backend/src/plugins/RoleButtons/types.ts b/backend/src/plugins/RoleButtons/types.ts index 37d84550..4f2a5495 100644 --- a/backend/src/plugins/RoleButtons/types.ts +++ b/backend/src/plugins/RoleButtons/types.ts @@ -34,22 +34,6 @@ export type TRoleButtonOption = z.infer; const zRoleButtonsConfigItem = z .strictObject({ - // Typed as "never" because you are not expected to supply this directly. - // The transform instead picks it up from the property key and the output type is a string. - name: z - .never() - .optional() - .transform((_, ctx) => { - const ruleName = String(ctx.path[ctx.path.length - 2]).trim(); - if (!ruleName) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Role buttons must have names", - }); - return z.NEVER; - } - return ruleName; - }), message: z.union([ z.strictObject({ channel_id: zSnowflake, @@ -66,7 +50,7 @@ const zRoleButtonsConfigItem = z .refine( (parsed) => { try { - createButtonComponents(parsed); + createButtonComponents(parsed, "test"); // We can use any configName here } catch (err) { if (err instanceof TooManyComponentsError) { return false;