From 21d18bb8ebc0124f919bad9b4789ef237fcef5de Mon Sep 17 00:00:00 2001 From: Peter-MJ-Parker <34216187+Peter-MJ-Parker@users.noreply.github.com> Date: Tue, 9 Jul 2024 15:43:36 -0500 Subject: [PATCH 1/2] chore: Update permCheck.ts (#112) * chore: Update permCheck.ts Allows users to check member perms before using specific sub command groups, sub commands, and options! * edit: permCheck - revert back to a function Reverted permCheck back to a function to avoid breaking changes. * edit: permCheck.ts Remove console logs * formatting permCheck.ts * edit: Update permCheck.ts Fixed overall formatting simplified ephemeral booleans No longer destructuring interaction from ctx fixed in guild from not fully returning controller.stop() remove `no_guild` function in favor of hard coding imported type CommandType * edit: Update permCheck.ts Remove ALL destructures `({ ctx })` --> `(ctx)` * edit: Update permCheck.ts edit response for not being in guild * edit: permCheck - assigned to object Remove all breaking changes while maintaining integrity of new features as well as original! * edit: permCheck - remove un-needed code. Thanks to Duro for simplifying the code into one function! --------- Co-authored-by: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> --- plugins/permCheck.ts | 262 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 242 insertions(+), 20 deletions(-) diff --git a/plugins/permCheck.ts b/plugins/permCheck.ts index 7884997..0d62fdb 100644 --- a/plugins/permCheck.ts +++ b/plugins/permCheck.ts @@ -1,16 +1,21 @@ -// @ts-nocheck +//@ts-nocheck /** * @plugin * This is perm check, it allows users to parse the permission you want and let the plugin do the rest. (check user for that perm). + * Each function (other than "command") allows multiple options! [ { ... }, { ... }, { ... } ] See examples! * * @author @Benzo-Fury [<@762918086349029386>] - * @version 1.0.1 + * @author @Peter-MJ-Parker [<@371759410009341952>] + * @version 2.0.0 * @example * ```ts * import { permCheck } from "../plugins/permCheck"; * import { commandModule } from "@sern/handler"; * export default commandModule({ - * plugins: [ permCheck('permission', 'No permission response') ], + * plugins: [ permCheck(["Administrator", "AddReactions"], "I am a custom response!"), + * permCheck.options([{ name: "user", needAllPerms: true, perms: ["AttachFiles", "CreateEvents"]}]), + * permCheck.subcommands([{ name: "list", needAllPerms: false, perms: ["Connect"]}]), + * permCheck.subGroups([{ name: "list", needAllPerms: false, perms: ["Connect"], response: "I am also a custom response!"}])], * execute: (ctx) => { * //your code here * } @@ -19,21 +24,238 @@ * @end */ -import type { GuildMember, PermissionResolvable } from "discord.js"; -import { CommandControlPlugin, CommandType, controller } from "@sern/handler"; -export function permCheck(perm: PermissionResolvable, response: string) { - return CommandControlPlugin(async (ctx, args) => { - if (ctx.guild === null) { - await ctx.reply("This command cannot be used here"); - console.warn( - "PermCheck > A command stopped because we couldn't check a users permissions (was used in dms)", - ); //delete this line if you dont want to be notified when a command is used outside of a guild/server - return controller.stop(); - } - if (!(ctx.member! as GuildMember).permissions.has(perm)) { - await ctx.reply(response); - return controller.stop(); - } - return controller.next(); - }); +import { + Colors, + EmbedBuilder, + PermissionsBitField, + type GuildMember, + type PermissionResolvable, + type TextChannel +} from 'discord.js'; +import { CommandControlPlugin, type CommandType, controller, Service } from '@sern/handler'; + +function command(perm: PermissionResolvable, response?: string) { + return CommandControlPlugin(async (ctx) => { + if (ctx.guild === null) { + await ctx.reply({ + content: "This command cannot be used in DM's!", + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + const _perms = (ctx.member as GuildMember).permissionsIn(ctx.channel as TextChannel); + if (!_perms.has(perm)) { + await ctx.reply({ + embeds: [ + sendEmbed(response ?? `You are missing required permissions to run this command:\n${permsToString(perm)}`) + ], + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + if (!_perms.any(perm)) { + await ctx.reply({ + embeds: [ + sendEmbed( + response ?? + `You need at least one of the following permissions to run this command:\n${permsToString(perm)}` + ) + ], + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + return controller.next(); + }); +} +function subGroups(opts: BaseOptions[]) { + return CommandControlPlugin(async (ctx) => { + if (ctx.guild === null) { + await ctx.reply({ + content: "This sub command group cannot be used in DM's!", + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + const member = ctx.member as GuildMember; + const group = ctx.options.getSubcommandGroup(); + for (const opt of opts) { + if (group !== opt.name) { + await ctx.reply({ + embeds: [ + sendEmbed(`[PLUGIN_permCheck.subGroups]: Failed to find specified subcommandGroup \`${opt.name}\`!`) + ], + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + const _perms = member.permissionsIn(ctx.channel as TextChannel); + if (opt.needAllPerms && !_perms.has(opt.perms)) { + await ctx.reply({ + embeds: [ + sendEmbed( + opt.response ?? `You cannot use this group due to missing permissions: ${permsToString(opt.perms)}` + ) + ], + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + if (!opt.needAllPerms && !_perms.any(opt.perms)) { + await ctx.reply({ + embeds: [ + sendEmbed( + opt.response ?? + `You cannot use this group because you need at least one of the following permissions: ${permsToString( + opt.perms + )}` + ) + ], + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + } + return controller.next(); + }); +} + +function subcommands(opts: BaseOptions[]) { + return CommandControlPlugin(async (ctx) => { + if (ctx.guild === null) { + await ctx.reply({ + content: "This sub command cannot be used in DM's!", + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + const member = ctx.member as GuildMember; + const sub = ctx.options.getSubcommand(); + for (const { name, needAllPerms, perms, response } of opts) { + if (sub !== name) { + await ctx.reply({ + embeds: [sendEmbed(`[PLUGIN_permCheck.subcommands]: Failed to find specified subcommand \`${name}\`!`)], + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + const _perms = member.permissionsIn(ctx.channel as TextChannel); + if (needAllPerms && !_perms.has(perms)) { + await ctx.reply({ + embeds: [ + sendEmbed(response ?? `You cannot use this subcommand due to missing permissions: ${permsToString(perms)}`) + ], + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + if (!needAllPerms && !_perms.any(perms)) { + await ctx.reply({ + embeds: [ + sendEmbed( + response ?? + `You cannot use this subcommand because you need at least the following permissions: ${permsToString( + perms + )}` + ) + ], + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + } + return controller.next(); + }); +} +function options(opts: BaseOptions[]) { + return CommandControlPlugin(async (ctx) => { + if (ctx.guild === null) { + await ctx.reply({ + content: "This specific option cannot be used in DM's!", + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + const member = ctx.member as GuildMember; + const channel = ctx.channel as TextChannel; + + for (const { name, needAllPerms, perms, response } of opts) { + const option = ctx.options.get(name); + + if (option && option.name !== name) { + await ctx.reply({ + embeds: [sendEmbed(`[PLUGIN_permCheck.options]: Could not find supplied option: \`${name}\``)], + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + + const permissions = member.permissionsIn(channel); + + if (needAllPerms) { + if (!permissions.has(perms)) { + await ctx.reply({ + embeds: [ + sendEmbed( + response ?? + `You need all the following permissions for option \`${name}\`:\n ${permsToString(...perms)}` + ) + ], + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + } else { + if (!permissions.any(perms)) { + await ctx.reply({ + embeds: [ + sendEmbed( + response ?? + `You need at least one of the following permissions for option \`${name}\`: \n${permsToString( + ...perms + )}` + ) + ], + ephemeral: !ctx.isMessage() + }); + return controller.stop(); + } + } + } + + return controller.next(); + }); +} +interface BaseOptions { + name: string; + perms: PermissionResolvable[]; + needAllPerms: boolean; + response?: string; } + +const sendEmbed = (description: string) => { + const client = Service('@sern/client'); + return new EmbedBuilder({ + title: ':x: Permission Error! :x:', + description, + color: Colors.Red, + footer: { + text: client.user?.username!, + icon_url: client.user?.displayAvatarURL()! + } + }); +}; + +export const permsToString = (...perms: PermissionResolvable[]) => { + return new PermissionsBitField(perms) + .toArray() + .map((perm) => `\`${perm}\``) + .join(', '); +}; + +export const permCheck = Object.assign(command, { + command, + subGroups, + subcommands, + options +}); From 036803c69b8646470babac87bd22ed52570c377c Mon Sep 17 00:00:00 2001 From: jacoobes Date: Tue, 9 Jul 2024 20:43:51 +0000 Subject: [PATCH 2/2] chore: update plugin listing Signed-off-by: GitHub Actions <41898282+github-actions[bot]@users.noreply.github.com> --- pluginlist.json | 136 ++++++++++++++++++++++++------------------------ 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/pluginlist.json b/pluginlist.json index b75b6f0..946bcc7 100644 --- a/pluginlist.json +++ b/pluginlist.json @@ -1,12 +1,4 @@ [ { - "description" : "\n\n This is perm check, it allows users to parse the permission you want and let the plugin do the rest. (check user for that perm).\n", - "hash" : "a758460fbe9ee036dc8a98854d73a4ba", - "name" : "permCheck", - "author" : [ "@Benzo-Fury [<@762918086349029386>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/permCheck.ts", - "example" : "\n\n ```ts\n import { permCheck } from \"../plugins/permCheck\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ permCheck('permission', 'No permission response') ],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", - "version" : "1.0.1" -}, { "description" : "\n\n Generalized `filter` plugin. all credit to trueharuu.\n Perform declarative conditionals as plugins.", "hash" : "8a77e9bf4590a979136fcb479470321f", "name" : "filter", @@ -15,21 +7,13 @@ "example" : "\n\n ```ts\n import { filter, not, isGuildOwner, canMentionEveryone } from '../plugins/filter';\n import { commandModule } from '@sern/handler';\n\n export default commandModule({\n plugins: [filter({ condition: [not(isGuildOwner()), canMentionEveryone()] })],\n async execute(context) {\n // your code here\n }\n });\n ```", "version" : "2.0.0" }, { - "description" : "\n\n This is dmOnly plugin, it allows commands to be run only in DMs.\n", - "hash" : "63eabcaafdbd6b6fbd6e52372e656a21", - "name" : "dmOnly", + "description" : "\n\n [DEPRECATED] It allows you to publish your application commands using the discord.js library with ease.\n", + "hash" : "66ef98cb1b934c774c7a1d987db1486d", + "name" : "publish", "author" : [ "@EvolutionX-10 [<@697795666373640213>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/dmOnly.ts", - "example" : "\n\n ```ts\n import { dmOnly } from \"../plugins/dmOnly\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [dmOnly()],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", - "version" : "1.0.0" -}, { - "description" : "\n\n This plugin checks the fields of a ModalSubmitInteraction\n with regex or a custom callback\n", - "hash" : "637eaca240ccb5fc8a1bf3d4ba0bc368", - "name" : "assertFields", - "author" : [ "@jacoobes [<@182326315813306368>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/assertFields.ts", - "example" : "\n\n ```ts\n export default commandModule({\n type: CommandType.Modal,\n plugins: [\n assertFields({\n fields: {\n // check the modal field \"mcUsernameInput\" with the regex /a+b+c/\n mcUsernameInput: /a+b+c+/\n },\n failure: (errors, interaction) => {\n interaction.reply(errors.join(\"\\n\"))\n }\n }),\n ],\n execute: ctx => {\n ctx.reply(\"nice!\")\n }\n })\n ```", - "version" : "1.0.0" + "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/publish.ts", + "example" : "\n\n ```ts\n import { publish } from \"../plugins/publish\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ publish() ], // put an object containing permissions, ids for guild commands, boolean for dmPermission\n // plugins: [ publish({ guildIds: ['guildId'], defaultMemberPermissions: 'Administrator'})]\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", + "version" : "2.0.0" }, { "description" : "\n\n fromCallback turns a callback into a plugin result.\n if the callback returns truthy value, plugin continues.\n This control plugin works for every command type. The arguments of the callback\n mirror the execute method on the current module.", "hash" : "6a085373d3d240922aa1d2c5b50fadd7", @@ -38,6 +22,22 @@ "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/fromCallback.ts", "example" : "\n\n ```ts\n const myServer = \"941002690211766332\";\n export default commandModule({\n type: CommandType.Both,\n plugins: [\n //This plugin prevents this command module from executing in other servers except myServer \n fromCallback((ctx, args) => ctx.guildId == myServer)\n ],\n execute: ctx => {\n ctx.reply(\"I only respond in myServer!\");\n }\n })\n ```", "version" : "1.0.0" +}, { + "description" : "\n\n This is OwnerOnly plugin, it allows only bot owners to run the command, like eval.\n", + "hash" : "31adb9ef134cddda53e47e505620c905", + "name" : "ownerOnly", + "author" : [ "@EvolutionX-10 [<@697795666373640213>]" ], + "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/ownerOnly.ts", + "example" : "\n\n ```ts\n import { ownerOnly } from \"../plugins/ownerOnly\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ ownerOnly() ], // can also pass array of IDs to override default owner IDs\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", + "version" : "1.2.0" +}, { + "description" : "\n\n Disables a command entirely, for whatever reasons you may need.\n", + "hash" : "44a7ac3d807a24297d95c717056ed8ee", + "name" : "disable", + "author" : [ "@jacoobes [<@182326315813306368>]", "@Peter-MJ-Parker [<@371759410009341952>]" ], + "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/disable.ts", + "example" : "\n\n ```ts\n import { disable } from \"../plugins/disable\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ disable() ],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", + "version" : "2.1.0" }, { "description" : "\n\n This plugin checks if a channel is the specified type\n", "hash" : "a3f95ec62e1480b8c3318443cc8184c0", @@ -47,45 +47,29 @@ "example" : "\n\n ```ts\n import { channelType } from \"../plugins/channelType\";\n import { ChannelType } from \"discord.js\"\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ channelType([ChannelType.GuildText], 'This cannot be used here') ],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", "version" : "1.0.0" }, { - "description" : "\n\n This plugin checks if the channel is nsfw and responds to user with a specified response if not nsfw\n", - "hash" : "d8c81cd449f09b2122330907352cdf76", - "name" : "nsfwOnly", - "author" : [ "@Benzo-Fury [<@762918086349029386>]", "@SrIzan10 [<@703974042700611634>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/nsfwOnly.ts", - "example" : "\n\n ```ts\n import { nsfwOnly } from \"../plugins/nsfwOnly\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ nsfwOnly('response', true) ],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", - "version" : "1.0.1" + "description" : "\n\n Asks the user for a confirmation msg before executing the command\n", + "hash" : "f2bd8f2845694357a20346a99b388e2e", + "name" : "confirmation", + "author" : [ "@trueharuu [<@504698587221852172>]" ], + "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/confirmation.ts", + "example" : "\n\n ```ts\n import { confirmation } from \"../plugins/confirmation\";\n import { CommandType, commandModule } from \"@sern/handler\";\n\n // YOU MUST HAVE GUILD MESSAGE REACTION INTENTS ON YOUR CLIENT!!!!\n export default commandModule({\n type : CommandType.Both\n plugins: [confirmation()],\n \texecute: (ctx, args) => {\n \t\tctx.interaction.followUp('Hello welcome to the secret club')\n \t}\n })\n ```", + "version" : "1.0.0" }, { - "description" : "\n\n This is buttonConfirmation plugin, it runs confirmation prompt in the form of buttons.\n Note that you need to use edit/editReply in the command itself because we are already replying in the plugin!\n Credits to original plugin of confirmation using reactions and its author!\n", - "hash" : "7ff98585dba82b7ac5268458b246b9fc", - "name" : "buttonConfirmation", + "description" : "\n\n This is dmOnly plugin, it allows commands to be run only in DMs.\n", + "hash" : "63eabcaafdbd6b6fbd6e52372e656a21", + "name" : "dmOnly", "author" : [ "@EvolutionX-10 [<@697795666373640213>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/buttonConfirmation.ts", - "example" : "\n\n ```ts\n import { buttonConfirmation } from \"../plugins/buttonConfirmation\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ buttonConfirmation() ],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", + "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/dmOnly.ts", + "example" : "\n\n ```ts\n import { dmOnly } from \"../plugins/dmOnly\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [dmOnly()],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", "version" : "1.0.0" }, { - "description" : "\n\n Disables a command entirely, for whatever reasons you may need.\n", - "hash" : "44a7ac3d807a24297d95c717056ed8ee", - "name" : "disable", - "author" : [ "@jacoobes [<@182326315813306368>]", "@Peter-MJ-Parker [<@371759410009341952>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/disable.ts", - "example" : "\n\n ```ts\n import { disable } from \"../plugins/disable\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ disable() ],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", - "version" : "2.1.0" -}, { - "description" : "\n\n [DEPRECATED] It allows you to publish your application commands using the discord.js library with ease.\n", - "hash" : "66ef98cb1b934c774c7a1d987db1486d", - "name" : "publish", - "author" : [ "@EvolutionX-10 [<@697795666373640213>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/publish.ts", - "example" : "\n\n ```ts\n import { publish } from \"../plugins/publish\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ publish() ], // put an object containing permissions, ids for guild commands, boolean for dmPermission\n // plugins: [ publish({ guildIds: ['guildId'], defaultMemberPermissions: 'Administrator'})]\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", + "description" : "\n\n This is perm check, it allows users to parse the permission you want and let the plugin do the rest. (check user for that perm).\n Each function (other than \"command\") allows multiple options! [ { ... }, { ... }, { ... } ] See examples!\n", + "hash" : "28213222ad554b8445b00ba396619fe6", + "name" : "permCheck", + "author" : [ "@Benzo-Fury [<@762918086349029386>]", "@Peter-MJ-Parker [<@371759410009341952>]" ], + "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/permCheck.ts", + "example" : "\n\n ```ts\n import { permCheck } from \"../plugins/permCheck\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ permCheck([\"Administrator\", \"AddReactions\"], \"I am a custom response!\"),\n \t\tpermCheck.options([{ name: \"user\", needAllPerms: true, perms: [\"AttachFiles\", \"CreateEvents\"]}]),\n \t\tpermCheck.subcommands([{ name: \"list\", needAllPerms: false, perms: [\"Connect\"]}]),\n \t\tpermCheck.subGroups([{ name: \"list\", needAllPerms: false, perms: [\"Connect\"], response: \"I am also a custom response!\"}])],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", "version" : "2.0.0" -}, { - "description" : "\n\n This is perm check, it allows users to parse the permission you want and let the plugin do the rest. (check bot or user for that perm).\n", - "hash" : "53a69e2b4f74b0635f51222b74921edd", - "name" : "requirePermission", - "author" : [ "@Benzo-Fury [<@762918086349029386>]", "@needhamgary [<@342314924804014081>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/requirePermission.ts", - "example" : "\n\n ```ts\n import { requirePermission } from \"../plugins/myPermCheck\";\n import { commandModule, CommandType } from \"@sern/handler\";\n export default commandModule({\n plugins: [ requirePermission('target', 'permission', 'No response (optional)') ],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", - "version" : "1.2.0" }, { "description" : "\n\n Allows you to set cooldowns (or \"ratelimits\") for commands, limits user/channel/guild actions.", "hash" : "9549ecb8901e2e9f814cd6234d1e8a32", @@ -103,19 +87,35 @@ "example" : "\n\n ```ts\n import { commandModule, CommandType } from \"@sern/handler\";\n import { serverOnly } from \"../plugins/serverOnly\";\n export default commandModule({\n type: CommandType.Both,\n plugins: [serverOnly([\"guildId\"], failMessage)], // fail message is the message you will see when the command is ran in the wrong server.\n description: \"command description\",\n execute: async (ctx, args) => {\n // your code here\n },\n });\n ```", "version" : "1.0.0" }, { - "description" : "\n\n This is OwnerOnly plugin, it allows only bot owners to run the command, like eval.\n", - "hash" : "31adb9ef134cddda53e47e505620c905", - "name" : "ownerOnly", - "author" : [ "@EvolutionX-10 [<@697795666373640213>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/ownerOnly.ts", - "example" : "\n\n ```ts\n import { ownerOnly } from \"../plugins/ownerOnly\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ ownerOnly() ], // can also pass array of IDs to override default owner IDs\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", + "description" : "\n\n This is perm check, it allows users to parse the permission you want and let the plugin do the rest. (check bot or user for that perm).\n", + "hash" : "53a69e2b4f74b0635f51222b74921edd", + "name" : "requirePermission", + "author" : [ "@Benzo-Fury [<@762918086349029386>]", "@needhamgary [<@342314924804014081>]" ], + "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/requirePermission.ts", + "example" : "\n\n ```ts\n import { requirePermission } from \"../plugins/myPermCheck\";\n import { commandModule, CommandType } from \"@sern/handler\";\n export default commandModule({\n plugins: [ requirePermission('target', 'permission', 'No response (optional)') ],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", "version" : "1.2.0" }, { - "description" : "\n\n Asks the user for a confirmation msg before executing the command\n", - "hash" : "f2bd8f2845694357a20346a99b388e2e", - "name" : "confirmation", - "author" : [ "@trueharuu [<@504698587221852172>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/confirmation.ts", - "example" : "\n\n ```ts\n import { confirmation } from \"../plugins/confirmation\";\n import { CommandType, commandModule } from \"@sern/handler\";\n\n // YOU MUST HAVE GUILD MESSAGE REACTION INTENTS ON YOUR CLIENT!!!!\n export default commandModule({\n type : CommandType.Both\n plugins: [confirmation()],\n \texecute: (ctx, args) => {\n \t\tctx.interaction.followUp('Hello welcome to the secret club')\n \t}\n })\n ```", + "description" : "\n\n This plugin checks if the channel is nsfw and responds to user with a specified response if not nsfw\n", + "hash" : "d8c81cd449f09b2122330907352cdf76", + "name" : "nsfwOnly", + "author" : [ "@Benzo-Fury [<@762918086349029386>]", "@SrIzan10 [<@703974042700611634>]" ], + "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/nsfwOnly.ts", + "example" : "\n\n ```ts\n import { nsfwOnly } from \"../plugins/nsfwOnly\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ nsfwOnly('response', true) ],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", + "version" : "1.0.1" +}, { + "description" : "\n\n This plugin checks the fields of a ModalSubmitInteraction\n with regex or a custom callback\n", + "hash" : "637eaca240ccb5fc8a1bf3d4ba0bc368", + "name" : "assertFields", + "author" : [ "@jacoobes [<@182326315813306368>]" ], + "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/assertFields.ts", + "example" : "\n\n ```ts\n export default commandModule({\n type: CommandType.Modal,\n plugins: [\n assertFields({\n fields: {\n // check the modal field \"mcUsernameInput\" with the regex /a+b+c/\n mcUsernameInput: /a+b+c+/\n },\n failure: (errors, interaction) => {\n interaction.reply(errors.join(\"\\n\"))\n }\n }),\n ],\n execute: ctx => {\n ctx.reply(\"nice!\")\n }\n })\n ```", + "version" : "1.0.0" +}, { + "description" : "\n\n This is buttonConfirmation plugin, it runs confirmation prompt in the form of buttons.\n Note that you need to use edit/editReply in the command itself because we are already replying in the plugin!\n Credits to original plugin of confirmation using reactions and its author!\n", + "hash" : "7ff98585dba82b7ac5268458b246b9fc", + "name" : "buttonConfirmation", + "author" : [ "@EvolutionX-10 [<@697795666373640213>]" ], + "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/plugins/buttonConfirmation.ts", + "example" : "\n\n ```ts\n import { buttonConfirmation } from \"../plugins/buttonConfirmation\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [ buttonConfirmation() ],\n execute: (ctx) => {\n \t\t//your code here\n }\n })\n ```", "version" : "1.0.0" } ] \ No newline at end of file