Reduced clunkiness of rest type and applied changes to commands

This commit is contained in:
WatDuhHekBro 2021-04-10 12:07:55 -05:00
parent 26e0bb5824
commit 15012c7d17
19 changed files with 217 additions and 204 deletions

View File

@ -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);
}

View File

@ -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
}
);
}
})
});

View File

@ -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 <user> <amount>`!"
}),
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!");

View File

@ -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: "<item>",
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}\`!`);
}
}
}
})
});

View File

@ -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);
}
})
});

View File

@ -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: "<question>",
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("⛔");

View File

@ -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)

View File

@ -1,4 +1,4 @@
import {Command, NamedCommand} from "../../core";
import {Command, NamedCommand, RestCommand} from "../../core";
const vaporwave = (() => {
const map = new Map<string, string>();
@ -24,9 +24,9 @@ function getVaporwaveText(text: string): string {
export default new NamedCommand({
description: "Transforms your text into .",
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.");
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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: "<code>",
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.",

View File

@ -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}\``;

View File

@ -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);
}
})
});

View File

@ -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: "<name>",
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}".`);
}
})
});

View File

@ -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));

View File

@ -1,13 +1,13 @@
import {Command, NamedCommand} from "../../core";
import {Command, NamedCommand, RestCommand} from "../../core";
export default new NamedCommand({
description: "Repeats your message.",
usage: "<message>",
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}`);
}
})
});

View File

@ -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);
}

View File

@ -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}) {

View File

@ -82,7 +82,6 @@ interface CommandOptionsBase {
interface CommandOptionsEndpoint {
readonly endpoint: true;
readonly rest?: RestCommand;
readonly run?: (($: CommandMenu) => Promise<any>) | 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<any>) | 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<any>) | 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<string, Command>;
readonly keyedSubcommandInfo: Collection<string, NamedCommand>;
readonly hasRestCommand: boolean;
readonly subcommandInfo: Collection<string, BaseCommand>;
readonly keyedSubcommandInfo: Collection<string, BaseCommand>;
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("<number>");
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("<any>");
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<string, NamedCommand>();
const subcommandInfo = new Collection<string, Command>();
const keyedSubcommandInfo = new Collection<string, BaseCommand>();
const subcommandInfo = new Collection<string, BaseCommand>();
// 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("<user>", this.user);
if (this.id) subcommandInfo.set(`<id = <${this.idType}>>`, this.id);
if (this.number) subcommandInfo.set("<number>", this.number);
if (this.any) subcommandInfo.set("<any>", this.any);
// The special case for a possible rest command.
if (this.any) {
if (this.any instanceof Command) subcommandInfo.set("<any>", 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 === "<any>") {
if (this.any) {
if (this.any instanceof Command) {
metadata.args.push("<any>");
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<string, NamedCommand>(),
subcommandInfo: new Collection<string, Command>(),
hasRestCommand: false,
keyedSubcommandInfo: new Collection<string, BaseCommand>(),
subcommandInfo: new Collection<string, BaseCommand>(),
...metadata
};
}