From b2ee0996f16c13da3bdfe799c95a36f9edea5ef7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 28 Jan 2023 23:47:35 +0530 Subject: [PATCH] chore: Update JavaScript plugins (#69) chore: update JavaScript plugins Co-authored-by: EvolutionX-10 --- JavaScript/assertFields.js | 61 +++++++ JavaScript/buttonConfirmation.js | 117 ++++++------ JavaScript/channelType.js | 34 ++-- JavaScript/confirmation.js | 135 +++++++------- JavaScript/cooldown.js | 62 +++---- JavaScript/dmOnly.js | 27 ++- JavaScript/nsfwOnly.js | 59 +++--- JavaScript/ownerOnly.js | 18 +- JavaScript/permCheck.js | 37 ++-- JavaScript/publish.js | 269 +++++++++++++-------------- JavaScript/requirePermission.js | 132 +++++++------- JavaScript/serverOnly.js | 31 ++-- TypeScript/assertFields.ts | 53 +++--- TypeScript/buttonConfirmation.ts | 145 +++++++-------- TypeScript/channelType.ts | 37 ++-- TypeScript/confirmation.ts | 130 +++++++------- TypeScript/cooldown.ts | 7 +- TypeScript/dmOnly.ts | 19 +- TypeScript/nsfwOnly.ts | 61 +++---- TypeScript/ownerOnly.ts | 4 +- TypeScript/permCheck.ts | 9 +- TypeScript/publish.ts | 300 +++++++++++++++---------------- TypeScript/requirePermission.ts | 14 +- TypeScript/serverOnly.ts | 32 ++-- 24 files changed, 876 insertions(+), 917 deletions(-) create mode 100644 JavaScript/assertFields.js diff --git a/JavaScript/assertFields.js b/JavaScript/assertFields.js new file mode 100644 index 0000000..816cbe3 --- /dev/null +++ b/JavaScript/assertFields.js @@ -0,0 +1,61 @@ +//@ts-nocheck + +/** + * This plugin checks the fields of a ModalSubmitInteraction + * with regex or a custom callback + * + * @author @jacoobes [<@182326315813306368>] + * @version 1.0.0 + * @example + * ```ts + * export default commandModule({ + * type: CommandType.Modal, + * plugins: [ + * assertFields({ + * fields: { + * // check the modal field "mcUsernameInput" with the regex /a+b+c/ + * mcUsernameInput: /a+b+c+/ + * }, + * failure: (errors, interaction) => { + * interaction.reply(errors.join("\n")) + * } + * }), + * ], + * execute: ctx => { + * ctx.reply("nice!") + * } + * }) + * ``` + */ +import { CommandControlPlugin, controller } from "@sern/handler"; +export function assertFields(config) { + return CommandControlPlugin((modal) => { + const pairs = Object.entries(config.fields); + const errors = []; + + for (const [field, assertion] of pairs) { + // Keep in mind this doesn't check for typos! + // feel free to add more checks. + const input = modal.fields.getTextInputValue(field); + const resolvedAssertion = + assertion instanceof RegExp + ? (value) => assertion.test(value) + : assertion; + + if (!resolvedAssertion(input)) { + errors.push( + input + + " failed to pass assertion " + + resolvedAssertion.toString() + ); + } + } + + if (errors.length > 0) { + config.failure(errors, modal); + return controller.stop(); + } + + return controller.next(); + }); +} diff --git a/JavaScript/buttonConfirmation.js b/JavaScript/buttonConfirmation.js index 578664b..afd925e 100644 --- a/JavaScript/buttonConfirmation.js +++ b/JavaScript/buttonConfirmation.js @@ -1,4 +1,4 @@ -// @ts-nocheck +//@ts-nocheck /** * This is buttonConfirmation plugin, it runs confirmation prompt in the form of buttons. @@ -19,7 +19,7 @@ * }) * ``` */ -import { PluginType } from "@sern/handler"; +import { CommandControlPlugin, controller } from "@sern/handler"; import { ActionRowBuilder, ButtonBuilder, @@ -27,69 +27,60 @@ import { ComponentType, } from "discord.js"; export function confirmation(options) { - return { - type: PluginType.Event, - description: "Confirms", - - async execute([ctx], controller) { - options = { - content: "Do you want to proceed?", - denialMessage: "Cancelled", - labels: ["No", "Yes"], - time: 60_000, - wrongUserResponse: "Not for you!", - ...options, - }; - const buttons = options.labels.map((l, i) => { - return new ButtonBuilder() - .setCustomId(l) - .setLabel(l) - .setStyle( - i === 0 ? ButtonStyle.Danger : ButtonStyle.Success - ); - }); - const sent = await ctx.reply({ - content: options.content, - components: [new ActionRowBuilder().setComponents(buttons)], - }); - const collector = sent.createMessageComponentCollector({ - componentType: ComponentType.Button, - filter: (i) => i.user.id === ctx.user.id, - time: options.time, - }); - return new Promise((resolve) => { - collector.on("collect", async (i) => { - await i.update({ - components: [], - }); - collector.stop(); - - if (i.customId === options.labels[1]) { - resolve(controller.next()); - return; - } - - await i.editReply({ - content: options?.denialMessage, - }); - resolve(controller.stop()); + return CommandControlPlugin(async (ctx, args) => { + options = { + content: "Do you want to proceed?", + denialMessage: "Cancelled", + labels: ["No", "Yes"], + time: 60_000, + wrongUserResponse: "Not for you!", + ...options, + }; + const buttons = options.labels.map((l, i) => { + return new ButtonBuilder() + .setCustomId(l) + .setLabel(l) + .setStyle(i === 0 ? ButtonStyle.Danger : ButtonStyle.Success); + }); + const sent = await ctx.reply({ + content: options.content, + components: [new ActionRowBuilder().setComponents(buttons)], + }); + const collector = sent.createMessageComponentCollector({ + componentType: ComponentType.Button, + filter: (i) => i.user.id === ctx.user.id, + time: options.time, + }); + return new Promise((resolve) => { + collector.on("collect", async (i) => { + await i.update({ + components: [], }); - collector.on("end", async (c) => { - if (c.size) return; - buttons.forEach((b) => b.setDisabled()); - await sent.edit({ - components: [ - new ActionRowBuilder().setComponents(buttons), - ], - }); + collector.stop(); + + if (i.customId === options.labels[1]) { + resolve(controller.next()); + return; + } + + await i.editReply({ + content: options?.denialMessage, }); - collector.on("ignore", async (i) => { - await i.reply({ - content: options?.wrongUserResponse, - ephemeral: true, - }); + resolve(controller.stop()); + }); + collector.on("end", async (c) => { + if (c.size) return; + buttons.forEach((b) => b.setDisabled()); + await sent.edit({ + components: [new ActionRowBuilder().setComponents(buttons)], }); }); - }, - }; + collector.on("ignore", async (i) => { + await i.reply({ + content: options?.wrongUserResponse, + ephemeral: true, + }); + }); + }); + }); } diff --git a/JavaScript/channelType.js b/JavaScript/channelType.js index 08ad15e..0a8278e 100644 --- a/JavaScript/channelType.js +++ b/JavaScript/channelType.js @@ -19,29 +19,23 @@ * ``` */ import { ChannelType } from "discord.js"; -import { PluginType } from "@sern/handler"; +import { CommandControlPlugin, controller } from "@sern/handler"; export function channelType(channelType, onFail) { - return { - type: PluginType.Event, - description: "Checks the channel type.", + return CommandControlPlugin(async (ctx, args) => { + let channel = ctx.channel?.type; //for some reason the dm channel type was returning undefined at some points - async execute(event, controller) { - const [ctx] = event; - let channel = ctx.channel?.type; //for some reason the dm channel type was returning undefined at some points + if (channel === undefined) { + channel = ChannelType.DM; + } - if (channel === undefined) { - channel = ChannelType.DM; - } + if (channelType.includes(channel)) { + return controller.next(); + } - if (channelType.includes(channel)) { - return controller.next(); - } + if (onFail) { + await ctx.reply(onFail); + } - if (onFail) { - await ctx.reply(onFail); - } - - return controller.stop(); - }, - }; + return controller.stop(); + }); } diff --git a/JavaScript/confirmation.js b/JavaScript/confirmation.js index a63c3d0..56cf0a3 100644 --- a/JavaScript/confirmation.js +++ b/JavaScript/confirmation.js @@ -15,14 +15,14 @@ * type : CommandType.Both * plugins: [confirmation()], * execute: (ctx, args) => { - * ctx.reply('hola'); + * ctx.interaction.followUp('Hello welcome to the secret club') * } * }) * ``` */ -import { PluginType } from "@sern/handler"; +import { CommandControlPlugin, controller } from "@sern/handler"; const defaultOptions = { - timeout: 1000, + timeout: 5000, message: "Are you sure you want to proceed?", onTimeout: "confirmation timed out", onCancel: "confirmation cancelled", @@ -38,83 +38,78 @@ const defaultOptions = { }; export function confirmation(raw = {}) { const options = Object.assign({}, defaultOptions, raw); - return { - name: "confirmation", - type: PluginType.Event, + return CommandControlPlugin(async (context, _) => { + if (typeof options.message === "function") { + options.message = await options.message(context); + } - async execute([context], controller) { - if (typeof options.message === "function") { - options.message = await options.message(context); + const response = await context.reply(await options.message); + let { yes, no } = options.emojis; + + if (typeof yes === "function") { + yes = await yes(context); + } + + if (typeof no === "function") { + no = await no(context); + } + + await response.react(await yes); + await response.react(await no); + + function filter(reaction, user) { + return ( + ([yes, no].includes(reaction.emoji.name) || + [yes, no].includes(reaction.emoji.identifier)) && + user.id === context.user.id + ); + } + + const recieved = await response.awaitReactions({ + filter, + max: 1, + time: options.timeout, + }); + + if (recieved.size === 0) { + if (typeof options.onTimeout === "function") { + await options.onTimeout(context, response); + } else { + await response.edit(await options.onTimeout); + await response.reactions.removeAll(); } - const response = await context.reply(await options.message); - let { yes, no } = options.emojis; + return controller.stop(); + } - if (typeof yes === "function") { - yes = await yes(context); - } + const reaction = recieved.first(); - if (typeof no === "function") { - no = await no(context); - } + if (!reaction) { + return controller.stop(); + } - await response.react(await yes); - await response.react(await no); - - function filter(reaction, user) { - return ( - ([yes, no].includes(reaction.emoji.name) || - [yes, no].includes(reaction.emoji.identifier)) && - user.id === context.user.id - ); - } - - const recieved = await response.awaitReactions({ - filter, - max: 1, - time: options.timeout, - }); - - if (recieved.size === 0) { - if (typeof options.onTimeout === "function") { - await options.onTimeout(context, response); + switch (reaction.emoji.name) { + case await yes: + if (typeof options.onConfirm === "function") { + await options.onConfirm(context, response); } else { - await response.edit(await options.onTimeout); + await response.edit(await options.onConfirm); + await response.reactions.removeAll(); + } + + return controller.next(); + + case await no: + if (typeof options.onCancel === "function") { + await options.onCancel(context, response); + } else { + await response.edit(await options.onCancel); await response.reactions.removeAll(); } return controller.stop(); - } + } - const reaction = recieved.first(); - - if (!reaction) { - return controller.stop(); - } - - switch (reaction.emoji.name) { - case await yes: - if (typeof options.onConfirm === "function") { - await options.onConfirm(context, response); - } else { - await response.edit(await options.onConfirm); - await response.reactions.removeAll(); - } - - return controller.next(); - - case await no: - if (typeof options.onCancel === "function") { - await options.onCancel(context, response); - } else { - await response.edit(await options.onCancel); - await response.reactions.removeAll(); - } - - return controller.stop(); - } - - return controller.next(); - }, - }; + return controller.next(); + }); } diff --git a/JavaScript/cooldown.js b/JavaScript/cooldown.js index 4647b22..f543b60 100644 --- a/JavaScript/cooldown.js +++ b/JavaScript/cooldown.js @@ -2,7 +2,7 @@ /** * Allows you to set cooldowns (or "ratelimits") for commands - * + * limits user/channel/guild actions, * @author @trueharuu [<@504698587221852172>] * @version 1.0.0 * @example @@ -17,7 +17,7 @@ * }) * ``` */ -import { PluginType } from "@sern/handler"; +import { CommandControlPlugin, controller } from "@sern/handler"; import { GuildMember } from "discord.js"; /** * actions/seconds @@ -89,41 +89,35 @@ function add(items, message) { if (!Array.isArray(c)) return c; return parseCooldown(c[0], c[1]); }); - return { - name: "cooldown", - description: "limits user/channel/guild actions", - type: PluginType.Event, + return CommandControlPlugin(async (context, args) => { + for (const { location, actions, seconds } of raw) { + const id = getPropertyForLocation(context, location); + const cooldown = map.get(id); - async execute([context], controller) { - for (const { location, actions, seconds } of raw) { - const id = getPropertyForLocation(context, location); - const cooldown = map.get(id); - - if (!cooldown) { - map.set(id, 1, seconds * 1000); - continue; - } - - if (cooldown >= actions) { - if (message) { - await message({ - location, - actions: cooldown, - maxActions: actions, - seconds, - context, - }); - } - - return controller.stop(); - } - - map.set(id, cooldown + 1, seconds * 1000); + if (!cooldown) { + map.set(id, 1, seconds * 1000); + continue; } - return controller.next(); - }, - }; + if (cooldown >= actions) { + if (message) { + await message({ + location, + actions: cooldown, + maxActions: actions, + seconds, + context, + }); + } + + return controller.stop(); + } + + map.set(id, cooldown + 1, seconds * 1000); + } + + return controller.next(); + }); } const locations = { diff --git a/JavaScript/dmOnly.js b/JavaScript/dmOnly.js index 293c1e4..5a2fe2f 100644 --- a/JavaScript/dmOnly.js +++ b/JavaScript/dmOnly.js @@ -17,22 +17,17 @@ * }) * ``` */ -import { PluginType } from "@sern/handler"; +import { CommandControlPlugin, controller } from "@sern/handler"; export function dmOnly(content, ephemeral) { - return { - type: PluginType.Event, - description: "Allows commands to be run in DM only", + // For discord.js you should have the Partials.Channel and DirectMessages intent enabled. + return CommandControlPlugin(async (ctx, _) => { + if (ctx.channel?.isDMBased()) return controller.next(); + if (content) + await ctx.reply({ + content, + ephemeral, + }); // Change this if you want or remove it for silent deny - async execute(event, controller) { - const [ctx] = event; - if (ctx.channel?.isDMBased()) return controller.next(); - if (content) - await ctx.reply({ - content, - ephemeral, - }); // Change this if you want or remove it for silent deny - - return controller.stop(); - }, - }; + return controller.stop(); + }); } diff --git a/JavaScript/nsfwOnly.js b/JavaScript/nsfwOnly.js index 72fa40e..138d371 100644 --- a/JavaScript/nsfwOnly.js +++ b/JavaScript/nsfwOnly.js @@ -18,7 +18,7 @@ * ``` */ import { ChannelType } from "discord.js"; -import { PluginType } from "@sern/handler"; +import { CommandControlPlugin, controller } from "@sern/handler"; function isGuildText(channel) { return ( @@ -28,39 +28,32 @@ function isGuildText(channel) { } export function nsfwOnly(onFail, ephemeral) { - return { - type: PluginType.Event, - description: "Checks if the channel is nsfw or not.", + return CommandControlPlugin(async (ctx, _) => { + if (ctx.guild === null) { + await ctx.reply({ + content: onFail, + ephemeral, + }); + return controller.stop(); + } //channel is thread (not supported by nsfw) - async execute(event, controller) { - const [ctx] = event; //checking if command was executed in dms + if (isGuildText(ctx.channel) == true) { + await ctx.reply({ + content: onFail, + ephemeral, + }); + return controller.stop(); + } - if (ctx.guild === null) { - await ctx.reply({ - content: onFail, - ephemeral, - }); - return controller.stop(); - } //channel is thread (not supported by nsfw) + if (!ctx.channel.nsfw) { + //channel is not nsfw + await ctx.reply({ + content: onFail, + ephemeral, + }); + return controller.stop(); + } //continues to command if nsfw - if (isGuildText(ctx.channel) == true) { - await ctx.reply({ - content: onFail, - ephemeral, - }); - return controller.stop(); - } - - if (!ctx.channel.nsfw) { - //channel is not nsfw - await ctx.reply({ - content: onFail, - ephemeral, - }); - return controller.stop(); - } //continues to command if nsfw - - return controller.next(); - }, - }; + return controller.next(); + }); } diff --git a/JavaScript/ownerOnly.js b/JavaScript/ownerOnly.js index f00cc7a..158f151 100644 --- a/JavaScript/ownerOnly.js +++ b/JavaScript/ownerOnly.js @@ -17,20 +17,14 @@ * }) * ``` */ -import { PluginType } from "@sern/handler"; +import { CommandControlPlugin, controller } from "@sern/handler"; const ownerIDs = ["697795666373640213"]; //! Fill your ID export function ownerOnly() { - return { - type: PluginType.Event, - description: "Allows only bot owner to run command", + return CommandControlPlugin((ctx, args) => { + if (ownerIDs.includes(ctx.user.id)) return controller.next(); //* If you want to reply when the command fails due to user not being owner, you can use following + // await ctx.reply("Only owner can run it!!!"); - async execute(event, controller) { - const [ctx] = event; - if (ownerIDs.includes(ctx.user.id)) return controller.next(); //* If you want to reply when the command fails due to user not being owner, you can use following - // await ctx.reply("Only owner can run it!!!"); - - return controller.stop(); //! Important: It stops the execution of command! - }, - }; + return controller.stop(); //! Important: It stops the execution of command! + }); } diff --git a/JavaScript/permCheck.js b/JavaScript/permCheck.js index 18ca416..b57ee21 100644 --- a/JavaScript/permCheck.js +++ b/JavaScript/permCheck.js @@ -17,30 +17,23 @@ * }) * ``` */ -import { PluginType } from "@sern/handler"; +import { CommandControlPlugin, controller } from "@sern/handler"; export function permCheck(perm, response) { - return { - type: PluginType.Event, - description: "Checks for specified perm", + 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 - async execute(event, controller) { - const [ctx] = event; + return controller.stop(); + } - if (ctx.guild === null) { - 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 + if (!ctx.member.permissions.has(perm)) { + await ctx.reply(response); + return controller.stop(); + } - return controller.stop(); - } - - if (!ctx.member.permissions.has(perm)) { - await ctx.reply(response); - return controller.stop(); - } - - return controller.next(); - }, - }; + return controller.next(); + }); } diff --git a/JavaScript/publish.js b/JavaScript/publish.js index 1a32776..19102fe 100644 --- a/JavaScript/publish.js +++ b/JavaScript/publish.js @@ -18,156 +18,135 @@ * }) * ``` */ -import { CommandType, PluginType } from "@sern/handler"; +import { CommandInitPlugin, CommandType, controller } from "@sern/handler"; import { ApplicationCommandType } from "discord.js"; -/** - * This is the dependency getter that is created from Sern.makeDependencies. - * import it here so that this plugin has access to your bot's dependencies - */ - import { useContainer } from "../index.js"; -export function publish(options) { - return { - type: PluginType.Command, - description: "Manage Application Commands", - name: "slash-auto-publish", - - async execute({ mod: module }, controller) { - // Users need to provide their own useContainer function. - const [client] = useContainer("@sern/client"); - const defaultOptions = { - guildIds: [], - dmPermission: undefined, - defaultMemberPermissions: null, - }; - options = { ...defaultOptions, ...options }; - let { defaultMemberPermissions, dmPermission, guildIds } = options; - - function c(e) { - console.error("publish command didnt work for", module.name); - console.error(e); - } - - const log = - (...message) => - () => - console.log(...message); - - const logged = (...message) => log(message); - /** - * a local function that returns either one value or the other, - * depending on {t}'s CommandType. If the commandtype of - * this module is CommandType.Both or CommandType.Text or CommandType.Slash, - * return 'is', else return 'els' - * @param t - * @returns S | T - */ - - const appCmd = (t) => { - return (is, els) => ((t & CommandType.Both) !== 0 ? is : els); - }; - - const curAppType = CommandTypeRaw[module.type]; - - const createCommandData = () => { - const cmd = appCmd(module.type); - return { - name: module.name, - type: curAppType, - description: cmd(module.description, ""), - options: cmd(optionsTransformer(module.options ?? []), []), - defaultMemberPermissions, - dmPermission, - }; - }; - - try { - const commandData = createCommandData(); - - if (!guildIds.length) { - const cmd = ( - await client.application.commands.fetch() - ).find( - (c) => c.name === module.name && c.type === curAppType - ); - - if (cmd) { - if (!cmd.equals(commandData, true)) { - logged( - `Found differences in global command ${module.name}` - ); - cmd.edit(commandData).then( - log( - `${module.name} updated with new data successfully!` - ) - ); - } - - return controller.next(); - } - - client.application.commands - .create(commandData) - .then(log("Command created", module.name)) - .catch(c); - return controller.next(); - } - - for (const id of guildIds) { - 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 - ); - - if (guildCmd) { - if (!guildCmd.equals(commandData, true)) { - logged( - `Found differences in command ${module.name}` - ); - guildCmd - .edit(commandData) - .then( - log( - `${module.name} updated with new data successfully!` - ) - ) - .catch(c); - continue; - } - - continue; - } - - guild.commands - .create(commandData) - .then( - log( - "Guild Command created", - module.name, - guild.name - ) - ) - .catch(c); - } - - return controller.next(); - } catch (e) { - logged("Command did not register" + module.name); - logged(e); - return controller.stop(); - } - }, - }; -} -export function optionsTransformer(ops) { - return ops.map((el) => - el.autocomplete ? (({ command, ...el }) => el)(el) : el - ); -} export const CommandTypeRaw = { [CommandType.Both]: ApplicationCommandType.ChatInput, [CommandType.CtxUser]: ApplicationCommandType.Message, [CommandType.CtxMsg]: ApplicationCommandType.User, [CommandType.Slash]: ApplicationCommandType.ChatInput, }; +export function publish(options) { + return CommandInitPlugin(async ({ module }) => { + // Users need to provide their own useContainer function. + const [client] = useContainer("@sern/client"); + const defaultOptions = { + guildIds: [], + dmPermission: undefined, + defaultMemberPermissions: null, + }; + options = { ...defaultOptions, ...options }; + let { defaultMemberPermissions, dmPermission, guildIds } = options; + + function c(e) { + console.error("publish command didnt work for", module.name); + console.error(e); + } + + const log = + (...message) => + () => + console.log(...message); + + const logged = (...message) => log(message); + /** + * a local function that returns either one value or the other, + * depending on {t}'s CommandType. If the commandtype of + * this module is CommandType.Both or CommandType.Text or CommandType.Slash, + * return 'is', else return 'els' + * @param t + * @returns S | T + */ + + const appCmd = (t) => { + return (is, els) => ((t & CommandType.Both) !== 0 ? is : els); + }; + + const curAppType = CommandTypeRaw[module.type]; + + const createCommandData = () => { + const cmd = appCmd(module.type); + return { + name: module.name, + type: curAppType, + description: cmd(module.description, ""), + options: cmd(optionsTransformer(module.options ?? []), []), + defaultMemberPermissions, + dmPermission, + }; + }; + + try { + const commandData = createCommandData(); + + if (!guildIds.length) { + const cmd = (await client.application.commands.fetch()).find( + (c) => c.name === module.name && c.type === curAppType + ); + + if (cmd) { + if (!cmd.equals(commandData, true)) { + logged( + `Found differences in global command ${module.name}` + ); + cmd.edit(commandData).then( + log( + `${module.name} updated with new data successfully!` + ) + ); + } + + return controller.next(); + } + + client.application.commands + .create(commandData) + .then(log("Command created", module.name)) + .catch(c); + return controller.next(); + } + + for (const id of guildIds) { + 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 + ); + + if (guildCmd) { + if (!guildCmd.equals(commandData, true)) { + logged(`Found differences in command ${module.name}`); + guildCmd + .edit(commandData) + .then( + log( + `${module.name} updated with new data successfully!` + ) + ) + .catch(c); + continue; + } + + continue; + } + + guild.commands + .create(commandData) + .then(log("Guild Command created", module.name, guild.name)) + .catch(c); + } + + return controller.next(); + } catch (e) { + logged("Command did not register" + module.name); + logged(e); + return controller.stop(); + } + }); +} +export function optionsTransformer(ops) { + return ops.map((el) => + el.autocomplete ? (({ command, ...el }) => el)(el) : el + ); +} diff --git a/JavaScript/requirePermission.js b/JavaScript/requirePermission.js index 25686ba..51d0ff0 100644 --- a/JavaScript/requirePermission.js +++ b/JavaScript/requirePermission.js @@ -1,3 +1,5 @@ +// @ts-nocheck + /** * 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). * @@ -16,7 +18,7 @@ * }) * ``` */ -import { PluginType } from "@sern/handler"; +import { CommandControlPlugin, controller } from "@sern/handler"; function payload(resp) { return { @@ -29,78 +31,66 @@ function payload(resp) { } export function requirePermission(target, perm, response) { - return { - type: PluginType.Event, - description: "Checks bot/user perms", + 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)" + ); //delete this line if you dont want to be notified when a command is used outside of a guild/server - async execute(event, controller) { - const [ctx] = event; + return controller.stop(); + } - 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)" - ); //delete this line if you dont want to be notified when a command is used outside of a guild/server + const bot = await ctx.guild.members.fetchMe({ + cache: false, + }); + const memm = ctx.member; - return controller.stop(); - } - - const bot = await ctx.guild.members.fetchMe({ - cache: false, - }); - const memm = ctx.member; - - switch (target) { - //*********************************************************************************************************************// - case "bot": - 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(); - } - - return controller.next(); - //*********************************************************************************************************************// - - case "user": - 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(); - } - - return controller.next(); - //*********************************************************************************************************************// - - case "both": - if ( - !bot.permissions.has(perm) || - !memm.permissions.has(perm) - ) { - if (!response) - response = `Please ensure <@${bot.user.id}> and <@${ - memm.user.id - }> both have \`${perm.join(", ")}\` permission(s).`; - await ctx.reply(payload(response)); - return controller.stop(); - } - - return controller.next(); - //*********************************************************************************************************************// - - default: - console.warn( - "Perm Check >>> You didn't specify user or bot." - ); - ctx.reply(payload("User or Bot was not specified.")); + switch (target) { + //*********************************************************************************************************************// + case "bot": + 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(); - } - }, - }; + } + + return controller.next(); + //*********************************************************************************************************************// + + case "user": + 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(); + } + + return controller.next(); + //*********************************************************************************************************************// + + case "both": + if (!bot.permissions.has(perm) || !memm.permissions.has(perm)) { + if (!response) + response = `Please ensure <@${bot.user.id}> and <@${ + memm.user.id + }> both have \`${perm.join(", ")}\` permission(s).`; + await ctx.reply(payload(response)); + return controller.stop(); + } + + return controller.next(); + //*********************************************************************************************************************// + + default: + console.warn("Perm Check >>> You didn't specify user or bot."); + ctx.reply(payload("User or Bot was not specified.")); + return controller.stop(); + } + }); } diff --git a/JavaScript/serverOnly.js b/JavaScript/serverOnly.js index dc4150e..976a614 100644 --- a/JavaScript/serverOnly.js +++ b/JavaScript/serverOnly.js @@ -19,26 +19,25 @@ * }); * ``` */ -import { PluginType } from "@sern/handler"; +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." ) { - return { - type: PluginType.Event, - description: "Checks if a command is available in a specific server.", + return CommandControlPlugin(async (ctx, _) => { + if (ctx.guildId == null) { + return controller.stop(); + } - async execute([ctx, args], controller) { - if (!guildId.includes(ctx.guildId)) { - await ctx.reply(failMessage).then(async (m) => { - setTimeout(async () => { - await m.delete(); - }, 3000); - }); - return controller.stop(); - } + if (!guildId.includes(ctx.guildId)) { + ctx.reply(failMessage).then(async (m) => { + setTimeout(async () => { + await m.delete(); + }, 3000); + }); + return controller.stop(); + } - return controller.next(); - }, - }; + return controller.next(); + }); } diff --git a/TypeScript/assertFields.ts b/TypeScript/assertFields.ts index 67ebfe4..423cbb6 100644 --- a/TypeScript/assertFields.ts +++ b/TypeScript/assertFields.ts @@ -29,30 +29,35 @@ import { CommandControlPlugin, CommandType, controller } from "@sern/handler"; import type { ModalSubmitInteraction } from "discord.js"; -type Assertion = - | RegExp - | ((value : string) => boolean); +type Assertion = RegExp | ((value: string) => boolean); export function assertFields(config: { - fields: Record, - failure: (errors: string[], interaction: ModalSubmitInteraction) => any + fields: Record; + failure: (errors: string[], interaction: ModalSubmitInteraction) => any; }) { - return CommandControlPlugin(modal => { - const pairs = Object.entries(config.fields); - const errors = []; - for(const [ field, assertion ] of pairs) { - // Keep in mind this doesn't check for typos! - // feel free to add more checks. - const input = modal.fields.getTextInputValue(field) - const resolvedAssertion = assertion instanceof RegExp ? (value: string) => assertion.test(value) : assertion; - if(!resolvedAssertion(input)) { - errors.push(input + " failed to pass assertion " + resolvedAssertion.toString() ) - } - } - if(errors.length > 0) { - config.failure(errors, modal); - return controller.stop(); - } - return controller.next(); - }) -} \ No newline at end of file + return CommandControlPlugin((modal) => { + const pairs = Object.entries(config.fields); + const errors = []; + for (const [field, assertion] of pairs) { + // Keep in mind this doesn't check for typos! + // feel free to add more checks. + const input = modal.fields.getTextInputValue(field); + const resolvedAssertion = + assertion instanceof RegExp + ? (value: string) => assertion.test(value) + : assertion; + if (!resolvedAssertion(input)) { + errors.push( + input + + " failed to pass assertion " + + resolvedAssertion.toString() + ); + } + } + if (errors.length > 0) { + config.failure(errors, modal); + return controller.stop(); + } + return controller.next(); + }); +} diff --git a/TypeScript/buttonConfirmation.ts b/TypeScript/buttonConfirmation.ts index 1c44158..d95227f 100644 --- a/TypeScript/buttonConfirmation.ts +++ b/TypeScript/buttonConfirmation.ts @@ -19,91 +19,84 @@ * ``` */ -import {CommandControlPlugin, CommandType, controller} from "@sern/handler"; +import { CommandControlPlugin, CommandType, controller } from "@sern/handler"; import { - ActionRowBuilder, - ButtonBuilder, - ButtonStyle, - ComponentType, + ActionRowBuilder, + ButtonBuilder, + ButtonStyle, + ComponentType, } from "discord.js"; -export function confirmation( - options?: Partial -) { - return CommandControlPlugin(async (ctx, args) => { - options = { - content: "Do you want to proceed?", - denialMessage: "Cancelled", - labels: ["No", "Yes"], - time: 60_000, - wrongUserResponse: "Not for you!", - ...options, - }; +export function confirmation(options?: Partial) { + return CommandControlPlugin(async (ctx, args) => { + options = { + content: "Do you want to proceed?", + denialMessage: "Cancelled", + labels: ["No", "Yes"], + time: 60_000, + wrongUserResponse: "Not for you!", + ...options, + }; - const buttons = options.labels!.map((l, i) => { - return new ButtonBuilder() - .setCustomId(l) - .setLabel(l) - .setStyle( - i === 0 ? ButtonStyle.Danger : ButtonStyle.Success - ); - }); - const sent = await ctx.reply({ - content: options.content, - components: [ - new ActionRowBuilder().setComponents( - buttons - ), - ], - }); + const buttons = options.labels!.map((l, i) => { + return new ButtonBuilder() + .setCustomId(l) + .setLabel(l) + .setStyle(i === 0 ? ButtonStyle.Danger : ButtonStyle.Success); + }); + const sent = await ctx.reply({ + content: options.content, + components: [ + new ActionRowBuilder().setComponents(buttons), + ], + }); - const collector = sent.createMessageComponentCollector({ - componentType: ComponentType.Button, - filter: (i) => i.user.id === ctx.user.id, - time: options.time, - }); + const collector = sent.createMessageComponentCollector({ + componentType: ComponentType.Button, + filter: (i) => i.user.id === ctx.user.id, + time: options.time, + }); - return new Promise((resolve) => { - collector.on("collect", async (i) => { - await i.update({ components: [] }); - collector.stop(); - if (i.customId === options!.labels![1]) { - resolve(controller.next()); - return; - } - await i.editReply({ - content: options?.denialMessage, - }); - resolve(controller.stop()); - }); + return new Promise((resolve) => { + collector.on("collect", async (i) => { + await i.update({ components: [] }); + collector.stop(); + if (i.customId === options!.labels![1]) { + resolve(controller.next()); + return; + } + await i.editReply({ + content: options?.denialMessage, + }); + resolve(controller.stop()); + }); - collector.on("end", async (c) => { - if (c.size) return; - buttons.forEach((b) => b.setDisabled()); - await sent.edit({ - components: [ - new ActionRowBuilder().setComponents( - buttons - ), - ], - }); - }); + collector.on("end", async (c) => { + if (c.size) return; + buttons.forEach((b) => b.setDisabled()); + await sent.edit({ + components: [ + new ActionRowBuilder().setComponents( + buttons + ), + ], + }); + }); - collector.on("ignore", async (i) => { - await i.reply({ - content: options?.wrongUserResponse, - ephemeral: true, - }); - }); - }); - }); + collector.on("ignore", async (i) => { + await i.reply({ + content: options?.wrongUserResponse, + ephemeral: true, + }); + }); + }); + }); } interface ConfirmationOptions { - content: string; - denialMessage: string; - time: number; - labels: [string, string]; - wrongUserResponse: string; + content: string; + denialMessage: string; + time: number; + labels: [string, string]; + wrongUserResponse: string; } - diff --git a/TypeScript/channelType.ts b/TypeScript/channelType.ts index 8b960bf..c83fd08 100644 --- a/TypeScript/channelType.ts +++ b/TypeScript/channelType.ts @@ -18,23 +18,20 @@ * ``` */ import { ChannelType } from "discord.js"; -import {CommandControlPlugin, CommandType, controller } from "@sern/handler"; -export function channelType( - channelType: ChannelType[], - onFail?: string -){ - return CommandControlPlugin(async (ctx, args) => { - let channel = ctx.channel?.type; - //for some reason the dm channel type was returning undefined at some points - if (channel === undefined) { - channel = ChannelType.DM; - } - if (channelType.includes(channel)) { - return controller.next(); - } - if (onFail) { - await ctx.reply(onFail); - } - return controller.stop(); - }) -} \ No newline at end of file +import { CommandControlPlugin, CommandType, controller } from "@sern/handler"; +export function channelType(channelType: ChannelType[], onFail?: string) { + return CommandControlPlugin(async (ctx, args) => { + let channel = ctx.channel?.type; + //for some reason the dm channel type was returning undefined at some points + if (channel === undefined) { + channel = ChannelType.DM; + } + if (channelType.includes(channel)) { + return controller.next(); + } + if (onFail) { + await ctx.reply(onFail); + } + return controller.stop(); + }); +} diff --git a/TypeScript/confirmation.ts b/TypeScript/confirmation.ts index 3b3a8fa..d5e75f8 100644 --- a/TypeScript/confirmation.ts +++ b/TypeScript/confirmation.ts @@ -20,7 +20,12 @@ * ``` */ -import {CommandControlPlugin, CommandType, Context, controller } from "@sern/handler"; +import { + CommandControlPlugin, + CommandType, + Context, + controller, +} from "@sern/handler"; import type { Awaitable, Message, MessageReaction, User } from "discord.js"; type Callback = Awaitable | ((context: Context) => Awaitable); @@ -58,76 +63,73 @@ const defaultOptions: ConfirmationOptions = { }, }; -export function confirmation( - raw: Partial = {} -) { +export function confirmation(raw: Partial = {}) { const options: ConfirmationOptions = Object.assign({}, defaultOptions, raw); return CommandControlPlugin(async (context, _) => { - if (typeof options.message === "function") { - options.message = await options.message(context); + if (typeof options.message === "function") { + options.message = await options.message(context); + } + + const response = await context.reply(await options.message); + let { yes, no } = options.emojis; + if (typeof yes === "function") { + yes = await yes(context); + } + + if (typeof no === "function") { + no = await no(context); + } + + await response.react(await yes); + await response.react(await no); + + function filter(reaction: MessageReaction, user: User) { + return ( + ([yes, no].includes(reaction.emoji.name!) || + [yes, no].includes(reaction.emoji.identifier)) && + user.id === context.user.id + ); + } + + const recieved = await response.awaitReactions({ + filter, + max: 1, + time: options.timeout, + }); + if (recieved.size === 0) { + if (typeof options.onTimeout === "function") { + await options.onTimeout(context, response); + } else { + await response.edit(await options.onTimeout); + await response.reactions.removeAll(); } + return controller.stop(); + } + const reaction = recieved.first(); + if (!reaction) { + return controller.stop(); + } - const response = await context.reply(await options.message); - let {yes, no} = options.emojis; - if (typeof yes === "function") { - yes = await yes(context); - } - - if (typeof no === "function") { - no = await no(context); - } - - await response.react(await yes); - await response.react(await no); - - function filter(reaction: MessageReaction, user: User) { - return ( - ([yes, no].includes(reaction.emoji.name!) || - [yes, no].includes(reaction.emoji.identifier)) && - user.id === context.user.id - ); - } - - const recieved = await response.awaitReactions({ - filter, - max: 1, - time: options.timeout, - }); - if (recieved.size === 0) { - if (typeof options.onTimeout === "function") { - await options.onTimeout(context, response); + switch (reaction.emoji.name) { + case await yes: + if (typeof options.onConfirm === "function") { + await options.onConfirm(context, response); } else { - await response.edit(await options.onTimeout); + await response.edit(await options.onConfirm); await response.reactions.removeAll(); } + + return controller.next(); + case await no: + if (typeof options.onCancel === "function") { + await options.onCancel(context, response); + } else { + await response.edit(await options.onCancel); + await response.reactions.removeAll(); + } + return controller.stop(); - } - const reaction = recieved.first(); - if (!reaction) { - return controller.stop(); - } - - switch (reaction.emoji.name) { - case await yes: - if (typeof options.onConfirm === "function") { - await options.onConfirm(context, response); - } else { - await response.edit(await options.onConfirm); - await response.reactions.removeAll(); - } - - return controller.next(); - case await no: - if (typeof options.onCancel === "function") { - await options.onCancel(context, response); - } else { - await response.edit(await options.onCancel); - await response.reactions.removeAll(); - } - - return controller.stop(); - } - return controller.next() } - ) + return controller.next(); + }); } diff --git a/TypeScript/cooldown.ts b/TypeScript/cooldown.ts index c1412e7..5ff45d8 100644 --- a/TypeScript/cooldown.ts +++ b/TypeScript/cooldown.ts @@ -17,7 +17,12 @@ * ``` */ -import {CommandControlPlugin, CommandType, Context, controller } from "@sern/handler"; +import { + CommandControlPlugin, + CommandType, + Context, + controller, +} from "@sern/handler"; import { GuildMember } from "discord.js"; /** * actions/seconds diff --git a/TypeScript/dmOnly.ts b/TypeScript/dmOnly.ts index a01fc64..a4e5512 100644 --- a/TypeScript/dmOnly.ts +++ b/TypeScript/dmOnly.ts @@ -16,16 +16,13 @@ * }) * ``` */ -import {CommandControlPlugin, CommandType, controller } from "@sern/handler"; -export function dmOnly( - content?: string, - ephemeral?: boolean -) { - // For discord.js you should have the Partials.Channel and DirectMessages intent enabled. - return CommandControlPlugin(async (ctx, _) => { - if (ctx.channel?.isDMBased()) return controller.next(); +import { CommandControlPlugin, CommandType, controller } from "@sern/handler"; +export function dmOnly(content?: string, ephemeral?: boolean) { + // For discord.js you should have the Partials.Channel and DirectMessages intent enabled. + return CommandControlPlugin(async (ctx, _) => { + if (ctx.channel?.isDMBased()) return controller.next(); - if (content) await ctx.reply({ content, ephemeral }); // Change this if you want or remove it for silent deny - return controller.stop(); - }) + if (content) await ctx.reply({ content, ephemeral }); // Change this if you want or remove it for silent deny + return controller.stop(); + }); } diff --git a/TypeScript/nsfwOnly.ts b/TypeScript/nsfwOnly.ts index 8f1d23e..330f00c 100644 --- a/TypeScript/nsfwOnly.ts +++ b/TypeScript/nsfwOnly.ts @@ -17,40 +17,37 @@ * ``` */ import { - ChannelType, - GuildTextBasedChannel, - TextBasedChannel, - TextChannel, + ChannelType, + GuildTextBasedChannel, + TextBasedChannel, + TextChannel, } from "discord.js"; -import {CommandControlPlugin, CommandType, controller } from "@sern/handler"; +import { CommandControlPlugin, CommandType, controller } from "@sern/handler"; function isGuildText( - channel: TextBasedChannel | null + channel: TextBasedChannel | null ): channel is GuildTextBasedChannel { - return ( - channel?.type == ChannelType.GuildPublicThread || - channel?.type == ChannelType.GuildPrivateThread - ); + return ( + channel?.type == ChannelType.GuildPublicThread || + channel?.type == ChannelType.GuildPrivateThread + ); } -export function nsfwOnly( - onFail: string, - ephemeral: boolean -) { - return CommandControlPlugin(async (ctx, _) => { - if (ctx.guild === null) { - await ctx.reply({ content: onFail, ephemeral }); - return controller.stop(); - } - //channel is thread (not supported by nsfw) - if (isGuildText(ctx.channel) == true) { - await ctx.reply({ content: onFail, ephemeral }); - return controller.stop(); - } - if (!(ctx.channel! as TextChannel).nsfw) { - //channel is not nsfw - await ctx.reply({ content: onFail, ephemeral }); - return controller.stop(); - } - //continues to command if nsfw - return controller.next(); - }); +export function nsfwOnly(onFail: string, ephemeral: boolean) { + return CommandControlPlugin(async (ctx, _) => { + if (ctx.guild === null) { + await ctx.reply({ content: onFail, ephemeral }); + return controller.stop(); + } + //channel is thread (not supported by nsfw) + if (isGuildText(ctx.channel) == true) { + await ctx.reply({ content: onFail, ephemeral }); + return controller.stop(); + } + if (!(ctx.channel! as TextChannel).nsfw) { + //channel is not nsfw + await ctx.reply({ content: onFail, ephemeral }); + return controller.stop(); + } + //continues to command if nsfw + return controller.next(); + }); } diff --git a/TypeScript/ownerOnly.ts b/TypeScript/ownerOnly.ts index 136bf60..2be12e8 100644 --- a/TypeScript/ownerOnly.ts +++ b/TypeScript/ownerOnly.ts @@ -20,10 +20,10 @@ import { CommandType, CommandControlPlugin, controller } from "@sern/handler"; const ownerIDs = ["697795666373640213"]; //! Fill your ID export function ownerOnly() { - return CommandControlPlugin((ctx,args) => { + return CommandControlPlugin((ctx, args) => { if (ownerIDs.includes(ctx.user.id)) return controller.next(); //* If you want to reply when the command fails due to user not being owner, you can use following // await ctx.reply("Only owner can run it!!!"); return controller.stop(); //! Important: It stops the execution of command! - }) + }); } diff --git a/TypeScript/permCheck.ts b/TypeScript/permCheck.ts index 3a86bac..d8ceac7 100644 --- a/TypeScript/permCheck.ts +++ b/TypeScript/permCheck.ts @@ -18,11 +18,8 @@ */ import type { GuildMember, PermissionResolvable } from "discord.js"; -import {CommandControlPlugin, CommandType, controller } from "@sern/handler"; -export function permCheck( - perm: PermissionResolvable, - response: string -) { +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"); @@ -36,5 +33,5 @@ export function permCheck( return controller.stop(); } return controller.next(); - }) + }); } diff --git a/TypeScript/publish.ts b/TypeScript/publish.ts index e8f024f..5f647d3 100644 --- a/TypeScript/publish.ts +++ b/TypeScript/publish.ts @@ -17,184 +17,180 @@ * }) * ``` */ -import {CommandInitPlugin, CommandType, controller, SernOptionsData, SlashCommand} from '@sern/handler' -import {ApplicationCommandData, ApplicationCommandType, PermissionResolvable} from "discord.js"; -import {useContainer} from "../index.js"; +import { + CommandInitPlugin, + CommandType, + controller, + SernOptionsData, + SlashCommand, +} from "@sern/handler"; +import { + ApplicationCommandData, + ApplicationCommandType, + PermissionResolvable, +} from "discord.js"; +import { useContainer } from "../index.js"; export const CommandTypeRaw = { - [CommandType.Both]: ApplicationCommandType.ChatInput, - [CommandType.CtxUser]: ApplicationCommandType.Message, - [CommandType.CtxMsg]: ApplicationCommandType.User, - [CommandType.Slash]: ApplicationCommandType.ChatInput, + [CommandType.Both]: ApplicationCommandType.ChatInput, + [CommandType.CtxUser]: ApplicationCommandType.Message, + [CommandType.CtxMsg]: ApplicationCommandType.User, + [CommandType.Slash]: ApplicationCommandType.ChatInput, } as const; -export function publish( - options?: PublishOptions -) { - return CommandInitPlugin(async ({ module }) => { - // Users need to provide their own useContainer function. - const [client] = useContainer("@sern/client"); - const defaultOptions = { - guildIds: [], - dmPermission: undefined, - defaultMemberPermissions: null, - }; +export function publish< + T extends + | CommandType.Both + | CommandType.Slash + | CommandType.CtxMsg + | CommandType.CtxUser +>(options?: PublishOptions) { + return CommandInitPlugin(async ({ module }) => { + // Users need to provide their own useContainer function. + const [client] = useContainer("@sern/client"); + const defaultOptions = { + guildIds: [], + dmPermission: undefined, + defaultMemberPermissions: null, + }; - options = {...defaultOptions, ...options} as PublishOptions & - ValidPublishOptions; - let {defaultMemberPermissions, dmPermission, guildIds} = - options as unknown as ValidPublishOptions; + options = { ...defaultOptions, ...options } as PublishOptions & + ValidPublishOptions; + let { defaultMemberPermissions, dmPermission, guildIds } = + options as unknown as ValidPublishOptions; - function c(e: unknown) { - console.error("publish command didnt work for", module.name); - console.error(e); - } + function c(e: unknown) { + console.error("publish command didnt work for", module.name); + console.error(e); + } - const log = - (...message: any[]) => - () => - console.log(...message); - const logged = (...message: any[]) => log(message); - /** - * a local function that returns either one value or the other, - * depending on {t}'s CommandType. If the commandtype of - * this module is CommandType.Both or CommandType.Text or CommandType.Slash, - * return 'is', else return 'els' - * @param t - * @returns S | T - */ - const appCmd = (t: V) => { - return (is: S, els: T) => - (t & CommandType.Both) !== 0 ? is : els; - }; - const curAppType = CommandTypeRaw[module.type]; - const createCommandData = () => { - const cmd = appCmd(module.type); - return { - name: module.name, - type: curAppType, - description: cmd(module.description, ""), - options: cmd( - optionsTransformer( - (module as SlashCommand).options ?? [] - ), - [] - ), - defaultMemberPermissions, - dmPermission, - } as ApplicationCommandData; - }; + const log = + (...message: any[]) => + () => + console.log(...message); + const logged = (...message: any[]) => log(message); + /** + * a local function that returns either one value or the other, + * depending on {t}'s CommandType. If the commandtype of + * this module is CommandType.Both or CommandType.Text or CommandType.Slash, + * return 'is', else return 'els' + * @param t + * @returns S | T + */ + const appCmd = (t: V) => { + return (is: S, els: T) => ((t & CommandType.Both) !== 0 ? is : els); + }; + const curAppType = CommandTypeRaw[module.type]; + const createCommandData = () => { + const cmd = appCmd(module.type); + return { + name: module.name, + type: curAppType, + description: cmd(module.description, ""), + options: cmd( + optionsTransformer((module as SlashCommand).options ?? []), + [] + ), + defaultMemberPermissions, + dmPermission, + } as ApplicationCommandData; + }; - try { - const commandData = createCommandData(); + try { + const commandData = createCommandData(); - if (!guildIds.length) { - const cmd = ( - await client.application!.commands.fetch() - ).find( - (c) => c.name === module.name && c.type === curAppType - ); - if (cmd) { - if (!cmd.equals(commandData, true)) { - logged( - `Found differences in global command ${module.name}` - ); - cmd.edit(commandData).then( - log( - `${module.name} updated with new data successfully!` - ) - ); - } - return controller.next(); - } - client - .application!.commands.create(commandData) - .then(log("Command created", module.name)) - .catch(c); - return controller.next(); - } + if (!guildIds.length) { + const cmd = (await client.application!.commands.fetch()).find( + (c) => c.name === module.name && c.type === curAppType + ); + if (cmd) { + if (!cmd.equals(commandData, true)) { + logged( + `Found differences in global command ${module.name}` + ); + cmd.edit(commandData).then( + log( + `${module.name} updated with new data successfully!` + ) + ); + } + return controller.next(); + } + client + .application!.commands.create(commandData) + .then(log("Command created", module.name)) + .catch(c); + return controller.next(); + } - for (const id of guildIds) { - 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 - ); - if (guildCmd) { - if (!guildCmd.equals(commandData, true)) { - logged( - `Found differences in command ${module.name}` - ); - guildCmd - .edit(commandData) - .then( - log( - `${module.name} updated with new data successfully!` - ) - ) - .catch(c); - continue; - } - continue; - } - guild.commands - .create(commandData) - .then( - log( - "Guild Command created", - module.name, - guild.name - ) - ) - .catch(c); - } - return controller.next(); - } catch (e) { - logged("Command did not register" + module.name); - logged(e); - return controller.stop(); - } - }) + for (const id of guildIds) { + 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 + ); + if (guildCmd) { + if (!guildCmd.equals(commandData, true)) { + logged(`Found differences in command ${module.name}`); + guildCmd + .edit(commandData) + .then( + log( + `${module.name} updated with new data successfully!` + ) + ) + .catch(c); + continue; + } + continue; + } + guild.commands + .create(commandData) + .then(log("Guild Command created", module.name, guild.name)) + .catch(c); + } + return controller.next(); + } catch (e) { + logged("Command did not register" + module.name); + logged(e); + return controller.stop(); + } + }); } export function optionsTransformer(ops: Array) { - return ops.map((el) => - el.autocomplete ? (({command, ...el}) => el)(el) : el - ); + return ops.map((el) => + el.autocomplete ? (({ command, ...el }) => el)(el) : el + ); } export type NonEmptyArray = [T, ...T[]]; export interface ValidPublishOptions { - guildIds: string[]; - dmPermission: boolean; - defaultMemberPermissions: PermissionResolvable; + guildIds: string[]; + dmPermission: boolean; + defaultMemberPermissions: PermissionResolvable; } interface GuildPublishOptions { - guildIds?: NonEmptyArray; - defaultMemberPermissions?: PermissionResolvable; - dmPermission?: never; + guildIds?: NonEmptyArray; + defaultMemberPermissions?: PermissionResolvable; + dmPermission?: never; } interface GlobalPublishOptions { - defaultMemberPermissions?: PermissionResolvable; - dmPermission?: false; - guildIds?: never; + defaultMemberPermissions?: PermissionResolvable; + dmPermission?: false; + guildIds?: never; } type BasePublishOptions = GuildPublishOptions | GlobalPublishOptions; export type PublishOptions = BasePublishOptions & - ( - | Required> - | ( - | Required> - | Required> - ) - ); \ No newline at end of file + ( + | Required> + | ( + | Required> + | Required> + ) + ); diff --git a/TypeScript/requirePermission.ts b/TypeScript/requirePermission.ts index ca02a96..c7a4ca4 100644 --- a/TypeScript/requirePermission.ts +++ b/TypeScript/requirePermission.ts @@ -19,9 +19,7 @@ */ import type { GuildMember, PermissionResolvable } from "discord.js"; -import { - CommandType, CommandControlPlugin, controller, -} from "@sern/handler"; +import { CommandType, CommandControlPlugin, controller } from "@sern/handler"; function payload(resp?: string) { return { @@ -73,10 +71,7 @@ export function requirePermission( return controller.next(); //*********************************************************************************************************************// case "both": - if ( - !bot.permissions.has(perm) || - !memm.permissions.has(perm) - ) { + if (!bot.permissions.has(perm) || !memm.permissions.has(perm)) { if (!response) response = `Please ensure <@${bot.user.id}> and <@${ memm.user.id @@ -87,12 +82,9 @@ export function requirePermission( return controller.next(); //*********************************************************************************************************************// default: - console.warn( - "Perm Check >>> You didn't specify user or bot." - ); + console.warn("Perm Check >>> You didn't specify user or bot."); ctx.reply(payload("User or Bot was not specified.")); return controller.stop(); } }); } - diff --git a/TypeScript/serverOnly.ts b/TypeScript/serverOnly.ts index 0445162..47610aa 100644 --- a/TypeScript/serverOnly.ts +++ b/TypeScript/serverOnly.ts @@ -22,21 +22,21 @@ 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." + guildId: string[], + 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) { - return controller.stop() - } - if (!guildId.includes(ctx.guildId)) { - ctx.reply(failMessage).then(async (m) => { - setTimeout(async () => { - await m.delete(); - }, 3000); - }); - return controller.stop(); - } - return controller.next(); - }) + return CommandControlPlugin(async (ctx, _) => { + if (ctx.guildId == null) { + return controller.stop(); + } + if (!guildId.includes(ctx.guildId)) { + ctx.reply(failMessage).then(async (m) => { + setTimeout(async () => { + await m.delete(); + }, 3000); + }); + return controller.stop(); + } + return controller.next(); + }); }