From c15e3ab86e859f7b71fe14807c010f6c5576face Mon Sep 17 00:00:00 2001 From: EvolutionX Date: Mon, 14 Feb 2022 09:38:48 +0530 Subject: [PATCH] Matched the case of `Utilities` caused import error --- src/handler/sern.ts | 440 ++++++++++++++++++++++---------------------- 1 file changed, 217 insertions(+), 223 deletions(-) diff --git a/src/handler/sern.ts b/src/handler/sern.ts index ebf0a46..0fa6c0a 100644 --- a/src/handler/sern.ts +++ b/src/handler/sern.ts @@ -1,23 +1,12 @@ -import * as Files from './utilities/readFile'; -import type * as Utils from './utilities/preprocessors/args'; +import * as Files from './Utilities/readFile'; +import type * as Utils from './Utilities/Preprocessors/args'; -import type { - Arg, - Context, - Visibility, - possibleOutput -} from '../types/handler'; +import type { Arg, Context, Visibility, possibleOutput } from '../types/handler'; -import type { - ApplicationCommandOptionData, - Awaitable, - Client, - CommandInteraction, - Message -} from 'discord.js'; +import type { ApplicationCommandOptionData, Awaitable, Client, CommandInteraction, Message } from 'discord.js'; import { Ok, Result, None, Some } from 'ts-results'; -import { isBot, hasPrefix, fmt } from './utilities/messageHelpers'; +import { isBot, hasPrefix, fmt } from './Utilities/messageHelpers'; import Logger from './logger'; /** @@ -25,221 +14,226 @@ import Logger from './logger'; */ export class Handler { - private wrapper: Wrapper; + private wrapper: Wrapper; - /** - * @constructor - * @param {Wrapper} wrapper The data that is required to run sern handler - */ - - constructor( - wrapper: Wrapper, - ) { - this.wrapper = wrapper; - this.client - - /** - * On ready, builds command data and registers them all - * from command directory - **/ - - .on('ready', async () => { - Files.buildData(this) - .then(data => this.registerModules(data)) - if (wrapper.init !== undefined) wrapper.init(this); - new Logger().tableRam() - }) + /** + * @constructor + * @param {Wrapper} wrapper The data that is required to run sern handler + */ - .on('messageCreate', async (message: Message) => { - if (isBot(message) || !hasPrefix(message, this.prefix)) return; - if (message.channel.type === 'DM') return; // TODO: Handle dms + constructor(wrapper: Wrapper) { + this.wrapper = wrapper; + this.client - const tryFmt = fmt(message, this.prefix) - const commandName = tryFmt.shift()!; - const module = Files.Commands.get(commandName) ?? Files.Alias.get(commandName) - if (module === undefined) { - message.channel.send('Unknown legacy command') - return; - } - const cmdResult = (await this.commandResult(module, message, tryFmt.join(' '))) - if (cmdResult === undefined) return; + /** + * On ready, builds command data and registers them all + * from command directory + **/ - message.channel.send(cmdResult); + .on('ready', async () => { + Files.buildData(this).then((data) => this.registerModules(data)); + if (wrapper.init !== undefined) wrapper.init(this); + new Logger().tableRam(); + }) - }) + .on('messageCreate', async (message: Message) => { + if (isBot(message) || !hasPrefix(message, this.prefix)) return; + if (message.channel.type === 'DM') return; // TODO: Handle dms - .on('interactionCreate', async (interaction) => { - if (!interaction.isCommand()) return; - const module = Files.Commands.get(interaction.commandName); - const res = await this.interactionResult(module, interaction); - if (res === undefined) return; - await interaction.reply(res); - }); + const tryFmt = fmt(message, this.prefix); + const commandName = tryFmt.shift()!; + const module = Files.Commands.get(commandName) ?? Files.Alias.get(commandName); + if (module === undefined) { + message.channel.send('Unknown legacy command'); + return; + } + const cmdResult = await this.commandResult(module, message, tryFmt.join(' ')); + if (cmdResult === undefined) return; + + message.channel.send(cmdResult); + }) + + .on('interactionCreate', async (interaction) => { + if (!interaction.isCommand()) return; + const module = Files.Commands.get(interaction.commandName); + const res = await this.interactionResult(module, interaction); + if (res === undefined) return; + await interaction.reply(res); + }); + } + + /** + * + * @param {Files.CommandVal | undefined} module Command file information + * @param {CommandInteraction} interaction The Discord.js command interaction (DiscordJS#CommandInteraction)) + * @returns {possibleOutput | undefined} Takes return value and replies it, if possible input + */ + + private async interactionResult( + module: Files.CommandVal | undefined, + interaction: CommandInteraction, + ): Promise { + if (module === undefined) return 'Unknown slash command!'; + const name = Array.from(Files.Commands.keys()).find((it) => it === interaction.commandName); + if (name === undefined) return `Could not find ${interaction.commandName} command!`; + + if (module.mod.type < CommandType.SLASH) return 'This is not a slash command'; + + const context = { message: None, interaction: Some(interaction) }; + const parsedArgs = module.mod.parse?.(context, ['slash', interaction.options]) ?? Ok(''); + + if (parsedArgs.err) return parsedArgs.val; + + return (await module.mod.delegate(context, parsedArgs))?.val; + } + + /** + * + * @param {Files.CommandVal | undefined} module Command file information + * @param {Message} message The message object + * @param {string} args Anything after the command + * @returns Takes return value and replies it, if possible input + */ + + private async commandResult( + module: Files.CommandVal | undefined, + message: Message, + args: string, + ): Promise { + if (module?.mod === undefined) return 'Unknown legacy command'; + if (module.mod.type === CommandType.SLASH) return `This may be a slash command and not a legacy command`; + if (module.mod.visibility === 'private') { + const checkIsTestServer = this.privateServers.find(({ id }) => id === message.guildId!)?.test; + if (checkIsTestServer === undefined) + return 'This command has the private modifier but is not registered under Handler#privateServers'; + if (checkIsTestServer !== module.mod.test) { + const msg = `This command is only available on test servers.`; // TODO: Customizable private message + + return msg; + } } + const context = { + message: Some(message), + interaction: None, + }; + const parsedArgs = module.mod.parse?.(context, ['text', args]) ?? Ok(''); + if (parsedArgs.err) return parsedArgs.val; + return (await module.mod.delegate(context, parsedArgs))?.val; + } - /** - * - * @param {Files.CommandVal | undefined} module Command file information - * @param {CommandInteraction} interaction The Discord.js command interaction (DiscordJS#CommandInteraction)) - * @returns {possibleOutput | undefined} Takes return value and replies it, if possible input - */ - - private async interactionResult( - module: Files.CommandVal | undefined, - interaction: CommandInteraction): Promise { + /** + * This function chains `Files.buildData` + * @param {{name: string, mod: Module, absPath: string}} modArr module information + */ - if (module === undefined) return 'Unknown slash command!'; - const name = Array.from(Files.Commands.keys()).find(it => it === interaction.commandName); - if (name === undefined) return `Could not find ${interaction.commandName} command!`; - - if (module.mod.type < CommandType.SLASH) return 'This is not a slash command'; - - const context = { message: None, interaction: Some(interaction) } - const parsedArgs = module.mod.parse?.(context, ['slash', interaction.options]) ?? Ok(''); - - if (parsedArgs.err) return parsedArgs.val; - - return (await module.mod.delegate(context, parsedArgs))?.val; - } - - /** - * - * @param {Files.CommandVal | undefined} module Command file information - * @param {Message} message The message object - * @param {string} args Anything after the command - * @returns Takes return value and replies it, if possible input - */ - - private async commandResult(module: Files.CommandVal | undefined, message: Message, args: string): Promise { - if (module?.mod === undefined) return 'Unknown legacy command'; - if (module.mod.type === CommandType.SLASH) return `This may be a slash command and not a legacy command` - if (module.mod.visibility === 'private') { - const checkIsTestServer = this.privateServers.find(({ id }) => id === message.guildId!)?.test; - if (checkIsTestServer === undefined) return 'This command has the private modifier but is not registered under Handler#privateServers'; - if (checkIsTestServer !== module.mod.test) { - const msg = `This command is only available on test servers.`; // TODO: Customizable private message - - return msg; + private async registerModules( + modArr: { + name: string; + mod: Module; + absPath: string; + }[], + ) { + for await (const { name, mod, absPath } of modArr) { + const cmdName = Files.fmtFileName(name); + switch (mod.type) { + case 1: + Files.Commands.set(cmdName, { mod, options: [] }); + break; + case 2: + case 1 | 2: + { + const options = (await import(absPath)).options as ApplicationCommandOptionData[]; + Files.Commands.set(cmdName, { mod, options: options ?? [] }); + switch (mod.visibility) { + case 'private': { + // Reloading guild slash commands + await this.reloadSlash(cmdName, mod.desc, options); + } + case 'public': { + // Creating global commands + await this.client.application!.commands.create({ + name: cmdName, + description: mod.desc, + options, + }); + } } + } + break; + default: + throw Error(`SernHandlerError: ${name} with ${mod.visibility} is not a valid module type.`); + } + + if (mod.alias.length > 0) { + for (const alias of mod.alias) { + Files.Alias.set(alias, { mod, options: [] }); } - const context = { - message: Some(message), - interaction: None - } - const parsedArgs = module.mod.parse?.(context, ['text', args]) ?? Ok(''); - if (parsedArgs.err) return parsedArgs.val; - return (await module.mod.delegate(context, parsedArgs))?.val; + } } - - /** - * This function chains `Files.buildData` - * @param {{name: string, mod: Module, absPath: string}} modArr module information - */ + } - private async registerModules( - modArr: { - name: string, - mod: Module, - absPath: string - }[] - ) { - for await (const { name, mod, absPath } of modArr) { - const cmdName = Files.fmtFileName(name); - switch (mod.type) { - case 1: Files.Commands.set(cmdName, { mod, options: [] }); break; - case 2: - case (1 | 2): { - const options = ((await import(absPath)).options as ApplicationCommandOptionData[]) - Files.Commands.set(cmdName, { mod, options: options ?? [] }); - switch (mod.visibility) { - case 'private': { - // Reloading guild slash commands - await this.reloadSlash(cmdName, mod.desc, options) - } - case 'public': { - // Creating global commands - await this.client.application!.commands - .create({ - name: cmdName, - description: mod.desc, - options - }); - } - } - } break; - default: throw Error(`SernHandlerError: ${name} with ${mod.visibility} is not a valid module type.`); - } + /** + * + * @param {string} cmdName name of command + * @param {string} description description of command + * @param {ApplicationCommandOptionData[]} options any options for the slash command + */ - if (mod.alias.length > 0) { - for (const alias of mod.alias) { - Files.Alias.set(alias, { mod, options: [] }) - } - } - } - } + private async reloadSlash( + cmdName: string, + description: string, + options: ApplicationCommandOptionData[], + ): Promise { + for (const { id } of this.privateServers) { + const guild = await this.client.guilds.fetch(id); - /** - * - * @param {string} cmdName name of command - * @param {string} description description of command - * @param {ApplicationCommandOptionData[]} options any options for the slash command - */ - - private async reloadSlash( - cmdName: string, - description: string, - options: ApplicationCommandOptionData[] - ) : Promise { - for (const { id } of this.privateServers) { - const guild = (await this.client.guilds.fetch(id)); + guild.commands.create({ + name: cmdName, + description, + options, + }); + } + } - guild.commands.create({ - name: cmdName, - description, - options - }); - } - } + /** + * @readonly + * @returns {string} The prefix used for legacy commands + */ - /** - * @readonly - * @returns {string} The prefix used for legacy commands - */ - - get prefix(): string { - return this.wrapper.prefix; - } - - /** - * @readonly - * @returns {string} Directory of the commands folder - */ - - get commandDir(): string { - return this.wrapper.commands; - } + get prefix(): string { + return this.wrapper.prefix; + } - /** - * @readonly - * @returns {Client} the discord.js client (DiscordJS#Client)); - */ - - get client(): Client { - return this.wrapper.client; - } - - /** - * @readonly - * @returns {{test: boolean, id: string}[]} Private server ID for testing or personal use - */ - - get privateServers(): { test: boolean, id: string }[] { - return this.wrapper.privateServers; - } + /** + * @readonly + * @returns {string} Directory of the commands folder + */ + + get commandDir(): string { + return this.wrapper.commands; + } + + /** + * @readonly + * @returns {Client} the discord.js client (DiscordJS#Client)); + */ + + get client(): Client { + return this.wrapper.client; + } + + /** + * @readonly + * @returns {{test: boolean, id: string}[]} Private server ID for testing or personal use + */ + + get privateServers(): { test: boolean; id: string }[] { + return this.wrapper.privateServers; + } } /** - * An object to be passed into Sern.Handler constructor. + * An object to be passed into Sern.Handler constructor. * @typedef {object} Wrapper * @property {readonly Client} client * @property {readonly string} prefix @@ -248,15 +242,15 @@ export class Handler { * @property {readonly {test: boolean, id: string}[]} privateServers */ export interface Wrapper { - readonly client: Client, - readonly prefix: string, - readonly commands: string - init?: (handler: Handler) => void, - readonly privateServers: { test: boolean, id: string }[], + readonly client: Client; + readonly prefix: string; + readonly commands: string; + init?: (handler: Handler) => void; + readonly privateServers: { test: boolean; id: string }[]; } /** - * An object that gets imported and acts as a command. + * An object that gets imported and acts as a command. * @typedef {object} Module * @property {string} desc * @property {Visibility} visibility @@ -266,13 +260,13 @@ export interface Wrapper { */ export interface Module { - alias: string[], - desc: string, - visibility: Visibility, - type: CommandType, - test : boolean, - delegate: (eventParams: Context, args: Ok) => Awaitable | void> - parse?: (ctx: Context, args: Arg) => Utils.ArgType + alias: string[]; + desc: string; + visibility: Visibility; + type: CommandType; + test: boolean; + delegate: (eventParams: Context, args: Ok) => Awaitable | void>; + parse?: (ctx: Context, args: Arg) => Utils.ArgType; } /**