Commands

Sub-Zero (Sub Commands)

We've covered the basics of creating a command, but what if we want to create a command that has subcommands? For example, we want to create a command with a create subcommand and a delete subcommand. This is where subcommands come into play.

Creating a Subcommand

To create a subcommand, we need to create a new class that extends SubCommand and implement the run method. Then, we need to add the subcommand to the main command.

Let's assume you have the following directory structure:

src
commands
index.ts
seyfert.config.mjs
package.json
tsconfig.json

With this file structure, you can use @Autoload() and Seyfert will automatically add the commands for you. But make sure to export the subcommands by default.

import { Declare, Command, Options } from "seyfert";
import { CreateCommand } from "./create.command";
import { DeleteCommand } from "./delete.command";

@Declare({
	name: "account",
	description: "account command"
})
// Being in the same folder with @AutoLoad() you can save this step
@Options([CreateCommand, DeleteCommand])
export default class AccountCommand extends Command {}
import { type CommandContext, Declare, SubCommand } from "seyfert";

@Declare({
	name: "create",
	description: "create a new something"
})
export class CreateCommand extends SubCommand {
	run(ctx: CommandContext) {
		// some logic here

		return ctx.write({
			content: "create command executed"
		});
	}
}
import { type CommandContext, Declare, SubCommand } from "seyfert";

@Declare({
	name: "delete",
	description: "delete something"
})
export class DeleteCommand extends SubCommand {
	run(ctx: CommandContext) {
		// some logic here

		return ctx.write({
			content: "delete command executed"
		});
	}
}

In the example above, we created a create subcommand and a delete subcommand. Then, we added the subcommands to the main command using the @Options decorator.

Note that we essentially treat the subcommand as an option of the main command. (In fact, this is how Discord handles subcommands too)

Subcommand Groups

For a more divided structure, you can create groups for subcommands using the @Group and @Groups decorators in the main command.

import { Command, Declare, Options, Groups } from 'seyfert';
import MySubCommand from './sub';

@Declare({
    name: 'parent',
    description: 'My main command',
})
@Options([MySubCommand])
@Groups({
    'my-group': {
        defaultDescription: 'A subcommand group',
    }
})
export default class ParentCommand extends Command {}
import { SubCommand, Declare, CommandContext, Group } from 'seyfert';

@Declare({
    name: 'subcommand',
    description: 'One of my subcommands within the my-group group',
})
@Group('my-group')
export default class GroupMySubCommand extends SubCommand {
    run(ctx: CommandContext) {
        return ctx.write({
            content: 'Hello from the subcommand!',
        });
    }
}