commit bd4af8d6dfd496b6f23b3b613331241553c8adb5 Author: EvolutionX Date: Sat Jun 4 11:00:53 2022 +0530 feat: bump initial files and first plugin 🎉 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..07764a7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text eol=lf \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..42061c0 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +README.md \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..8dc2e72 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "tabWidth": 4, + "useTabs": true +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..802ac1f --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +## TODO diff --git a/TypeScript/publish.ts b/TypeScript/publish.ts new file mode 100644 index 0000000..e4ca618 --- /dev/null +++ b/TypeScript/publish.ts @@ -0,0 +1,125 @@ +// @ts-nocheck + +/** + * @author: EvolutionX-10 + * @version: 1.0.0 + * @description: This is publish plugin, it allows you to publish and update your slash commands with ease. + * @license: MIT + * @example: + * ```ts + * import { publish } from "../path/to/your/plugin/folder"; + * import { sernModule, CommandType } from "@sern/handler"; + * export default sernModule([publish()], { // put guild id in array for guild commands + * // your code + * }) + * ``` + */ + +import { + CommandPlugin, + CommandType, + PluginType, + SernOptionsData, +} from "@sern/handler"; +import { ApplicationCommandType } from "discord.js"; + +export function publish( + guildIds: string | Array = [] +): CommandPlugin { + return { + type: PluginType.Command, + description: "Manage Slash Commands", + name: "slash-auto-publish", + async execute(client, module, controller) { + function c(e: unknown) { + console.error("publish command didnt work for", module.name!); + console.error(e); + } + try { + const commandData = { + name: module.name!, + type: CommandTypeRaw[module.type], + description: module.description, + options: optionsTransformer(module.options ?? []), + }; + if (!Array.isArray(guildIds)) guildIds = [guildIds]; + + if (!guildIds.length) { + await client.application?.commands.fetch(); + if ( + client.application?.commands.cache.find( + (c) => c.name === module.name + ) + ) + return controller.next(); + await client + .application!.commands.create(commandData) + .catch(c); + console.log("Command created", module.name!); + return controller.next(); + } + + for (const id of guildIds) { + const guild = await client.guilds.fetch(id).catch(c); + if (!guild) continue; + const cmd = (await guild.commands.fetch()).find( + (c) => c.name === module.name + ); + if (cmd) { + if (!matchData(commandData, cmd)) { + console.log( + `Found differences in command ${module.name}\nUpdating...` + ); + await cmd.edit(commandData).catch(c); + console.log( + `${module.name} updated with new data successfully` + ); + continue; + } + continue; + } + await guild.commands.create(commandData).catch(c); + console.log( + "Guild Command created", + module.name!, + guild.name + ); + } + return controller.next(); + } catch (e) { + console.log("Command did not register" + module.name!); + console.log(e); + return controller.stop(); + } + }, + }; +} + +/** + * It compares two objects and returns true if they have the same keys and values + * @param {object} obj1 - The first object to compare. Should ALWAYS be built data from module + * @param {object} obj2 - The object to compare against. + * @returns true + */ +export function matchData(obj1: object, obj2: object) { + const keys = Object.keys(obj1); + for (const key of keys) { + // @ts-ignore + if (JSON.stringify(obj1[key]) !== JSON.stringify(obj2[key])) + return false; + } + return true; +} + +export function optionsTransformer(ops: Array) { + return ops.map((el) => + el.autocomplete ? (({ command, ...el }) => el)(el) : el + ); +} + +export const CommandTypeRaw = { + [CommandType.Both]: ApplicationCommandType.ChatInput, + [CommandType.MenuMsg]: ApplicationCommandType.Message, + [CommandType.MenuUser]: ApplicationCommandType.User, + [CommandType.Slash]: ApplicationCommandType.ChatInput, +} as const;