From ecaad4b1626ea1125713874de172fb3d7f4bbf2b Mon Sep 17 00:00:00 2001 From: EvolutionX-10 Date: Fri, 1 Sep 2023 16:52:00 +0000 Subject: [PATCH] chore: update JavaScript plugins --- JavaScript/assertFields.js | 4 +- JavaScript/buttonConfirmation.js | 2 + JavaScript/channelType.js | 2 + JavaScript/confirmation.js | 2 + JavaScript/cooldown.js | 2 + JavaScript/disable.js | 2 + JavaScript/dmOnly.js | 2 + JavaScript/filter.js | 575 +++++++++++++++++++ JavaScript/nsfwOnly.js | 2 + JavaScript/ownerOnly.js | 2 + JavaScript/permCheck.js | 4 +- JavaScript/publish.js | 27 +- JavaScript/requirePermission.js | 8 +- JavaScript/serverOnly.js | 4 +- TypeScript/assertFields.ts | 2 +- TypeScript/buttonConfirmation.ts | 2 +- TypeScript/cooldown.ts | 6 +- TypeScript/disable.ts | 4 +- TypeScript/dmOnly.ts | 2 +- TypeScript/filter.ts | 916 ++++++++++++++++--------------- TypeScript/nsfwOnly.ts | 4 +- TypeScript/ownerOnly.ts | 2 +- TypeScript/permCheck.ts | 2 +- TypeScript/publish.ts | 26 +- TypeScript/requirePermission.ts | 10 +- TypeScript/serverOnly.ts | 2 +- pluginlist.json | 247 +++++---- 27 files changed, 1253 insertions(+), 610 deletions(-) create mode 100644 JavaScript/filter.js diff --git a/JavaScript/assertFields.js b/JavaScript/assertFields.js index 816cbe3..49a845f 100644 --- a/JavaScript/assertFields.js +++ b/JavaScript/assertFields.js @@ -1,6 +1,7 @@ //@ts-nocheck /** + * @plugin * This plugin checks the fields of a ModalSubmitInteraction * with regex or a custom callback * @@ -26,6 +27,7 @@ * } * }) * ``` + * @plugin */ import { CommandControlPlugin, controller } from "@sern/handler"; export function assertFields(config) { @@ -46,7 +48,7 @@ export function assertFields(config) { errors.push( input + " failed to pass assertion " + - resolvedAssertion.toString() + resolvedAssertion.toString(), ); } } diff --git a/JavaScript/buttonConfirmation.js b/JavaScript/buttonConfirmation.js index d8b4b3e..71ff128 100644 --- a/JavaScript/buttonConfirmation.js +++ b/JavaScript/buttonConfirmation.js @@ -1,6 +1,7 @@ //@ts-nocheck /** + * @plugin * This is buttonConfirmation plugin, it runs confirmation prompt in the form of buttons. * Note that you need to use edit/editReply in the command itself because we are already replying in the plugin! * Credits to original plugin of confirmation using reactions and its author! @@ -18,6 +19,7 @@ * } * }) * ``` + * @end */ import { CommandControlPlugin, controller } from "@sern/handler"; import { diff --git a/JavaScript/channelType.js b/JavaScript/channelType.js index 0a8278e..6e6a628 100644 --- a/JavaScript/channelType.js +++ b/JavaScript/channelType.js @@ -1,6 +1,7 @@ // @ts-nocheck /** + * @plugin * This plugin checks if a channel is the specified type * * @author @Benzo-Fury [<@762918086349029386>] @@ -17,6 +18,7 @@ * } * }) * ``` + * @end */ import { ChannelType } from "discord.js"; import { CommandControlPlugin, controller } from "@sern/handler"; diff --git a/JavaScript/confirmation.js b/JavaScript/confirmation.js index 56cf0a3..f25bcad 100644 --- a/JavaScript/confirmation.js +++ b/JavaScript/confirmation.js @@ -1,6 +1,7 @@ //@ts-nocheck /** + * @plugin * Asks the user for a confirmation message before executing the command * * @author @trueharuu [<@504698587221852172>] @@ -19,6 +20,7 @@ * } * }) * ``` + * @end */ import { CommandControlPlugin, controller } from "@sern/handler"; const defaultOptions = { diff --git a/JavaScript/cooldown.js b/JavaScript/cooldown.js index f543b60..8eab536 100644 --- a/JavaScript/cooldown.js +++ b/JavaScript/cooldown.js @@ -1,6 +1,7 @@ // @ts-nocheck /** + * @plugin * Allows you to set cooldowns (or "ratelimits") for commands * limits user/channel/guild actions, * @author @trueharuu [<@504698587221852172>] @@ -16,6 +17,7 @@ * } * }) * ``` + * @end */ import { CommandControlPlugin, controller } from "@sern/handler"; import { GuildMember } from "discord.js"; diff --git a/JavaScript/disable.js b/JavaScript/disable.js index 0da784a..f84673b 100644 --- a/JavaScript/disable.js +++ b/JavaScript/disable.js @@ -1,6 +1,7 @@ // @ts-nocheck /** + * @plugin * Disables a command entirely, for whatever reasons you may need. * * @author @jacoobes [<@182326315813306368>] @@ -17,6 +18,7 @@ * } * }) * ``` + * @end */ import { CommandControlPlugin, controller } from "@sern/handler"; export function disable(onFail) { diff --git a/JavaScript/dmOnly.js b/JavaScript/dmOnly.js index 5a2fe2f..74ecfc8 100644 --- a/JavaScript/dmOnly.js +++ b/JavaScript/dmOnly.js @@ -1,6 +1,7 @@ // @ts-nocheck /** + * @plugin * This is dmOnly plugin, it allows commands to be run only in DMs. * * @author @EvolutionX-10 [<@697795666373640213>] @@ -16,6 +17,7 @@ * } * }) * ``` + * @end */ import { CommandControlPlugin, controller } from "@sern/handler"; export function dmOnly(content, ephemeral) { diff --git a/JavaScript/filter.js b/JavaScript/filter.js new file mode 100644 index 0000000..5ce108c --- /dev/null +++ b/JavaScript/filter.js @@ -0,0 +1,575 @@ +import { CommandControlPlugin, controller } from "@sern/handler"; +import { + GuildMember, + GuildMemberRoleManager, + PermissionsBitField, + User, +} from "discord.js"; +export class Criteria { + constructor(name, execute, children) { + this.name = name; + this.execute = execute; + this.children = children; + } + + toString() { + return this.name + " " + this.children.map((c) => c.name).join(", "); + } +} +export const or = (...filters) => { + function execute(context) { + let pass = false; + + tests: for (const filter of filters) { + if (filter.test(context)) { + pass = true; + break tests; + } + } + + return pass; + } + + const children = filters.map((x) => x.criteria); + return new FilterImpl( + new Criteria("or", execute, children), + `or(${filters.map((x) => x.message).join(", ")})`, + ); +}; +export const and = (...filters) => { + function execute(context) { + for (const filter of filters) { + if (!filter.test(context)) { + return false; + } + } + + return true; + } + + const children = filters.map((x) => x.criteria); + return new FilterImpl( + new Criteria("and", execute, children), + `and(${filters.map((x) => x.message).join(", ")})`, + ); +}; +export const not = (filter) => { + function execute(context) { + return !filter.test(context); + } + + return new FilterImpl( + new Criteria("not", execute, [filter.criteria]), + `not(${filter.criteria})`, + ); +}; +export const custom = (execute, message) => { + return new FilterImpl(new Criteria("custom", execute, []), message); +}; +export const withCustomMessage = (filter, message) => { + return new FilterImpl(filter.criteria, message); +}; +export const hasGuildPermission = (permission) => { + const b = PermissionsBitField.resolve(permission); + const field = Object.entries(PermissionsBitField.Flags).find( + ([, v]) => v === b, + ); + + if (field === undefined) { + throw new Error( + `unknown permission \`${permission}\` in filter \`hasGuildPermission\``, + ); + } + + const [name] = field; + + function execute(context) { + if (context.member !== null) { + if (typeof context.member.permissions === "string") { + return new PermissionsBitField( + BigInt(context.member.permissions), + ).has(b); + } + + return context.member.permissions.has(b); + } + + return true; + } + + return new FilterImpl( + new Criteria("hasGuildPermission", execute, []), + `has guild permission: ${name}`, + ); +}; +export const hasChannelPermission = (permission, channelId) => { + const b = PermissionsBitField.resolve(permission); + const field = Object.entries(PermissionsBitField.Flags).find( + ([, v]) => v === b, + ); + + if (field === undefined) { + throw new Error( + `unknown permission \`${permission}\` in filter \`hasChannelPermission\``, + ); + } + + const [name] = field; + + function execute(context) { + if (context.member !== null) { + const channel = + channelId !== undefined + ? context.guild?.channels.cache.get(channelId) + : context.channel; // ? + + if (channel == undefined || channel === null) { + return false; + } + + if (channel.isDMBased()) { + return true; + } + + const field2 = channel.permissionsFor(context.user); // assume we have no permission overrides + + if (field2 === null) { + if (context.member !== null) { + if (typeof context.member.permissions === "string") { + return new PermissionsBitField( + BigInt(context.member.permissions), + ).has(b); + } + + return context.member.permissions.has(b); + } + + return false; + } + + return field2.has(b); + } + + return true; + } + + return new FilterImpl( + new Criteria("hasChannelPermission", execute, []), + channelId !== undefined + ? `has channel permission ${name} in <#${channelId}>` + : `has channel permission ${name}`, + ); +}; +export const canAddReactions = (channelId) => { + return hasChannelPermission("AddReactions", channelId); +}; +export const canAttachFiles = (channelId) => { + return hasChannelPermission("AttachFiles", channelId); +}; +export const canBanMembers = () => { + return hasGuildPermission("BanMembers"); +}; +export const canChangeNickname = () => { + return hasGuildPermission("ChangeNickname"); +}; +export const canConnect = (channelId) => { + return hasChannelPermission("Connect", channelId); +}; +export const canCreateInstantInvite = (channelId) => { + return hasChannelPermission("CreateInstantInvite", channelId); +}; +export const canDeafenMembers = (channelId) => { + return hasChannelPermission("DeafenMembers", channelId); +}; +export const canEmbedLinks = (channelId) => { + return hasChannelPermission("EmbedLinks", channelId); +}; +export const canKickMembers = () => { + return hasGuildPermission("KickMembers"); +}; +export const canManageChannelWebhooks = (channelId) => { + return hasChannelPermission("ManageWebhooks", channelId); +}; +export const canManageChannels = (channelId) => { + return hasChannelPermission("ManageChannels", channelId); +}; +export const canManageEmojisAndStickers = () => { + return hasGuildPermission("ManageEmojisAndStickers"); +}; +export const canManageGuild = () => { + return hasGuildPermission("ManageGuild"); +}; +export const canManageGuildWebhooks = () => { + return hasGuildPermission("ManageWebhooks"); +}; +export const canManageMessages = (channelId) => { + return hasChannelPermission("ManageMessages", channelId); +}; +export const canManageNicknames = () => { + return hasGuildPermission("ManageNicknames"); +}; +export const canManageRoles = () => { + return hasGuildPermission("ManageRoles"); +}; +export const canMentionEveryone = (channelId) => { + return hasChannelPermission("MentionEveryone", channelId); +}; +export const canMoveMembers = (channelId) => { + return hasChannelPermission("MoveMembers", channelId); +}; +export const canMuteMembers = (channelId) => { + return hasChannelPermission("MuteMembers", channelId); +}; +export const canPrioritySpeaker = (channelId) => { + return hasChannelPermission("PrioritySpeaker", channelId); +}; +export const canReadMessageHistory = (channelId) => { + return hasChannelPermission("ReadMessageHistory", channelId); +}; +export const canViewChannel = (channelId) => { + return hasChannelPermission("ViewChannel", channelId); +}; +export const canSendMessages = (channelId) => { + return hasChannelPermission("SendMessages", channelId); +}; +export const canSendTtsMessages = (channelId) => { + return hasChannelPermission("SendTTSMessages", channelId); +}; +export const canSpeak = (channelId) => { + return hasChannelPermission("Speak", channelId); +}; +export const canStream = (channelId) => { + return hasChannelPermission("Stream", channelId); +}; +export const canUseExternalEmojis = (channelId) => { + return hasChannelPermission("UseExternalEmojis", channelId); +}; +export const canUseVoiceActivity = (channelId) => { + return hasChannelPermission("UseVAD", channelId); +}; +export const canViewAuditLog = () => { + return hasGuildPermission("ViewAuditLog"); +}; +export const canViewGuildInsights = () => { + return hasGuildPermission("ViewGuildInsights"); +}; +export const channelIdIn = (channelIds) => { + function execute(context) { + return channelIds.includes( + context.isMessage() + ? context.message.channelId + : context.interaction.channelId, + ); + } + + return new FilterImpl( + new Criteria("channelIdIn", execute, []), + `channel is one of: ${channelIds.map((v) => `<#${v}>`).join(", ")}`, + ); +}; +export const hasEveryRole = (roles) => { + return withCustomMessage( + and(...roles.map((v) => hasRole(v))), + `has all of: ${roles.map((v) => `<@&${v}>`).join(", ")}`, + ); +}; +export const hasMentionableRole = () => { + function execute(context) { + if (context.member !== null) { + if (context.member.roles instanceof GuildMemberRoleManager) { + return ( + context.member.roles.cache.filter( + (x) => x.mentionable === true, + ).size > 0 + ); + } + + if (context.guild === null) { + return false; + } + + return context.member.roles + .map((roleId) => context.guild.roles.cache.get(roleId)) + .filter((x) => x !== undefined) + .some((x) => x.mentionable); + } + + return false; + } + + return new FilterImpl( + new Criteria("hasMentionableRole", execute, []), + "has a mentionable role", + ); +}; +export const hasNickname = (nickname) => { + function execute(context) { + if (context.member !== null) { + if (context.member instanceof GuildMember) { + if (nickname !== null) { + return context.member.nickname === nickname; + } + + return context.member.nickname !== null; + } + + if (nickname !== null) { + return context.member.nick === nickname; + } + + return ( + context.member.nick !== null && + context.member.nick !== undefined + ); + } // dm members can technically have nicknames but they're per-user, so this should never be true. + + return false; + } + + return new FilterImpl( + new Criteria("hasNickname", execute, []), + "has a nickname", + ); +}; +export const hasParentId = (parentId) => { + function execute(context) { + if (context.channel !== null) { + if (context.channel.isDMBased()) { + return false; + } + + return context.channel.parentId === parentId; + } + + return false; + } + + return new FilterImpl( + new Criteria("hasParentId", execute, []), + `has channel parent <#${parentId}>`, + ); +}; +export const hasRole = (roleId) => { + function execute(context) { + if (context.member !== null) { + if (context.member.roles instanceof GuildMemberRoleManager) { + return context.member.roles.cache.has(roleId); + } + + if (context.guild === null) { + return false; + } + + return context.member.roles.includes(roleId); + } // assume dm members have every role ever. + + return true; + } + + return new FilterImpl( + new Criteria("hasRole", execute, []), + `has role <@&${roleId}>`, + ); +}; +export const hasSomeRole = (roles) => { + return withCustomMessage( + or(...roles.map((role) => hasRole(role))), + `has any of: ${roles.map((v) => `<@&${v}>`).join(", ")}`, + ); +}; +export const isAdministator = () => { + return hasGuildPermission("Administrator"); +}; +export const isChannelId = (channelId) => { + function execute(context) { + if (context.isMessage()) { + return context.message.channelId === channelId; + } + + return context.interaction.channelId === channelId; + } + + return new FilterImpl( + new Criteria("isChannelId", execute, []), + `is channel <#${channelId}>`, + ); +}; +export const isChannelNsfw = () => { + function execute(context) { + if (context.channel !== null) { + if (context.channel.isDMBased() || context.channel.isThread()) { + return false; + } + + return context.channel.nsfw; + } + + return false; + } + + return new FilterImpl( + new Criteria("isChannelNsfw", execute, []), + "channel marked as nsfw", + ); +}; +export const isGuildOwner = () => { + function execute(context) { + if (context.guild !== null) { + return context.guild.ownerId === context.user.id; + } + + return true; + } + + return new FilterImpl( + new Criteria("isGuildOwner", execute, []), + "is guild owner", + ); +}; +export const isBotOwner = () => { + function execute(context) { + if (context.client.application !== null) { + if (context.client.application.owner !== null) { + if (context.client.application.owner instanceof User) { + return ( + context.user.id === context.client.application.owner.id + ); + } + + return context.client.application.owner.members.has( + context.user.id, + ); + } + } // nope + + return false; + } + + return new FilterImpl( + new Criteria("isBotOwner", execute, []), + "is bot owner", + ); +}; +export const isUserId = (userId) => { + function execute(context) { + return context.user.id === userId; + } + + return new FilterImpl( + new Criteria("isUserId", execute, []), + `is user: <@${userId}>`, + ); +}; +export const parentIdIn = (parentIds) => { + return withCustomMessage( + or(...parentIds.map((v) => hasParentId(v))), + `channel parent is one of: ${parentIds + .map((v) => `<#${v}>`) + .join(", ")}`, + ); +}; +export const userIdIn = (userIds) => { + return withCustomMessage( + or(...userIds.map((v) => isUserId(v))), + `user is one of: ${userIds.map((v) => `<@${v}>`).join(", ")}`, + ); +}; +export const isInGuild = () => { + function execute(context) { + return context.guildId !== null; + } + + return new FilterImpl( + new Criteria("isInGuild", execute, []), + "is in guild", + ); +}; +export const isInDm = () => { + const notInGuild = compose(not, isInGuild); + return withCustomMessage(notInGuild(), "is in dm"); +}; +export const never = () => { + function execute(context) { + void context; + return false; + } + + return new FilterImpl(new Criteria("never", execute, []), "never"); +}; +export const always = () => { + function execute(context) { + void context; + return true; + } + + return new FilterImpl(new Criteria("always", execute, []), "always"); +}; + +/** + * Call FilterImpls in right to left order. + * @example + * import { compose, isUserId, not } from '../plugins/filter' + * const isNotUserId = compose(not, isUserId) + * + */ +export const compose = (...funcs) => { + return ( + arg, //@ts-ignore + ) => funcs.reduceRight((result, func) => func(result), arg); +}; +export class FilterImpl { + constructor(criteria, message) { + this.criteria = criteria; + this.message = message; + this.test = this.criteria.execute; + } +} + +/** + * @plugin + * Generalized `filter` plugin. revised by jacoobes, all credit to original author. + * Perform declarative conditionals as plugins. + * @author @trueharuu [<@504698587221852172>] + * @version 2.0.0 + * @example + * import { filter, not, isGuildOwner, canMentionEveryone } from '../plugins/filter'; + * import { commandModule } from '@sern/handler'; + * + * export default commandModule({ + * plugins: [filter({ condition: [not(isGuildOwner()), canMentionEveryone()] })], + * async execute(context) { + * // your code here + * } + * }); + * @end + */ +export const filter = (options) => { + return CommandControlPlugin(async (context) => { + const arrayifiedCondition = Array.isArray(options.condition) + ? options.condition + : [options.condition]; + const value = and(...arrayifiedCondition).test(context); + + if (value) { + return controller.next(); + } + + if (options.onFailed !== undefined) { + await options.onFailed(context, arrayifiedCondition); + } else { + await context.reply({ + ephemeral: true, + content: `you do not match the criteria for this command:\n${arrayifiedCondition + .map((x) => x.message) + .filter((x) => x !== undefined) + .join("\n")}`, + allowedMentions: { + repliedUser: false, + parse: [], + }, + }); + } + + return controller.stop(); + }); +}; diff --git a/JavaScript/nsfwOnly.js b/JavaScript/nsfwOnly.js index 138d371..3d63a68 100644 --- a/JavaScript/nsfwOnly.js +++ b/JavaScript/nsfwOnly.js @@ -1,6 +1,7 @@ //@ts-nocheck /** + * @plugin * This plugin checks if the channel is nsfw and responds to user with a specified response if not nsfw * * @author @Benzo-Fury [<@762918086349029386>] @@ -16,6 +17,7 @@ * } * }) * ``` + * @end */ import { ChannelType } from "discord.js"; import { CommandControlPlugin, controller } from "@sern/handler"; diff --git a/JavaScript/ownerOnly.js b/JavaScript/ownerOnly.js index 03114f0..bd7faba 100644 --- a/JavaScript/ownerOnly.js +++ b/JavaScript/ownerOnly.js @@ -1,6 +1,7 @@ // @ts-nocheck /** + * @plugin * This is OwnerOnly plugin, it allows only bot owners to run the command, like eval. * * @author @EvolutionX-10 [<@697795666373640213>] @@ -16,6 +17,7 @@ * } * }) * ``` + * @end */ import { CommandControlPlugin, controller } from "@sern/handler"; const ownerIDs = ["697795666373640213"]; //! Fill your ID diff --git a/JavaScript/permCheck.js b/JavaScript/permCheck.js index b57ee21..2f41a0f 100644 --- a/JavaScript/permCheck.js +++ b/JavaScript/permCheck.js @@ -1,6 +1,7 @@ // @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). * * @author @Benzo-Fury [<@762918086349029386>] @@ -16,6 +17,7 @@ * } * }) * ``` + * @end */ import { CommandControlPlugin, controller } from "@sern/handler"; export function permCheck(perm, response) { @@ -23,7 +25,7 @@ export function permCheck(perm, response) { 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)" + "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(); diff --git a/JavaScript/publish.js b/JavaScript/publish.js index 86f23b9..9bfbc16 100644 --- a/JavaScript/publish.js +++ b/JavaScript/publish.js @@ -1,6 +1,7 @@ // @ts-nocheck /** + * @plugin * This is publish plugin, it allows you to publish your application commands using the discord.js library with ease. * * @author @EvolutionX-10 [<@697795666373640213>] @@ -17,13 +18,13 @@ * } * }) * ``` + * @end */ import { CommandInitPlugin, CommandType, controller } from "@sern/handler"; import { ApplicationCommandType, ApplicationCommandOptionType, } from "discord.js"; -import { useContainer } from "../index.js"; export const CommandTypeRaw = { [CommandType.Both]: ApplicationCommandType.ChatInput, [CommandType.CtxUser]: ApplicationCommandType.User, @@ -33,7 +34,15 @@ export const CommandTypeRaw = { export function publish(options) { return CommandInitPlugin(async ({ module }) => { // Users need to provide their own useContainer function. - const [client] = useContainer("@sern/client"); + let client; + + try { + client = (await import("@sern/handler")).Service("@sern/client"); + } catch { + const { useContainer } = await import("../index.js"); + client = useContainer("@sern/client")[0]; + } + const defaultOptions = { guildIds: [], dmPermission: undefined, @@ -85,18 +94,18 @@ export function publish(options) { if (!guildIds.length) { const cmd = (await client.application.commands.fetch()).find( - (c) => c.name === module.name && c.type === curAppType + (c) => c.name === module.name && c.type === curAppType, ); if (cmd) { if (!cmd.equals(commandData, true)) { logged( - `Found differences in global command ${module.name}` + `Found differences in global command ${module.name}`, ); cmd.edit(commandData).then( log( - `${module.name} updated with new data successfully!` - ) + `${module.name} updated with new data successfully!`, + ), ); } @@ -114,7 +123,7 @@ export function publish(options) { const guild = await client.guilds.fetch(id).catch(c); if (!guild) continue; const guildCmd = (await guild.commands.fetch()).find( - (c) => c.name === module.name && c.type === curAppType + (c) => c.name === module.name && c.type === curAppType, ); if (guildCmd) { @@ -124,8 +133,8 @@ export function publish(options) { .edit(commandData) .then( log( - `${module.name} updated with new data successfully!` - ) + `${module.name} updated with new data successfully!`, + ), ) .catch(c); continue; diff --git a/JavaScript/requirePermission.js b/JavaScript/requirePermission.js index 8b8dc3d..550f9d8 100644 --- a/JavaScript/requirePermission.js +++ b/JavaScript/requirePermission.js @@ -1,6 +1,7 @@ // @ts-nocheck /** + * @plugin * 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). * * @author @Benzo-Fury [<@762918086349029386>] @@ -17,6 +18,7 @@ * } * }) * ``` + * @end */ import { CommandControlPlugin, controller } from "@sern/handler"; @@ -36,7 +38,7 @@ export function requirePermission(target, perm, response) { if (ctx.guild === null) { ctx.reply(payload("This command cannot be used here")); console.warn( - "PermCheck > A command stopped because we couldn't check a users permissions (was used in dms)" + "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(); @@ -53,7 +55,7 @@ export function requirePermission(target, perm, response) { if (!bot.permissions.has(perm)) { if (!response) response = `I cannot use this command, please give me \`${perm.join( - ", " + ", ", )}\` permission(s).`; await ctx.reply(payload(response)); return controller.stop(); @@ -66,7 +68,7 @@ export function requirePermission(target, perm, response) { if (!memm.permissions.has(perm)) { if (!response) response = `You cannot use this command because you are missing \`${perm.join( - ", " + ", ", )}\` permission(s).`; await ctx.reply(payload(response)); return controller.stop(); diff --git a/JavaScript/serverOnly.js b/JavaScript/serverOnly.js index b93ec4e..1c484df 100644 --- a/JavaScript/serverOnly.js +++ b/JavaScript/serverOnly.js @@ -1,6 +1,7 @@ // @ts-nocheck /** + * @plugin * Checks if a command is available in a specific server. * * @author @Peter-MJ-Parker [<@371759410009341952>] @@ -18,11 +19,12 @@ * }, * }); * ``` + * @end */ import { controller, CommandControlPlugin } from "@sern/handler"; export function serverOnly( guildId, - failMessage = "This command is not available in this guild. \nFor permission to use in your server, please contact my developer." + failMessage = "This command is not available in this guild. \nFor permission to use in your server, please contact my developer.", ) { return CommandControlPlugin(async (ctx, _) => { if (ctx.guildId == null) { diff --git a/TypeScript/assertFields.ts b/TypeScript/assertFields.ts index e338d70..340eb25 100644 --- a/TypeScript/assertFields.ts +++ b/TypeScript/assertFields.ts @@ -52,7 +52,7 @@ export function assertFields(config: { errors.push( input + " failed to pass assertion " + - resolvedAssertion.toString() + resolvedAssertion.toString(), ); } } diff --git a/TypeScript/buttonConfirmation.ts b/TypeScript/buttonConfirmation.ts index ee2d75c..4f1f579 100644 --- a/TypeScript/buttonConfirmation.ts +++ b/TypeScript/buttonConfirmation.ts @@ -79,7 +79,7 @@ export function buttonConfirmation(options?: Partial) { await sent.edit({ components: [ new ActionRowBuilder().setComponents( - buttons + buttons, ), ], }); diff --git a/TypeScript/cooldown.ts b/TypeScript/cooldown.ts index 2d05866..e8336a8 100644 --- a/TypeScript/cooldown.ts +++ b/TypeScript/cooldown.ts @@ -45,7 +45,7 @@ export class ExpiryMap extends Map { public readonly expiry: number; constructor( expiry: number = Infinity, - iterable: [K, V][] | ReadonlyMap = [] + iterable: [K, V][] | ReadonlyMap = [], ) { super(iterable); this.expiry = expiry; @@ -65,7 +65,7 @@ export const map = new ExpiryMap(); function parseCooldown( location: CooldownLocation, - cooldown: CooldownString + cooldown: CooldownString, ): Cooldown { const [actions, seconds] = cooldown.split("/").map((s) => Number(s)); @@ -113,7 +113,7 @@ function add( | [CooldownLocation | keyof typeof CooldownLocation, CooldownString] | Cooldown >, - message?: CooldownResponse + message?: CooldownResponse, ) { const raw = items.map((c) => { if (!Array.isArray(c)) return c; diff --git a/TypeScript/disable.ts b/TypeScript/disable.ts index 77be33e..c4be2dc 100644 --- a/TypeScript/disable.ts +++ b/TypeScript/disable.ts @@ -16,7 +16,7 @@ * //your code here * } * }) - * ``` + * ``` * @end */ import { CommandType, CommandControlPlugin, controller } from "@sern/handler"; @@ -30,7 +30,7 @@ export function disable( onFail?: | string | Omit - | ReplyMessageOptions + | ReplyMessageOptions, ) { return CommandControlPlugin(async (ctx, [args]) => { if (onFail !== undefined) { diff --git a/TypeScript/dmOnly.ts b/TypeScript/dmOnly.ts index a9760ca..b33ff79 100644 --- a/TypeScript/dmOnly.ts +++ b/TypeScript/dmOnly.ts @@ -15,7 +15,7 @@ * //your code here * } * }) - * ``` + * ``` * @end */ import { CommandControlPlugin, CommandType, controller } from "@sern/handler"; diff --git a/TypeScript/filter.ts b/TypeScript/filter.ts index e4a67fb..3db8dda 100644 --- a/TypeScript/filter.ts +++ b/TypeScript/filter.ts @@ -1,601 +1,614 @@ import { - CommandControlPlugin, - type CommandType, - type Context, - controller, + CommandControlPlugin, + type CommandType, + type Context, + controller, } from "@sern/handler"; import { - GuildMember, - GuildMemberRoleManager, - PermissionResolvable, - PermissionsBitField, - User, + GuildMember, + GuildMemberRoleManager, + PermissionResolvable, + PermissionsBitField, + User, } from "discord.js"; - export type Test = (context: Context) => boolean; export class Criteria { - public constructor( - public readonly name: string, - public readonly execute: Test, - public readonly children: Array - ) {} - toString() { - return this.name + ' ' + this.children.map(c => c.name).join(', ') - } + public constructor( + public readonly name: string, + public readonly execute: Test, + public readonly children: Array, + ) {} + toString() { + return this.name + " " + this.children.map((c) => c.name).join(", "); + } } export const or = (...filters: Array): FilterImpl => { - function execute(context: Context): boolean { - let pass = false; - tests: for (const filter of filters) { - if (filter.test(context)) { - pass = true; - break tests; - } - } + function execute(context: Context): boolean { + let pass = false; + tests: for (const filter of filters) { + if (filter.test(context)) { + pass = true; + break tests; + } + } - return pass; - } + return pass; + } - const children: Array = filters.map((x) => x.criteria); - - return new FilterImpl( - new Criteria("or", execute, children), - `or(${filters.map((x) => x.message).join(", ")})` - ); -} + const children: Array = filters.map((x) => x.criteria); + return new FilterImpl( + new Criteria("or", execute, children), + `or(${filters.map((x) => x.message).join(", ")})`, + ); +}; export const and = (...filters: Array): FilterImpl => { - function execute(context: Context): boolean { - for (const filter of filters) { - if (!filter.test(context)) { - return false; - } - } + function execute(context: Context): boolean { + for (const filter of filters) { + if (!filter.test(context)) { + return false; + } + } - return true; - } + return true; + } - const children: Array = filters.map((x) => x.criteria); - - return new FilterImpl( - new Criteria("and", execute, children), - `and(${filters.map((x) => x.message).join(", ")})` - ); - -} + const children: Array = filters.map((x) => x.criteria); + return new FilterImpl( + new Criteria("and", execute, children), + `and(${filters.map((x) => x.message).join(", ")})`, + ); +}; export const not = (filter: FilterImpl): FilterImpl => { - function execute(context: Context): boolean { - return !filter.test(context); - } + function execute(context: Context): boolean { + return !filter.test(context); + } - return new FilterImpl( - new Criteria("not", execute, [filter.criteria]), - `not(${filter.criteria})` - ); - } -export const custom =(execute: Test, message?: string): FilterImpl => { - return new FilterImpl(new Criteria("custom", execute, []), message); -} + return new FilterImpl( + new Criteria("not", execute, [filter.criteria]), + `not(${filter.criteria})`, + ); +}; +export const custom = (execute: Test, message?: string): FilterImpl => { + return new FilterImpl(new Criteria("custom", execute, []), message); +}; export const withCustomMessage = ( - filter: FilterImpl, - message?: string + filter: FilterImpl, + message?: string, ): FilterImpl => { - return new FilterImpl(filter.criteria, message); -} + return new FilterImpl(filter.criteria, message); +}; export const hasGuildPermission = ( - permission: PermissionResolvable + permission: PermissionResolvable, ): FilterImpl => { - const b = PermissionsBitField.resolve(permission); - const field = Object.entries(PermissionsBitField.Flags).find( - ([, v]) => v === b - ); + const b = PermissionsBitField.resolve(permission); + const field = Object.entries(PermissionsBitField.Flags).find( + ([, v]) => v === b, + ); - if (field === undefined) { - throw new Error( - `unknown permission \`${permission}\` in filter \`hasGuildPermission\`` - ); - } + if (field === undefined) { + throw new Error( + `unknown permission \`${permission}\` in filter \`hasGuildPermission\``, + ); + } - const [name] = field; + const [name] = field; - function execute(context: Context): boolean { - if (context.member !== null) { - if (typeof context.member.permissions === "string") { - return new PermissionsBitField(BigInt(context.member.permissions)).has(b); - } - return context.member.permissions.has(b); - } + function execute(context: Context): boolean { + if (context.member !== null) { + if (typeof context.member.permissions === "string") { + return new PermissionsBitField( + BigInt(context.member.permissions), + ).has(b); + } + return context.member.permissions.has(b); + } - return true; - } + return true; + } - return new FilterImpl( - new Criteria("hasGuildPermission", execute, []), - `has guild permission: ${name}` - ); -} + return new FilterImpl( + new Criteria("hasGuildPermission", execute, []), + `has guild permission: ${name}`, + ); +}; export const hasChannelPermission = ( - permission: PermissionResolvable, - channelId?: string - ): FilterImpl => { - const b = PermissionsBitField.resolve(permission); - const field = Object.entries(PermissionsBitField.Flags).find( - ([, v]) => v === b - ); + permission: PermissionResolvable, + channelId?: string, +): FilterImpl => { + const b = PermissionsBitField.resolve(permission); + const field = Object.entries(PermissionsBitField.Flags).find( + ([, v]) => v === b, + ); - if (field === undefined) { - throw new Error( - `unknown permission \`${permission}\` in filter \`hasChannelPermission\`` - ); - } + if (field === undefined) { + throw new Error( + `unknown permission \`${permission}\` in filter \`hasChannelPermission\``, + ); + } - const [name] = field; + const [name] = field; - function execute(context: Context): boolean { - if (context.member !== null) { - const channel = - channelId !== undefined - ? context.guild?.channels.cache.get(channelId) - : context.channel; + function execute(context: Context): boolean { + if (context.member !== null) { + const channel = + channelId !== undefined + ? context.guild?.channels.cache.get(channelId) + : context.channel; - // ? - if (channel == undefined || channel === null) { - return false; - } + // ? + if (channel == undefined || channel === null) { + return false; + } - if (channel.isDMBased()) { - return true; - } + if (channel.isDMBased()) { + return true; + } - const field2 = channel.permissionsFor(context.user); + const field2 = channel.permissionsFor(context.user); - // assume we have no permission overrides - if (field2 === null) { - if (context.member !== null) { - if (typeof context.member.permissions === "string") { - return new PermissionsBitField( - BigInt(context.member.permissions) - ).has(b); - } + // assume we have no permission overrides + if (field2 === null) { + if (context.member !== null) { + if (typeof context.member.permissions === "string") { + return new PermissionsBitField( + BigInt(context.member.permissions), + ).has(b); + } - return context.member.permissions.has(b); - } + return context.member.permissions.has(b); + } - return false; - } + return false; + } - return field2.has(b); - } + return field2.has(b); + } - return true; - } + return true; + } - return new FilterImpl( - new Criteria("hasChannelPermission", execute, []), - channelId !== undefined - ? `has channel permission ${name} in <#${channelId}>` - : `has channel permission ${name}` - ); - } + return new FilterImpl( + new Criteria("hasChannelPermission", execute, []), + channelId !== undefined + ? `has channel permission ${name} in <#${channelId}>` + : `has channel permission ${name}`, + ); +}; -export const canAddReactions =(channelId?: string): FilterImpl => { - return hasChannelPermission("AddReactions", channelId); -} +export const canAddReactions = (channelId?: string): FilterImpl => { + return hasChannelPermission("AddReactions", channelId); +}; -export const canAttachFiles =(channelId?: string): FilterImpl => { - return hasChannelPermission("AttachFiles", channelId); -} +export const canAttachFiles = (channelId?: string): FilterImpl => { + return hasChannelPermission("AttachFiles", channelId); +}; export const canBanMembers = (): FilterImpl => { - return hasGuildPermission("BanMembers"); -} + return hasGuildPermission("BanMembers"); +}; export const canChangeNickname = (): FilterImpl => { - return hasGuildPermission("ChangeNickname"); -} + return hasGuildPermission("ChangeNickname"); +}; export const canConnect = (channelId?: string): FilterImpl => { - return hasChannelPermission("Connect", channelId); -} + return hasChannelPermission("Connect", channelId); +}; -export const canCreateInstantInvite =(channelId?: string): FilterImpl => { - return hasChannelPermission("CreateInstantInvite", channelId); - } +export const canCreateInstantInvite = (channelId?: string): FilterImpl => { + return hasChannelPermission("CreateInstantInvite", channelId); +}; -export const canDeafenMembers =(channelId?: string): FilterImpl => { - return hasChannelPermission("DeafenMembers", channelId); - } +export const canDeafenMembers = (channelId?: string): FilterImpl => { + return hasChannelPermission("DeafenMembers", channelId); +}; -export const canEmbedLinks =(channelId?: string): FilterImpl => { - return hasChannelPermission("EmbedLinks", channelId); - } +export const canEmbedLinks = (channelId?: string): FilterImpl => { + return hasChannelPermission("EmbedLinks", channelId); +}; -export const canKickMembers =(): FilterImpl => { - return hasGuildPermission("KickMembers"); - } +export const canKickMembers = (): FilterImpl => { + return hasGuildPermission("KickMembers"); +}; -export const canManageChannelWebhooks =(channelId?: string): FilterImpl => { - return hasChannelPermission("ManageWebhooks", channelId); - } +export const canManageChannelWebhooks = (channelId?: string): FilterImpl => { + return hasChannelPermission("ManageWebhooks", channelId); +}; -export const canManageChannels =(channelId?: string): FilterImpl => { - return hasChannelPermission("ManageChannels", channelId); -} +export const canManageChannels = (channelId?: string): FilterImpl => { + return hasChannelPermission("ManageChannels", channelId); +}; -export const canManageEmojisAndStickers =(): FilterImpl => { - return hasGuildPermission("ManageEmojisAndStickers"); -} +export const canManageEmojisAndStickers = (): FilterImpl => { + return hasGuildPermission("ManageEmojisAndStickers"); +}; -export const canManageGuild =(): FilterImpl => { - return hasGuildPermission("ManageGuild"); -} +export const canManageGuild = (): FilterImpl => { + return hasGuildPermission("ManageGuild"); +}; -export const canManageGuildWebhooks =(): FilterImpl => { - return hasGuildPermission("ManageWebhooks"); -} +export const canManageGuildWebhooks = (): FilterImpl => { + return hasGuildPermission("ManageWebhooks"); +}; -export const canManageMessages =(channelId?: string): FilterImpl => { - return hasChannelPermission("ManageMessages", channelId); -} +export const canManageMessages = (channelId?: string): FilterImpl => { + return hasChannelPermission("ManageMessages", channelId); +}; export const canManageNicknames = (): FilterImpl => { - return hasGuildPermission("ManageNicknames"); -} + return hasGuildPermission("ManageNicknames"); +}; export const canManageRoles = (): FilterImpl => { - return hasGuildPermission("ManageRoles"); -} + return hasGuildPermission("ManageRoles"); +}; export const canMentionEveryone = (channelId?: string): FilterImpl => { - return hasChannelPermission("MentionEveryone", channelId); - } + return hasChannelPermission("MentionEveryone", channelId); +}; export const canMoveMembers = (channelId?: string): FilterImpl => { - return hasChannelPermission("MoveMembers", channelId); - } + return hasChannelPermission("MoveMembers", channelId); +}; export const canMuteMembers = (channelId?: string): FilterImpl => { - return hasChannelPermission("MuteMembers", channelId); - } + return hasChannelPermission("MuteMembers", channelId); +}; export const canPrioritySpeaker = (channelId?: string): FilterImpl => { - return hasChannelPermission("PrioritySpeaker", channelId); - } + return hasChannelPermission("PrioritySpeaker", channelId); +}; export const canReadMessageHistory = (channelId?: string): FilterImpl => { - return hasChannelPermission("ReadMessageHistory", channelId); - } + return hasChannelPermission("ReadMessageHistory", channelId); +}; export const canViewChannel = (channelId: string): FilterImpl => { - return hasChannelPermission("ViewChannel", channelId); - } + return hasChannelPermission("ViewChannel", channelId); +}; export const canSendMessages = (channelId: string): FilterImpl => { - return hasChannelPermission("SendMessages", channelId); - } + return hasChannelPermission("SendMessages", channelId); +}; export const canSendTtsMessages = (channelId?: string): FilterImpl => { - return hasChannelPermission("SendTTSMessages", channelId); - } + return hasChannelPermission("SendTTSMessages", channelId); +}; export const canSpeak = (channelId?: string): FilterImpl => { - return hasChannelPermission("Speak", channelId); - } + return hasChannelPermission("Speak", channelId); +}; export const canStream = (channelId?: string): FilterImpl => { - return hasChannelPermission("Stream", channelId); - } + return hasChannelPermission("Stream", channelId); +}; export const canUseExternalEmojis = (channelId?: string): FilterImpl => { - return hasChannelPermission("UseExternalEmojis", channelId); - } + return hasChannelPermission("UseExternalEmojis", channelId); +}; export const canUseVoiceActivity = (channelId?: string): FilterImpl => { - return hasChannelPermission("UseVAD", channelId); - } + return hasChannelPermission("UseVAD", channelId); +}; export const canViewAuditLog = (): FilterImpl => { - return hasGuildPermission("ViewAuditLog"); - } + return hasGuildPermission("ViewAuditLog"); +}; export const canViewGuildInsights = (): FilterImpl => { - return hasGuildPermission("ViewGuildInsights"); - } + return hasGuildPermission("ViewGuildInsights"); +}; export const channelIdIn = (channelIds: Array): FilterImpl => { - function execute(context: Context): boolean { - return channelIds.includes( - context.isMessage() - ? context.message.channelId - : context.interaction.channelId - ); - } + function execute(context: Context): boolean { + return channelIds.includes( + context.isMessage() + ? context.message.channelId + : context.interaction.channelId, + ); + } - return new FilterImpl( - new Criteria("channelIdIn", execute, []), - `channel is one of: ${channelIds.map((v) => `<#${v}>`).join(", ")}` - ); - } + return new FilterImpl( + new Criteria("channelIdIn", execute, []), + `channel is one of: ${channelIds.map((v) => `<#${v}>`).join(", ")}`, + ); +}; export const hasEveryRole = (roles: Array): FilterImpl => { - return withCustomMessage( - and(...roles.map((v) => hasRole(v))), - `has all of: ${roles.map((v) => `<@&${v}>`).join(", ")}` - ); - } + return withCustomMessage( + and(...roles.map((v) => hasRole(v))), + `has all of: ${roles.map((v) => `<@&${v}>`).join(", ")}`, + ); +}; export const hasMentionableRole = (): FilterImpl => { - function execute(context: Context): boolean { - if (context.member !== null) { - if (context.member.roles instanceof GuildMemberRoleManager) { - return ( - context.member.roles.cache.filter((x) => x.mentionable === true) - .size > 0 - ); - } + function execute(context: Context): boolean { + if (context.member !== null) { + if (context.member.roles instanceof GuildMemberRoleManager) { + return ( + context.member.roles.cache.filter( + (x) => x.mentionable === true, + ).size > 0 + ); + } - if (context.guild === null) { - return false; - } + if (context.guild === null) { + return false; + } - return context.member.roles - .map((roleId) => context.guild!.roles.cache.get(roleId)) - .filter((x) => x !== undefined) - .some((x) => x!.mentionable); - } + return context.member.roles + .map((roleId) => context.guild!.roles.cache.get(roleId)) + .filter((x) => x !== undefined) + .some((x) => x!.mentionable); + } - return false; - } - return new FilterImpl( - new Criteria("hasMentionableRole", execute, []), - "has a mentionable role" - ); - } + return false; + } + return new FilterImpl( + new Criteria("hasMentionableRole", execute, []), + "has a mentionable role", + ); +}; export const hasNickname = (nickname?: string): FilterImpl => { - function execute(context: Context): boolean { - if (context.member !== null) { - if (context.member instanceof GuildMember) { - if (nickname !== null) { - return context.member.nickname === nickname; - } + function execute(context: Context): boolean { + if (context.member !== null) { + if (context.member instanceof GuildMember) { + if (nickname !== null) { + return context.member.nickname === nickname; + } - return context.member.nickname !== null; - } + return context.member.nickname !== null; + } - if (nickname !== null) { - return context.member.nick === nickname; - } + if (nickname !== null) { + return context.member.nick === nickname; + } - return ( - context.member.nick !== null && context.member.nick !== undefined - ); - } + return ( + context.member.nick !== null && + context.member.nick !== undefined + ); + } - // dm members can technically have nicknames but they're per-user, so this should never be true. - return false; - } - return new FilterImpl(new Criteria("hasNickname", execute, []), "has a nickname"); - } + // dm members can technically have nicknames but they're per-user, so this should never be true. + return false; + } + return new FilterImpl( + new Criteria("hasNickname", execute, []), + "has a nickname", + ); +}; export const hasParentId = (parentId: string): FilterImpl => { - function execute(context: Context): boolean { - if (context.channel !== null) { - if (context.channel.isDMBased()) { - return false; - } + function execute(context: Context): boolean { + if (context.channel !== null) { + if (context.channel.isDMBased()) { + return false; + } - return context.channel.parentId === parentId; - } + return context.channel.parentId === parentId; + } - return false; - } + return false; + } - return new FilterImpl( - new Criteria("hasParentId", execute, []), - `has channel parent <#${parentId}>` - ); - } + return new FilterImpl( + new Criteria("hasParentId", execute, []), + `has channel parent <#${parentId}>`, + ); +}; export const hasRole = (roleId: string): FilterImpl => { - function execute(context: Context): boolean { - if (context.member !== null) { - if (context.member.roles instanceof GuildMemberRoleManager) { - return context.member.roles.cache.has(roleId); - } + function execute(context: Context): boolean { + if (context.member !== null) { + if (context.member.roles instanceof GuildMemberRoleManager) { + return context.member.roles.cache.has(roleId); + } - if (context.guild === null) { - return false; - } + if (context.guild === null) { + return false; + } - return context.member.roles.includes(roleId); - } + return context.member.roles.includes(roleId); + } - // assume dm members have every role ever. - return true; - } + // assume dm members have every role ever. + return true; + } - return new FilterImpl( - new Criteria("hasRole", execute, []), - `has role <@&${roleId}>` - ); - } + return new FilterImpl( + new Criteria("hasRole", execute, []), + `has role <@&${roleId}>`, + ); +}; export const hasSomeRole = (roles: Array): FilterImpl => { - return withCustomMessage( - or(...roles.map((role) => hasRole(role))), - `has any of: ${roles.map((v) => `<@&${v}>`).join(", ")}` - ); - } + return withCustomMessage( + or(...roles.map((role) => hasRole(role))), + `has any of: ${roles.map((v) => `<@&${v}>`).join(", ")}`, + ); +}; export const isAdministator = (): FilterImpl => { - return hasGuildPermission("Administrator"); - } + return hasGuildPermission("Administrator"); +}; export const isChannelId = (channelId: string): FilterImpl => { - function execute(context: Context): boolean { - if (context.isMessage()) { - return context.message.channelId === channelId; - } + function execute(context: Context): boolean { + if (context.isMessage()) { + return context.message.channelId === channelId; + } - return context.interaction.channelId === channelId; - } + return context.interaction.channelId === channelId; + } - return new FilterImpl( - new Criteria("isChannelId", execute, []), - `is channel <#${channelId}>` - ); - } + return new FilterImpl( + new Criteria("isChannelId", execute, []), + `is channel <#${channelId}>`, + ); +}; export const isChannelNsfw = (): FilterImpl => { - function execute(context: Context): boolean { - if (context.channel !== null) { - if (context.channel.isDMBased() || context.channel.isThread()) { - return false; - } + function execute(context: Context): boolean { + if (context.channel !== null) { + if (context.channel.isDMBased() || context.channel.isThread()) { + return false; + } - return context.channel.nsfw; - } + return context.channel.nsfw; + } - return false; - } - return new FilterImpl( - new Criteria("isChannelNsfw", execute, []), - "channel marked as nsfw" - ); - } + return false; + } + return new FilterImpl( + new Criteria("isChannelNsfw", execute, []), + "channel marked as nsfw", + ); +}; export const isGuildOwner = (): FilterImpl => { - function execute(context: Context): boolean { - if (context.guild !== null) { - return context.guild.ownerId === context.user.id; - } + function execute(context: Context): boolean { + if (context.guild !== null) { + return context.guild.ownerId === context.user.id; + } - return true; - } - return new FilterImpl( - new Criteria("isGuildOwner", execute, []), - "is guild owner" - ); - } + return true; + } + return new FilterImpl( + new Criteria("isGuildOwner", execute, []), + "is guild owner", + ); +}; export const isBotOwner = (): FilterImpl => { - function execute(context: Context): boolean { - if (context.client.application !== null) { - if (context.client.application.owner !== null) { - if (context.client.application.owner instanceof User) { - return context.user.id === context.client.application.owner.id; - } + function execute(context: Context): boolean { + if (context.client.application !== null) { + if (context.client.application.owner !== null) { + if (context.client.application.owner instanceof User) { + return ( + context.user.id === context.client.application.owner.id + ); + } - return context.client.application.owner.members.has(context.user.id); - } - } + return context.client.application.owner.members.has( + context.user.id, + ); + } + } - // nope - return false; - } - return new FilterImpl(new Criteria("isBotOwner", execute, []), "is bot owner"); - } + // nope + return false; + } + return new FilterImpl( + new Criteria("isBotOwner", execute, []), + "is bot owner", + ); +}; export const isUserId = (userId: string): FilterImpl => { - function execute(context: Context): boolean { - return context.user.id === userId; - } - return new FilterImpl( - new Criteria("isUserId", execute, []), - `is user: <@${userId}>` - ); - } + function execute(context: Context): boolean { + return context.user.id === userId; + } + return new FilterImpl( + new Criteria("isUserId", execute, []), + `is user: <@${userId}>`, + ); +}; export const parentIdIn = (parentIds: Array): FilterImpl => { - return withCustomMessage( - or(...parentIds.map((v) => hasParentId(v))), - `channel parent is one of: ${parentIds.map((v) => `<#${v}>`).join(", ")}` - ); - } + return withCustomMessage( + or(...parentIds.map((v) => hasParentId(v))), + `channel parent is one of: ${parentIds + .map((v) => `<#${v}>`) + .join(", ")}`, + ); +}; export const userIdIn = (userIds: Array): FilterImpl => { - return withCustomMessage( - or(...userIds.map((v) => isUserId(v))), - `user is one of: ${userIds.map((v) => `<@${v}>`).join(", ")}` - ); - } + return withCustomMessage( + or(...userIds.map((v) => isUserId(v))), + `user is one of: ${userIds.map((v) => `<@${v}>`).join(", ")}`, + ); +}; export const isInGuild = (): FilterImpl => { - function execute(context: Context): boolean { - return context.guildId !== null; - } + function execute(context: Context): boolean { + return context.guildId !== null; + } - return new FilterImpl(new Criteria("isInGuild", execute, []), "is in guild"); - } + return new FilterImpl( + new Criteria("isInGuild", execute, []), + "is in guild", + ); +}; export const isInDm = (): FilterImpl => { - const notInGuild = compose(not, isInGuild); - return withCustomMessage(notInGuild(), "is in dm"); -} + const notInGuild = compose(not, isInGuild); + return withCustomMessage(notInGuild(), "is in dm"); +}; export const never = (): FilterImpl => { - function execute(context: Context): boolean { - void context; - return false; - } - return new FilterImpl(new Criteria("never", execute, []), "never"); -} + function execute(context: Context): boolean { + void context; + return false; + } + return new FilterImpl(new Criteria("never", execute, []), "never"); +}; export const always = (): FilterImpl => { - function execute(context: Context): boolean { - void context; - return true; - } - return new FilterImpl(new Criteria("always", execute, []), "always"); -} + function execute(context: Context): boolean { + void context; + return true; + } + return new FilterImpl(new Criteria("always", execute, []), "always"); +}; type CtxMap = (arg: T) => FilterImpl; /** - * Call FilterImpls in right to left order. - * @example - * import { compose, isUserId, not } from '../plugins/filter' - * const isNotUserId = compose(not, isUserId) - * - */ + * Call FilterImpls in right to left order. + * @example + * import { compose, isUserId, not } from '../plugins/filter' + * const isNotUserId = compose(not, isUserId) + * + */ export const compose = (...funcs: CtxMap[]): CtxMap => { - return (arg: T): FilterImpl => - //@ts-ignore - funcs.reduceRight((result, func) => func(result), arg); -} - + return (arg: T): FilterImpl => + //@ts-ignore + funcs.reduceRight((result, func) => func(result), arg); +}; export class FilterImpl { - public readonly test: Test; + public readonly test: Test; - public constructor( - public readonly criteria: Criteria, - public message?: string - ) { - this.test = this.criteria.execute; - } + public constructor( + public readonly criteria: Criteria, + public message?: string, + ) { + this.test = this.criteria.execute; + } } - export type FilterOptions = { - condition: Array | FilterImpl, - onFailed?: (context: Context, filters: Array) => unknown + condition: Array | FilterImpl; + onFailed?: (context: Context, filters: Array) => unknown; }; /** * @plugin * Generalized `filter` plugin. revised by jacoobes, all credit to original author. - * Perform declarative conditionals as plugins. + * Perform declarative conditionals as plugins. * @author @trueharuu [<@504698587221852172>] * @version 2.0.0 - * @example + * @example * import { filter, not, isGuildOwner, canMentionEveryone } from '../plugins/filter'; * import { commandModule } from '@sern/handler'; * @@ -608,32 +621,33 @@ export type FilterOptions = { * @end */ -export const filter = - (options: FilterOptions) => { - return CommandControlPlugin(async (context) => { - const arrayifiedCondition = Array.isArray(options.condition) ? options.condition : [options.condition] - const value = and(...arrayifiedCondition).test(context); +export const filter = (options: FilterOptions) => { + return CommandControlPlugin(async (context) => { + const arrayifiedCondition = Array.isArray(options.condition) + ? options.condition + : [options.condition]; + const value = and(...arrayifiedCondition).test(context); - if (value) { - return controller.next(); - } + if (value) { + return controller.next(); + } - if (options.onFailed !== undefined) { - await options.onFailed(context, arrayifiedCondition); - } else { - await context.reply({ - ephemeral: true, - content: `you do not match the criteria for this command:\n${arrayifiedCondition - .map((x) => x.message) - .filter((x) => x !== undefined) - .join("\n")}`, - allowedMentions: { - repliedUser: false, - parse: [], - }, - }); - } + if (options.onFailed !== undefined) { + await options.onFailed(context, arrayifiedCondition); + } else { + await context.reply({ + ephemeral: true, + content: `you do not match the criteria for this command:\n${arrayifiedCondition + .map((x) => x.message) + .filter((x) => x !== undefined) + .join("\n")}`, + allowedMentions: { + repliedUser: false, + parse: [], + }, + }); + } - return controller.stop(); - }); - }; + return controller.stop(); + }); +}; diff --git a/TypeScript/nsfwOnly.ts b/TypeScript/nsfwOnly.ts index ca9a78e..a0ae9e4 100644 --- a/TypeScript/nsfwOnly.ts +++ b/TypeScript/nsfwOnly.ts @@ -15,7 +15,7 @@ * //your code here * } * }) - * ``` + * ``` * @end */ import { @@ -26,7 +26,7 @@ import { } from "discord.js"; import { CommandControlPlugin, CommandType, controller } from "@sern/handler"; function isGuildText( - channel: TextBasedChannel | null + channel: TextBasedChannel | null, ): channel is GuildTextBasedChannel { return ( channel?.type == ChannelType.GuildPublicThread || diff --git a/TypeScript/ownerOnly.ts b/TypeScript/ownerOnly.ts index 3986182..e45a9a4 100644 --- a/TypeScript/ownerOnly.ts +++ b/TypeScript/ownerOnly.ts @@ -15,7 +15,7 @@ * //your code here * } * }) - * ``` + * ``` * @end */ diff --git a/TypeScript/permCheck.ts b/TypeScript/permCheck.ts index c2809cf..7884997 100644 --- a/TypeScript/permCheck.ts +++ b/TypeScript/permCheck.ts @@ -26,7 +26,7 @@ export function permCheck(perm: PermissionResolvable, response: string) { 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)" + "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(); } diff --git a/TypeScript/publish.ts b/TypeScript/publish.ts index fda3260..4a68618 100644 --- a/TypeScript/publish.ts +++ b/TypeScript/publish.ts @@ -16,7 +16,7 @@ * //your code here * } * }) - * ``` + * ``` * @end */ import { @@ -46,16 +46,16 @@ export function publish< | CommandType.Both | CommandType.Slash | CommandType.CtxMsg - | CommandType.CtxUser + | CommandType.CtxUser, >(options?: PublishOptions) { return CommandInitPlugin(async ({ module }) => { // Users need to provide their own useContainer function. let client; try { - client = (await import('@sern/handler')).Service('@sern/client') + client = (await import("@sern/handler")).Service("@sern/client"); } catch { - const { useContainer } = await import('../index.js') - client = useContainer("@sern/client")[0]; + const { useContainer } = await import("../index.js"); + client = useContainer("@sern/client")[0]; } const defaultOptions = { guildIds: [], @@ -98,7 +98,7 @@ export function publish< description: cmd(module.description, ""), options: cmd( optionsTransformer((module as SlashCommand).options ?? []), - [] + [], ), defaultMemberPermissions, dmPermission, @@ -110,17 +110,17 @@ export function publish< if (!guildIds.length) { const cmd = (await client.application!.commands.fetch()).find( - (c) => c.name === module.name && c.type === curAppType + (c) => c.name === module.name && c.type === curAppType, ); if (cmd) { if (!cmd.equals(commandData, true)) { logged( - `Found differences in global command ${module.name}` + `Found differences in global command ${module.name}`, ); cmd.edit(commandData).then( log( - `${module.name} updated with new data successfully!` - ) + `${module.name} updated with new data successfully!`, + ), ); } return controller.next(); @@ -136,7 +136,7 @@ export function publish< const guild = await client.guilds.fetch(id).catch(c); if (!guild) continue; const guildCmd = (await guild.commands.fetch()).find( - (c) => c.name === module.name && c.type === curAppType + (c) => c.name === module.name && c.type === curAppType, ); if (guildCmd) { if (!guildCmd.equals(commandData, true)) { @@ -145,8 +145,8 @@ export function publish< .edit(commandData) .then( log( - `${module.name} updated with new data successfully!` - ) + `${module.name} updated with new data successfully!`, + ), ) .catch(c); continue; diff --git a/TypeScript/requirePermission.ts b/TypeScript/requirePermission.ts index db9b5c3..92f508c 100644 --- a/TypeScript/requirePermission.ts +++ b/TypeScript/requirePermission.ts @@ -16,7 +16,7 @@ * //your code here * } * }) - * ``` + * ``` * @end */ @@ -35,13 +35,13 @@ function payload(resp?: string) { export function requirePermission( target: "user" | "bot" | "both", perm: PermissionResolvable[], - response?: string + response?: string, ) { return CommandControlPlugin(async (ctx, args) => { if (ctx.guild === null) { ctx.reply(payload("This command cannot be used here")); console.warn( - "PermCheck > A command stopped because we couldn't check a users permissions (was used in dms)" + "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(); } @@ -55,7 +55,7 @@ export function requirePermission( if (!bot.permissions.has(perm)) { if (!response) response = `I cannot use this command, please give me \`${perm.join( - ", " + ", ", )}\` permission(s).`; await ctx.reply(payload(response)); return controller.stop(); @@ -66,7 +66,7 @@ export function requirePermission( if (!memm.permissions.has(perm)) { if (!response) response = `You cannot use this command because you are missing \`${perm.join( - ", " + ", ", )}\` permission(s).`; await ctx.reply(payload(response)); return controller.stop(); diff --git a/TypeScript/serverOnly.ts b/TypeScript/serverOnly.ts index 453fcd0..8f4378a 100644 --- a/TypeScript/serverOnly.ts +++ b/TypeScript/serverOnly.ts @@ -25,7 +25,7 @@ import { CommandType, controller, CommandControlPlugin } from "@sern/handler"; export function serverOnly( guildId: string[], - failMessage = "This command is not available in this guild. \nFor permission to use in your server, please contact my developer." + failMessage = "This command is not available in this guild. \nFor permission to use in your server, please contact my developer.", ) { return CommandControlPlugin(async (ctx, _) => { if (ctx.guildId == null) { diff --git a/pluginlist.json b/pluginlist.json index d7d0e87..31ea0c1 100644 --- a/pluginlist.json +++ b/pluginlist.json @@ -1,113 +1,134 @@ -[ { - "description" : "\n\n This plugin checks the fields of a ModalSubmitInteraction\n with regex or a custom callback\n", - "hash" : "2da46f3202e2b209ab24620d4f890da2", - "name" : "assertFields", - "author" : [ "@jacoobes [<@182326315813306368>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 ```\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" : "d752596f5d9871e469d142ccf5569691", - "name" : "buttonConfirmation", - "author" : [ "@EvolutionX-10 [<@697795666373640213>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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" -}, { - "description" : "\n\n This plugin checks if a channel is the specified type\n", - "hash" : "a3f95ec62e1480b8c3318443cc8184c0", - "name" : "channelType", - "author" : [ "@Benzo-Fury [<@762918086349029386>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/channelType.ts", - "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 Asks the user for a confirmation message before executing the command\n", - "hash" : "77e7cc0e4f9706183d2debb918056809", - "name" : "confirmation", - "author" : [ "@trueharuu [<@504698587221852172>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 Allows you to set cooldowns (or \"ratelimits\") for commands\n limits user/channel/guild actions,", - "hash" : "5dfb3c2f533878a15cf9764ffb921d1e", - "name" : "cooldown", - "author" : [ "@trueharuu [<@504698587221852172>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/cooldown.ts", - "example" : "\n\n ```ts\n import { cooldown } from \"../plugins/cooldown\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [cooldown.add( [ ['channel', '1/4'] ] )], // limit to 1 action every 4 seconds per channel\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" : "96e4b5b562500b0bcdc442fbf130a555", - "name" : "disable", - "author" : [ "@jacoobes [<@182326315813306368>]", "@Peter-MJ-Parker [<@371759410009341952>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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.0.0" -}, { - "description" : "\n\n This is dmOnly plugin, it allows commands to be run only in DMs.\n", - "hash" : "844e68aa0c9147c98930b34a5d716a22", - "name" : "dmOnly", - "author" : [ "@EvolutionX-10 [<@697795666373640213>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 Generalized `filter` plugin. revised by jacoobes, all credit to original author.\n Perform declarative conditionals as plugins. ", - "hash" : "ba85e67d23bbfacc337f82e9fade283c", - "name" : "filter", - "author" : [ "@trueharuu [<@504698587221852172>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/filter.ts", - "example" : "\n\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 });", - "version" : "2.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" : "65ff8138fd20486d6eeff17cdb7b93cf", - "name" : "nsfwOnly", - "author" : [ "@Benzo-Fury [<@762918086349029386>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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.0" -}, { - "description" : "\n\n This is OwnerOnly plugin, it allows only bot owners to run the command, like eval.\n", - "hash" : "5ffb76d3a2ecdb0516fa98a93dd1d15d", - "name" : "ownerOnly", - "author" : [ "@EvolutionX-10 [<@697795666373640213>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 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" : "45fb62d9ffe908469ea58aabb550daf7", - "name" : "permCheck", - "author" : [ "@Benzo-Fury [<@762918086349029386>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 This is publish plugin, it allows you to publish your application commands using the discord.js library with ease.\n", - "hash" : "3f76c395a51cccc9c66de9ea65d28b19", - "name" : "publish", - "author" : [ "@EvolutionX-10 [<@697795666373640213>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 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" : "bad95c4cf2105d9f60363ddf16ab7b82", - "name" : "requirePermission", - "author" : [ "@Benzo-Fury [<@762918086349029386>]", "@needhamgary [<@342314924804014081>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 Checks if a command is available in a specific server.\n", - "hash" : "b1d78678451c260286a97de8f1cb9e07", - "name" : "serverOnly", - "author" : [ "@Peter-MJ-Parker [<@371759410009341952>]" ], - "link" : "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/serverOnly.ts", - "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" -} ] \ No newline at end of file +[ + { + "description": "\n\n This plugin checks the fields of a ModalSubmitInteraction\n with regex or a custom callback\n", + "hash": "2da46f3202e2b209ab24620d4f890da2", + "name": "assertFields", + "author": ["@jacoobes [<@182326315813306368>]"], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 ```\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": "d752596f5d9871e469d142ccf5569691", + "name": "buttonConfirmation", + "author": ["@EvolutionX-10 [<@697795666373640213>]"], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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" + }, + { + "description": "\n\n This plugin checks if a channel is the specified type\n", + "hash": "a3f95ec62e1480b8c3318443cc8184c0", + "name": "channelType", + "author": ["@Benzo-Fury [<@762918086349029386>]"], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/channelType.ts", + "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 Asks the user for a confirmation message before executing the command\n", + "hash": "77e7cc0e4f9706183d2debb918056809", + "name": "confirmation", + "author": ["@trueharuu [<@504698587221852172>]"], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 Allows you to set cooldowns (or \"ratelimits\") for commands\n limits user/channel/guild actions,", + "hash": "5dfb3c2f533878a15cf9764ffb921d1e", + "name": "cooldown", + "author": ["@trueharuu [<@504698587221852172>]"], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/cooldown.ts", + "example": "\n\n ```ts\n import { cooldown } from \"../plugins/cooldown\";\n import { commandModule } from \"@sern/handler\";\n export default commandModule({\n plugins: [cooldown.add( [ ['channel', '1/4'] ] )], // limit to 1 action every 4 seconds per channel\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": "96e4b5b562500b0bcdc442fbf130a555", + "name": "disable", + "author": [ + "@jacoobes [<@182326315813306368>]", + "@Peter-MJ-Parker [<@371759410009341952>]" + ], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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.0.0" + }, + { + "description": "\n\n This is dmOnly plugin, it allows commands to be run only in DMs.\n", + "hash": "844e68aa0c9147c98930b34a5d716a22", + "name": "dmOnly", + "author": ["@EvolutionX-10 [<@697795666373640213>]"], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 Generalized `filter` plugin. revised by jacoobes, all credit to original author.\n Perform declarative conditionals as plugins. ", + "hash": "ba85e67d23bbfacc337f82e9fade283c", + "name": "filter", + "author": ["@trueharuu [<@504698587221852172>]"], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/filter.ts", + "example": "\n\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 });", + "version": "2.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": "65ff8138fd20486d6eeff17cdb7b93cf", + "name": "nsfwOnly", + "author": ["@Benzo-Fury [<@762918086349029386>]"], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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.0" + }, + { + "description": "\n\n This is OwnerOnly plugin, it allows only bot owners to run the command, like eval.\n", + "hash": "5ffb76d3a2ecdb0516fa98a93dd1d15d", + "name": "ownerOnly", + "author": ["@EvolutionX-10 [<@697795666373640213>]"], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 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": "45fb62d9ffe908469ea58aabb550daf7", + "name": "permCheck", + "author": ["@Benzo-Fury [<@762918086349029386>]"], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 This is publish plugin, it allows you to publish your application commands using the discord.js library with ease.\n", + "hash": "3f76c395a51cccc9c66de9ea65d28b19", + "name": "publish", + "author": ["@EvolutionX-10 [<@697795666373640213>]"], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 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": "bad95c4cf2105d9f60363ddf16ab7b82", + "name": "requirePermission", + "author": [ + "@Benzo-Fury [<@762918086349029386>]", + "@needhamgary [<@342314924804014081>]" + ], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/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 Checks if a command is available in a specific server.\n", + "hash": "b1d78678451c260286a97de8f1cb9e07", + "name": "serverOnly", + "author": ["@Peter-MJ-Parker [<@371759410009341952>]"], + "link": "https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/TypeScript/serverOnly.ts", + "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" + } +]