From 15012c7d1730a7f61b570189c2b1e92d6ac0c92b Mon Sep 17 00:00:00 2001 From: WatDuhHekBro <44940783+WatDuhHekBro@users.noreply.github.com> Date: Sat, 10 Apr 2021 12:07:55 -0500 Subject: [PATCH] Reduced clunkiness of rest type and applied changes to commands --- src/commands/fun/eco.ts | 8 ++-- src/commands/fun/figlet.ts | 24 ++++++------ src/commands/fun/modules/eco-core.ts | 21 +++-------- src/commands/fun/modules/eco-shop.ts | 52 +++++++++++++------------- src/commands/fun/owoify.ts | 15 +++++--- src/commands/fun/poll.ts | 8 ++-- src/commands/fun/urban.ts | 8 ++-- src/commands/fun/vaporwave.ts | 8 ++-- src/commands/fun/weather.ts | 8 ++-- src/commands/fun/whois.ts | 9 ++--- src/commands/system/admin.ts | 56 ++++++++++++++++------------ src/commands/system/help.ts | 1 - src/commands/utility/calc.ts | 32 ++++++++-------- src/commands/utility/desc.ts | 26 +++++++------ src/commands/utility/info.ts | 15 ++++---- src/commands/utility/say.ts | 8 ++-- src/commands/utility/time.ts | 17 +++++++-- src/commands/utility/todo.ts | 50 +++++++++++++------------ src/core/command.ts | 55 ++++++++++++--------------- 19 files changed, 217 insertions(+), 204 deletions(-) diff --git a/src/commands/fun/eco.ts b/src/commands/fun/eco.ts index 1572151..96c1b43 100644 --- a/src/commands/fun/eco.ts +++ b/src/commands/fun/eco.ts @@ -1,4 +1,4 @@ -import {Command, NamedCommand, getMemberByName} from "../../core"; +import {Command, NamedCommand, getMemberByName, RestCommand} from "../../core"; import {isAuthorized, getMoneyEmbed} from "./modules/eco-utils"; import {DailyCommand, PayCommand, GuildCommand, LeaderboardCommand} from "./modules/eco-core"; import {BuyCommand, ShopCommand} from "./modules/eco-shop"; @@ -33,11 +33,11 @@ export default new NamedCommand({ if (isAuthorized(guild, channel)) send(getMoneyEmbed(args[0])); } }), - any: new Command({ + any: new RestCommand({ description: "See how much money someone else has by using their username.", - async run({send, guild, channel, args, message}) { + async run({send, guild, channel, args, message, combined}) { if (isAuthorized(guild, channel)) { - const member = await getMemberByName(guild!, args.join(" ")); + const member = await getMemberByName(guild!, combined); if (member instanceof GuildMember) send(getMoneyEmbed(member.user)); else send(member); } diff --git a/src/commands/fun/figlet.ts b/src/commands/fun/figlet.ts index 0ae2538..a25ed2a 100644 --- a/src/commands/fun/figlet.ts +++ b/src/commands/fun/figlet.ts @@ -1,17 +1,19 @@ -import {Command, NamedCommand} from "../../core"; +import {Command, NamedCommand, RestCommand} from "../../core"; import figlet from "figlet"; export default new NamedCommand({ description: "Generates a figlet of your input.", - async run({send, message, channel, guild, author, member, client, args}) { - const input = args.join(" "); - if (!args[0]) return send("You have to provide input for me to create a figlet!"); - return send( - "```" + - figlet.textSync(`${input}`, { + run: "You have to provide input for me to create a figlet!", + any: new RestCommand({ + async run({send, message, channel, guild, author, member, client, args, combined}) { + return send( + figlet.textSync(combined, { horizontalLayout: "full" - }) + - "```" - ); - } + }), + { + code: true + } + ); + } + }) }); diff --git a/src/commands/fun/modules/eco-core.ts b/src/commands/fun/modules/eco-core.ts index 4bb5808..390c268 100644 --- a/src/commands/fun/modules/eco-core.ts +++ b/src/commands/fun/modules/eco-core.ts @@ -1,4 +1,5 @@ -import {Command, NamedCommand, prompt} from "../../../core"; +import {GuildMember} from "discord.js"; +import {Command, getMemberByName, NamedCommand, prompt, RestCommand} from "../../../core"; import {pluralise} from "../../../lib"; import {Storage} from "../../../structures"; import {isAuthorized, getMoneyEmbed, getSendEmbed, ECO_EMBED_COLOR} from "./eco-utils"; @@ -140,8 +141,8 @@ export const PayCommand = new NamedCommand({ number: new Command({ run: "You must use the format `eco pay `!" }), - any: new Command({ - async run({send, args, author, channel, guild}) { + any: new RestCommand({ + async run({send, args, author, channel, guild, combined}) { if (isAuthorized(guild, channel)) { const last = args.pop(); @@ -156,18 +157,8 @@ export const PayCommand = new NamedCommand({ else if (!guild) return send("You have to use this in a server if you want to send Mons with a username!"); - const username = args.join(" "); - const member = ( - await guild.members.fetch({ - query: username, - limit: 1 - }) - ).first(); - - if (!member) - return send( - `Couldn't find a user by the name of \`${username}\`! If you want to send Mons to someone in a different server, you have to use their user ID!` - ); + const member = await getMemberByName(guild, combined); + if (!(member instanceof GuildMember)) return send(member); else if (member.user.id === author.id) return send("You can't send Mons to yourself!"); else if (member.user.bot && process.argv[2] !== "dev") return send("You can't send Mons to a bot!"); diff --git a/src/commands/fun/modules/eco-shop.ts b/src/commands/fun/modules/eco-shop.ts index b76c47d..acd0e4a 100644 --- a/src/commands/fun/modules/eco-shop.ts +++ b/src/commands/fun/modules/eco-shop.ts @@ -1,4 +1,4 @@ -import {Command, NamedCommand, paginate} from "../../../core"; +import {Command, NamedCommand, paginate, RestCommand} from "../../../core"; import {pluralise, split} from "../../../lib"; import {Storage, getPrefix} from "../../../structures"; import {isAuthorized, ECO_EMBED_COLOR} from "./eco-utils"; @@ -47,37 +47,37 @@ export const ShopCommand = new NamedCommand({ export const BuyCommand = new NamedCommand({ description: "Buys an item from the shop.", usage: "", - async run({send, guild, channel, args, message, author}) { - if (isAuthorized(guild, channel)) { - let found = false; + run: "You need to specify an item to buy.", + any: new RestCommand({ + async run({send, guild, channel, args, message, author, combined}) { + if (isAuthorized(guild, channel)) { + let found = false; + let amount = 1; // The amount the user is buying. - let amount = 1; // The amount the user is buying. + // For now, no shop items support being bought multiple times. Uncomment these 2 lines when it's supported/needed. + //if (/\d+/g.test(args[args.length - 1])) + //amount = parseInt(args.pop()); - // For now, no shop items support being bought multiple times. Uncomment these 2 lines when it's supported/needed. - //if (/\d+/g.test(args[args.length - 1])) - //amount = parseInt(args.pop()); + for (let item of ShopItems) { + if (item.usage === combined) { + const user = Storage.getUser(author.id); + const cost = item.cost * amount; - let requested = args.join(" "); // The item the user is buying. + if (cost > user.money) { + send("Not enough Mons!"); + } else { + user.money -= cost; + Storage.save(); + item.run(message, cost, amount); + } - for (let item of ShopItems) { - if (item.usage === requested) { - const user = Storage.getUser(author.id); - const cost = item.cost * amount; - - if (cost > user.money) { - send("Not enough Mons!"); - } else { - user.money -= cost; - Storage.save(); - item.run(message, cost, amount); + found = true; + break; } - - found = true; - break; } - } - if (!found) send(`There's no item in the shop that goes by \`${requested}\`!`); + if (!found) send(`There's no item in the shop that goes by \`${combined}\`!`); + } } - } + }) }); diff --git a/src/commands/fun/owoify.ts b/src/commands/fun/owoify.ts index e9e59d9..cbc4ccf 100644 --- a/src/commands/fun/owoify.ts +++ b/src/commands/fun/owoify.ts @@ -1,12 +1,15 @@ -import {Command, NamedCommand} from "../../core"; +import {Command, NamedCommand, RestCommand} from "../../core"; import {getContent} from "../../lib"; import {URL} from "url"; export default new NamedCommand({ description: "OwO-ifies the input.", - async run({send, message, channel, guild, author, member, client, args}) { - let url = new URL(`https://nekos.life/api/v2/owoify?text=${args.join(" ")}`); - const content = (await getContent(url.toString())) as any; // Apparently, the object in question is {owo: string}. - send(content.owo); - } + run: "You need to specify some text to owoify.", + any: new RestCommand({ + async run({send, message, channel, guild, author, member, client, args, combined}) { + let url = new URL(`https://nekos.life/api/v2/owoify?text=${combined}`); + const content = (await getContent(url.toString())) as any; // Apparently, the object in question is {owo: string}. + send(content.owo); + } + }) }); diff --git a/src/commands/fun/poll.ts b/src/commands/fun/poll.ts index 3d60e1e..5795db1 100644 --- a/src/commands/fun/poll.ts +++ b/src/commands/fun/poll.ts @@ -1,13 +1,13 @@ import {MessageEmbed} from "discord.js"; -import {Command, NamedCommand} from "../../core"; +import {Command, NamedCommand, RestCommand} from "../../core"; export default new NamedCommand({ description: "Create a poll.", usage: "", run: "Please provide a question.", - any: new Command({ + any: new RestCommand({ description: "Question for the poll.", - async run({send, message, channel, guild, author, member, client, args}) { + async run({send, message, channel, guild, author, member, client, args, combined}) { const embed = new MessageEmbed() .setAuthor( `Poll created by ${message.author.username}`, @@ -15,7 +15,7 @@ export default new NamedCommand({ ) .setColor(0xffffff) .setFooter("React to vote.") - .setDescription(args.join(" ")); + .setDescription(combined); const msg = await send(embed); await msg.react("✅"); await msg.react("⛔"); diff --git a/src/commands/fun/urban.ts b/src/commands/fun/urban.ts index 44d5a64..928ca57 100644 --- a/src/commands/fun/urban.ts +++ b/src/commands/fun/urban.ts @@ -1,14 +1,14 @@ -import {Command, NamedCommand} from "../../core"; +import {Command, NamedCommand, RestCommand} from "../../core"; import {MessageEmbed} from "discord.js"; import urban from "relevant-urban"; export default new NamedCommand({ description: "Gives you a definition of the inputted word.", run: "Please input a word.", - any: new Command({ - async run({send, message, channel, guild, author, member, client, args}) { + any: new RestCommand({ + async run({send, message, channel, guild, author, member, client, args, combined}) { // [Bug Fix]: Use encodeURIComponent() when emojis are used: "TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters" - urban(encodeURIComponent(args.join(" "))) + urban(encodeURIComponent(combined)) .then((res) => { const embed = new MessageEmbed() .setColor(0x1d2439) diff --git a/src/commands/fun/vaporwave.ts b/src/commands/fun/vaporwave.ts index e2c1727..71ae065 100644 --- a/src/commands/fun/vaporwave.ts +++ b/src/commands/fun/vaporwave.ts @@ -1,4 +1,4 @@ -import {Command, NamedCommand} from "../../core"; +import {Command, NamedCommand, RestCommand} from "../../core"; const vaporwave = (() => { const map = new Map(); @@ -24,9 +24,9 @@ function getVaporwaveText(text: string): string { export default new NamedCommand({ description: "Transforms your text into vaporwave.", run: "You need to enter some text!", - any: new Command({ - async run({send, message, channel, guild, author, member, client, args}) { - const text = getVaporwaveText(args.join(" ")); + any: new RestCommand({ + async run({send, message, channel, guild, author, member, client, args, combined}) { + const text = getVaporwaveText(combined); if (text !== "") send(text); else send("Make sure to enter at least one valid character."); } diff --git a/src/commands/fun/weather.ts b/src/commands/fun/weather.ts index 6760286..44c82b7 100644 --- a/src/commands/fun/weather.ts +++ b/src/commands/fun/weather.ts @@ -1,15 +1,15 @@ -import {Command, NamedCommand} from "../../core"; +import {Command, NamedCommand, RestCommand} from "../../core"; import {MessageEmbed} from "discord.js"; import {find} from "weather-js"; export default new NamedCommand({ description: "Shows weather info of specified location.", run: "You need to provide a city.", - any: new Command({ - async run({send, message, channel, guild, author, member, client, args}) { + any: new RestCommand({ + async run({send, message, channel, guild, author, member, client, args, combined}) { find( { - search: args.join(" "), + search: combined, degreeType: "C" }, function (error, result) { diff --git a/src/commands/fun/whois.ts b/src/commands/fun/whois.ts index aea91c7..4ad9c97 100644 --- a/src/commands/fun/whois.ts +++ b/src/commands/fun/whois.ts @@ -1,5 +1,5 @@ import {User, GuildMember} from "discord.js"; -import {Command, NamedCommand, getMemberByName, CHANNEL_TYPE} from "../../core"; +import {Command, NamedCommand, getMemberByName, CHANNEL_TYPE, RestCommand} from "../../core"; // Quotes must be used here or the numbers will change const registry: {[id: string]: string} = { @@ -65,11 +65,10 @@ export default new NamedCommand({ } } }), - any: new Command({ + any: new RestCommand({ channelType: CHANNEL_TYPE.GUILD, - async run({send, message, channel, guild, author, client, args}) { - const query = args.join(" ") as string; - const member = await getMemberByName(guild!, query); + async run({send, message, channel, guild, author, client, args, combined}) { + const member = await getMemberByName(guild!, combined); if (member instanceof GuildMember) { if (member.id in registry) { diff --git a/src/commands/system/admin.ts b/src/commands/system/admin.ts index 6b2593a..b49e890 100644 --- a/src/commands/system/admin.ts +++ b/src/commands/system/admin.ts @@ -1,4 +1,12 @@ -import {Command, NamedCommand, botHasPermission, getPermissionLevel, getPermissionName, CHANNEL_TYPE} from "../../core"; +import { + Command, + NamedCommand, + botHasPermission, + getPermissionLevel, + getPermissionName, + CHANNEL_TYPE, + RestCommand +} from "../../core"; import {clean} from "../../lib"; import {Config, Storage} from "../../structures"; import {Permissions, TextChannel, User} from "discord.js"; @@ -119,12 +127,11 @@ export default new NamedCommand({ Storage.save(); send("Reset your server's welcome message to the default."); }, - any: new Command({ - async run({send, message, channel, guild, author, member, client, args}) { - const newMessage = args.join(" "); - Storage.getGuild(guild!.id).welcomeMessage = newMessage; + any: new RestCommand({ + async run({send, message, channel, guild, author, member, client, args, combined}) { + Storage.getGuild(guild!.id).welcomeMessage = combined; Storage.save(); - send(`Set your server's welcome message to \`${newMessage}\`.`); + send(`Set your server's welcome message to \`${combined}\`.`); } }) }) @@ -241,29 +248,32 @@ export default new NamedCommand({ description: "Evaluate code.", usage: "", permission: PERMISSIONS.BOT_OWNER, - // You have to bring everything into scope to use them. AFAIK, there isn't a more maintainable way to do this, but at least TS will let you know if anything gets removed. - async run({send, message, channel, guild, author, member, client, args}) { - try { - const code = args.join(" "); - let evaled = eval(code); - - if (typeof evaled !== "string") evaled = require("util").inspect(evaled); - send(clean(evaled), {code: "js", split: true}); - } catch (err) { - send(clean(err), {code: "js", split: true}); + run: "You have to enter some code to execute first.", + any: new RestCommand({ + // You have to bring everything into scope to use them. AFAIK, there isn't a more maintainable way to do this, but at least TS will let you know if anything gets removed. + async run({send, message, channel, guild, author, member, client, args, combined}) { + try { + let evaled = eval(combined); + if (typeof evaled !== "string") evaled = require("util").inspect(evaled); + send(clean(evaled), {code: "js", split: true}); + } catch (err) { + send(clean(err), {code: "js", split: true}); + } } - } + }) }), nick: new NamedCommand({ description: "Change the bot's nickname.", permission: PERMISSIONS.BOT_SUPPORT, channelType: CHANNEL_TYPE.GUILD, - async run({send, message, channel, guild, author, member, client, args}) { - const nickName = args.join(" "); - await guild!.me?.setNickname(nickName); - if (botHasPermission(guild, Permissions.FLAGS.MANAGE_MESSAGES)) message.delete({timeout: 5000}); - send(`Nickname set to \`${nickName}\``).then((m) => m.delete({timeout: 5000})); - } + run: "You have to specify a nickname to set for the bot", + any: new RestCommand({ + async run({send, message, channel, guild, author, member, client, args, combined}) { + await guild!.me?.setNickname(combined); + if (botHasPermission(guild, Permissions.FLAGS.MANAGE_MESSAGES)) message.delete({timeout: 5000}); + send(`Nickname set to \`${combined}\``).then((m) => m.delete({timeout: 5000})); + } + }) }), guilds: new NamedCommand({ description: "Shows a list of all guilds the bot is a member of.", diff --git a/src/commands/system/help.ts b/src/commands/system/help.ts index 8e32c35..7691a5a 100644 --- a/src/commands/system/help.ts +++ b/src/commands/system/help.ts @@ -53,7 +53,6 @@ export default new NamedCommand({ list.push(`❯ \`${header} ${type}${customUsage}\` - ${subcommand.description}`); } - if (result.hasRestCommand) list.push(`❯ \`${header} <...>\``); append = list.length > 0 ? list.join("\n") : "None"; } else { append = `\`${header} ${command.usage}\``; diff --git a/src/commands/utility/calc.ts b/src/commands/utility/calc.ts index e31940d..ac0727d 100644 --- a/src/commands/utility/calc.ts +++ b/src/commands/utility/calc.ts @@ -1,22 +1,24 @@ -import {Command, NamedCommand} from "../../core"; +import {Command, NamedCommand, RestCommand} from "../../core"; import * as math from "mathjs"; import {MessageEmbed} from "discord.js"; export default new NamedCommand({ description: "Calculates a specified math expression.", - async run({send, message, channel, guild, author, member, client, args}) { - if (!args[0]) return send("Please provide a calculation."); - let resp; - try { - resp = math.evaluate(args.join(" ")); - } catch (e) { - return send("Please provide a *valid* calculation."); + run: "Please provide a calculation.", + any: new RestCommand({ + async run({send, message, channel, guild, author, member, client, args, combined}) { + let resp; + try { + resp = math.evaluate(combined); + } catch (e) { + return send("Please provide a *valid* calculation."); + } + const embed = new MessageEmbed() + .setColor(0xffffff) + .setTitle("Math Calculation") + .addField("Input", `\`\`\`js\n${combined}\`\`\``) + .addField("Output", `\`\`\`js\n${resp}\`\`\``); + return send(embed); } - const embed = new MessageEmbed() - .setColor(0xffffff) - .setTitle("Math Calculation") - .addField("Input", `\`\`\`js\n${args.join("")}\`\`\``) - .addField("Output", `\`\`\`js\n${resp}\`\`\``); - return send(embed); - } + }) }); diff --git a/src/commands/utility/desc.ts b/src/commands/utility/desc.ts index 773b997..9930df3 100644 --- a/src/commands/utility/desc.ts +++ b/src/commands/utility/desc.ts @@ -1,19 +1,21 @@ -import {Command, NamedCommand} from "../../core"; +import {Command, NamedCommand, RestCommand} from "../../core"; export default new NamedCommand({ description: "Renames current voice channel.", usage: "", - async run({send, message, channel, guild, author, member, client, args}) { - const voiceChannel = message.member?.voice.channel; + run: "Please provide a new voice channel name.", + any: new RestCommand({ + async run({send, message, channel, guild, author, member, client, args, combined}) { + const voiceChannel = message.member?.voice.channel; - if (!voiceChannel) return send("You are not in a voice channel."); - if (!voiceChannel.guild.me?.hasPermission("MANAGE_CHANNELS")) - return send("I am lacking the required permissions to perform this action."); - if (args.length === 0) return send("Please provide a new voice channel name."); + if (!voiceChannel) return send("You are not in a voice channel."); + if (!voiceChannel.guild.me?.hasPermission("MANAGE_CHANNELS")) + return send("I am lacking the required permissions to perform this action."); - const prevName = voiceChannel.name; - const newName = args.join(" "); - await voiceChannel.setName(newName); - return await send(`Changed channel name from "${prevName}" to "${newName}".`); - } + const prevName = voiceChannel.name; + const newName = combined; + await voiceChannel.setName(newName); + return await send(`Changed channel name from "${prevName}" to "${newName}".`); + } + }) }); diff --git a/src/commands/utility/info.ts b/src/commands/utility/info.ts index fff17c5..5e51363 100644 --- a/src/commands/utility/info.ts +++ b/src/commands/utility/info.ts @@ -1,7 +1,7 @@ import {MessageEmbed, version as djsversion, Guild, User, GuildMember} from "discord.js"; import ms from "ms"; import os from "os"; -import {Command, NamedCommand, getMemberByName, CHANNEL_TYPE, getGuildByName} from "../../core"; +import {Command, NamedCommand, getMemberByName, CHANNEL_TYPE, getGuildByName, RestCommand} from "../../core"; import {formatBytes, trimArray} from "../../lib"; import {verificationLevels, filterLevels, regions} from "../../defs/info"; import moment, {utc} from "moment"; @@ -30,12 +30,11 @@ export default new NamedCommand({ ); } }), - any: new Command({ + any: new RestCommand({ description: "Shows another user's avatar by searching their name", channelType: CHANNEL_TYPE.GUILD, - async run({send, message, channel, guild, author, client, args}) { - const name = args.join(" "); - const member = await getMemberByName(guild!, name); + async run({send, message, channel, guild, author, client, args, combined}) { + const member = await getMemberByName(guild!, combined); if (member instanceof GuildMember) { send( @@ -106,10 +105,10 @@ export default new NamedCommand({ send(await getGuildInfo(targetGuild, guild)); } }), - any: new Command({ + any: new RestCommand({ description: "Display info about a guild by finding its name.", - async run({send, message, channel, guild, author, member, client, args}) { - const targetGuild = getGuildByName(args.join(" ")); + async run({send, message, channel, guild, author, member, client, args, combined}) { + const targetGuild = getGuildByName(combined); if (targetGuild instanceof Guild) { send(await getGuildInfo(targetGuild, guild)); diff --git a/src/commands/utility/say.ts b/src/commands/utility/say.ts index 02067a1..0ffe639 100644 --- a/src/commands/utility/say.ts +++ b/src/commands/utility/say.ts @@ -1,13 +1,13 @@ -import {Command, NamedCommand} from "../../core"; +import {Command, NamedCommand, RestCommand} from "../../core"; export default new NamedCommand({ description: "Repeats your message.", usage: "", run: "Please provide a message for me to say!", - any: new Command({ + any: new RestCommand({ description: "Message to repeat.", - async run({send, message, channel, guild, author, member, client, args}) { - send(`*${author} says:*\n${args.join(" ")}`); + async run({send, message, channel, guild, author, member, client, args, combined}) { + send(`*${author} says:*\n${combined}`); } }) }); diff --git a/src/commands/utility/time.ts b/src/commands/utility/time.ts index 1196ea5..7598f5a 100644 --- a/src/commands/utility/time.ts +++ b/src/commands/utility/time.ts @@ -1,4 +1,13 @@ -import {Command, NamedCommand, ask, askYesOrNo, askMultipleChoice, prompt, getMemberByName} from "../../core"; +import { + Command, + NamedCommand, + ask, + askYesOrNo, + askMultipleChoice, + prompt, + getMemberByName, + RestCommand +} from "../../core"; import {Storage} from "../../structures"; import {User, GuildMember} from "discord.js"; import moment from "moment"; @@ -381,10 +390,10 @@ export default new NamedCommand({ send(getTimeEmbed(args[0])); } }), - any: new Command({ + any: new RestCommand({ description: "See what time it is for someone else (by their username).", - async run({send, channel, args, guild}) { - const member = await getMemberByName(guild!, args.join(" ")); + async run({send, channel, args, guild, combined}) { + const member = await getMemberByName(guild!, combined); if (member instanceof GuildMember) send(getTimeEmbed(member.user)); else send(member); } diff --git a/src/commands/utility/todo.ts b/src/commands/utility/todo.ts index 57961c0..9057166 100644 --- a/src/commands/utility/todo.ts +++ b/src/commands/utility/todo.ts @@ -1,4 +1,4 @@ -import {Command, NamedCommand} from "../../core"; +import {Command, NamedCommand, RestCommand} from "../../core"; import moment from "moment"; import {Storage} from "../../structures"; import {MessageEmbed} from "discord.js"; @@ -21,34 +21,38 @@ export default new NamedCommand({ }, subcommands: { add: new NamedCommand({ - async run({send, message, channel, guild, author, member, client, args}) { - const user = Storage.getUser(author.id); - const note = args.join(" "); - user.todoList[Date.now().toString()] = note; - console.debug(user.todoList); - Storage.save(); - send(`Successfully added \`${note}\` to your todo list.`); - } + run: "You need to specify a note to add.", + any: new RestCommand({ + async run({send, message, channel, guild, author, member, client, args, combined}) { + const user = Storage.getUser(author.id); + user.todoList[Date.now().toString()] = combined; + console.debug(user.todoList); + Storage.save(); + send(`Successfully added \`${combined}\` to your todo list.`); + } + }) }), remove: new NamedCommand({ - async run({send, message, channel, guild, author, member, client, args}) { - const user = Storage.getUser(author.id); - const note = args.join(" "); - let isFound = false; + run: "You need to specify a note to remove.", + any: new RestCommand({ + async run({send, message, channel, guild, author, member, client, args, combined}) { + const user = Storage.getUser(author.id); + let isFound = false; - for (const timestamp in user.todoList) { - const selectedNote = user.todoList[timestamp]; + for (const timestamp in user.todoList) { + const selectedNote = user.todoList[timestamp]; - if (selectedNote === note) { - delete user.todoList[timestamp]; - Storage.save(); - isFound = true; - send(`Removed \`${note}\` from your todo list.`); + if (selectedNote === combined) { + delete user.todoList[timestamp]; + Storage.save(); + isFound = true; + send(`Removed \`${combined}\` from your todo list.`); + } } - } - if (!isFound) send("That item couldn't be found."); - } + if (!isFound) send("That item couldn't be found."); + } + }) }), clear: new NamedCommand({ async run({send, message, channel, guild, author, member, client, args}) { diff --git a/src/core/command.ts b/src/core/command.ts index 703ca9d..c818986 100644 --- a/src/core/command.ts +++ b/src/core/command.ts @@ -82,7 +82,6 @@ interface CommandOptionsBase { interface CommandOptionsEndpoint { readonly endpoint: true; - readonly rest?: RestCommand; readonly run?: (($: CommandMenu) => Promise) | string; } @@ -91,6 +90,7 @@ interface CommandOptionsEndpoint { // Role pings, maybe not, but it's not a big deal. interface CommandOptionsNonEndpoint { readonly endpoint?: false; + readonly run?: (($: CommandMenu) => Promise) | string; readonly subcommands?: {[key: string]: NamedCommand}; readonly channel?: Command; readonly role?: Command; @@ -100,9 +100,7 @@ interface CommandOptionsNonEndpoint { readonly guild?: Command; // Only available if an ID is set to reroute to it. readonly id?: ID; readonly number?: Command; - readonly any?: Command; - readonly rest?: undefined; // Redeclare it here as undefined to prevent its use otherwise. - readonly run?: (($: CommandMenu) => Promise) | string; + readonly any?: Command | RestCommand; } type CommandOptions = CommandOptionsBase & (CommandOptionsEndpoint | CommandOptionsNonEndpoint); @@ -123,9 +121,8 @@ interface ExecuteCommandMetadata { export interface CommandInfo { readonly type: "info"; readonly command: BaseCommand; - readonly subcommandInfo: Collection; - readonly keyedSubcommandInfo: Collection; - readonly hasRestCommand: boolean; + readonly subcommandInfo: Collection; + readonly keyedSubcommandInfo: Collection; readonly permission: number; readonly nsfw: boolean; readonly channelType: CHANNEL_TYPE; @@ -181,8 +178,7 @@ export class Command extends BaseCommand { private id: Command | null; private idType: ID | null; private number: Command | null; - private any: Command | null; - private rest: RestCommand | null; + private any: Command | RestCommand | null; constructor(options?: CommandOptions) { super(options); @@ -199,7 +195,6 @@ export class Command extends BaseCommand { this.idType = null; this.number = null; this.any = null; - this.rest = null; if (options && !options.endpoint) { if (options.channel) this.channel = options.channel; @@ -263,8 +258,6 @@ export class Command extends BaseCommand { } } } - } else if (options && options.endpoint) { - if (options.rest) this.rest = options.rest; } } @@ -327,14 +320,7 @@ export class Command extends BaseCommand { } // If the current command is an endpoint but there are still some arguments left, don't continue unless there's a RestCommand. - if (this.endpoint) { - if (this.rest) { - args.unshift(param); - return this.rest.execute(args.join(" "), menu, metadata); - } else { - return {content: "Too many arguments!"}; - } - } + if (this.endpoint) return {content: "Too many arguments!"}; // Resolve the value of the current command's argument (adding it to the resolved args), // then pass the thread of execution to whichever subcommand is valid (if any). @@ -513,10 +499,14 @@ export class Command extends BaseCommand { metadata.symbolicArgs.push(""); menu.args.push(Number(param)); return this.number.execute(args, menu, metadata); - } else if (this.any) { + } else if (this.any instanceof Command) { metadata.symbolicArgs.push(""); menu.args.push(param); return this.any.execute(args, menu, metadata); + } else if (this.any instanceof RestCommand) { + metadata.symbolicArgs.push("<...>"); + args.unshift(param); + return this.any.execute(args.join(" "), menu, metadata); } else { // Continue adding on the rest of the arguments if there's no valid subcommand. menu.args.push(param); @@ -553,8 +543,8 @@ export class Command extends BaseCommand { // If there are no arguments left, return the data or an error message. if (param === undefined) { - const keyedSubcommandInfo = new Collection(); - const subcommandInfo = new Collection(); + const keyedSubcommandInfo = new Collection(); + const subcommandInfo = new Collection(); // Get all the subcommands of the current command but without aliases. for (const [tag, command] of this.subcommands.entries()) { @@ -572,14 +562,18 @@ export class Command extends BaseCommand { if (this.user) subcommandInfo.set("", this.user); if (this.id) subcommandInfo.set(`>`, this.id); if (this.number) subcommandInfo.set("", this.number); - if (this.any) subcommandInfo.set("", this.any); + + // The special case for a possible rest command. + if (this.any) { + if (this.any instanceof Command) subcommandInfo.set("", this.any); + else subcommandInfo.set("<...>", this.any); + } return { type: "info", command: this, keyedSubcommandInfo, subcommandInfo, - hasRestCommand: !!this.rest, ...metadata }; } @@ -640,16 +634,16 @@ export class Command extends BaseCommand { return invalidSubcommandGenerator(); } } else if (param === "") { - if (this.any) { + if (this.any instanceof Command) { metadata.args.push(""); return this.any.resolveInfoInternal(args, metadata); } else { return invalidSubcommandGenerator(); } } else if (param === "<...>") { - if (this.rest) { + if (this.any instanceof RestCommand) { metadata.args.push("<...>"); - return this.rest.resolveInfoFinale(metadata); + return this.any.resolveInfoFinale(metadata); } else { return invalidSubcommandGenerator(); } @@ -755,9 +749,8 @@ export class RestCommand extends BaseCommand { return { type: "info", command: this, - keyedSubcommandInfo: new Collection(), - subcommandInfo: new Collection(), - hasRestCommand: false, + keyedSubcommandInfo: new Collection(), + subcommandInfo: new Collection(), ...metadata }; }