@wolfstar/plugin-subcommands-advanced
v2.2.0
Published
Plugin for @wolfstar/http-framework to modularize slash subcommands into separate command classes
Maintainers
Readme
Modular slash subcommands for @wolfstar/http-framework.
Description
Plugin for @wolfstar/http-framework that lets you split slash subcommands (and subcommand groups) into separate command classes, instead of putting every handler method on the parent.
Adapted from @kaname-png/plugin-subcommands-advanced for WolfStar’s HTTP interaction framework.
Installation
pnpm add @wolfstar/http-framework @wolfstar/plugin-subcommands-advancedUsage
Stars module
On framework 6.1 and later, list the module in modules in stars.config (needs the optional
@wolfstar/kit peer). The module itself takes no options; the package's behaviour is still configured
through ClientOptions.subcommandsAdvanced (for example nameCommandsAutogenerated):
// stars.config.ts
export default defineConfig({
modules: ["@wolfstar/plugin-subcommands-advanced/module"],
});Never combine the module (or the @wolfstar/plugin-subcommands-advanced/plugin factory below) with
import "@wolfstar/plugin-subcommands-advanced/register": both paths install the same hooks, so
combining them installs them twice.
Without Stars, pass the definePlugin factory to plugins instead:
import subcommandsPlugin from "@wolfstar/plugin-subcommands-advanced/plugin";
const client = new Client({ plugins: [subcommandsPlugin()] });register entrypoint (framework v3/v5/v6)
Import the register entrypoint before creating the client:
import "@wolfstar/plugin-subcommands-advanced/register";
import { Client, RegisterCommand } from "@wolfstar/http-framework";
import {
Command,
Subcommand,
RegisterAsSubcommand,
RegisterAsSubcommandGroup,
} from "@wolfstar/plugin-subcommands-advanced";
const client = new Client({
subcommandsAdvanced: {
// optional: piece names become parent/sub or parent/group/sub
nameCommandsAutogenerated: true,
},
});Recommended layout:
commands/
└── utils/
├── parent.ts // parent chat-input command
├── ping.ts // subcommand
└── poll/
└── create.ts // grouped subcommandParent command
import { RegisterCommand } from "@wolfstar/http-framework";
import { Subcommand } from "@wolfstar/plugin-subcommands-advanced";
@RegisterCommand((builder) =>
builder
.setName("utils")
.setDescription("Utility commands")
.addSubcommandGroup((group) => group.setName("poll").setDescription("Poll tools")),
)
export class UtilsCommand extends Subcommand {}Direct subcommand
import { Command, RegisterAsSubcommand } from "@wolfstar/plugin-subcommands-advanced";
@RegisterAsSubcommand("utils", (builder) => builder.setName("ping").setDescription("Ping the bot"))
export class PingCommand extends Command {
public override chatInputRun(interaction: Command.ChatInputInteraction) {
return interaction.reply({ content: "Pong!" });
}
}Grouped subcommand
import { Command, RegisterAsSubcommandGroup } from "@wolfstar/plugin-subcommands-advanced";
@RegisterAsSubcommandGroup("utils", "poll", (builder) =>
builder.setName("create").setDescription("Create a poll"),
)
export class PollCreateCommand extends Command {
public override chatInputRun(interaction: Command.ChatInputInteraction) {
return interaction.reply({ content: "Created!" });
}
}Constructor options (no decorators)
import { Command } from "@wolfstar/plugin-subcommands-advanced";
export class PingCommand extends Command {
public constructor(context: Command.LoaderContext, options: Command.Options) {
super(context, {
...options,
registerSubCommand: {
parentCommandName: "utils",
slashSubcommand: (builder) => builder.setName("ping").setDescription("Ping!"),
},
});
}
public override chatInputRun(interaction: Command.ChatInputInteraction) {
return interaction.reply({ content: "Pong!" });
}
}How it works
@wolfstar/http-framework routes subcommands to methods on the parent command instance. This plugin:
- Lets child command classes register themselves into in-memory registries (by parent name).
- After all command pieces are constructed, rebuilds the parent’s chat-input resolver and
CommandRouter, installing thin delegate methods that call each child’schatInputRun.
You do not need to call the optional hooks.subcommands / hooks.groups helpers unless you are registering the parent imperatively and want to attach builders yourself.
Notes
- HTTP-only: there is no message-command support (unlike the Sapphire original).
- Child classes should not use
@RegisterCommand— only the parent registers the top-level slash command. - Subcommand groups must still be declared on the parent (via
@RegisterCommandbuilder orregisterApplicationCommands). Command.OptionsOf/Subcommand.OptionsOfre-export the framework'sCommand.OptionsOf(options generated bystars codegen). The type needs@wolfstar/http-framework6.2.0 or later; on an older framework it fails to resolve when type-checking withskipLibCheckoff.
