import type { ChatInputCommandInteraction } from "discord.js"; import type { Option, InferOptions } from "./options"; export class Subcommand { constructor( public name: string, public config: { description: string; options?: Record>; run: Function; }, ) {} } export class SubcommandGroup { public subcommands: Record = {}; constructor( public name: string, public description: string, ) {} subcommand>>( name: string, config: { description: string; options?: O; run: ( interaction: ChatInputCommandInteraction, args: InferOptions, ctx: Ctx, ) => Promise | void; }, ): this { this.subcommands[name] = new Subcommand(name, config); return this; } } export class SubcommandGroupBuilder { public subcommands: Record = {}; public groups: Record> = {}; constructor( public name: string, public description: string, public middlewares: Function[] = [], ) {} subcommand>>( name: string, config: { description: string; options?: O; run: ( interaction: ChatInputCommandInteraction, args: InferOptions, ctx: Ctx, ) => Promise | void; }, ): this { this.subcommands[name] = new Subcommand(name, config); return this; } group( name: string, config: { description: string }, setup: (group: SubcommandGroup) => void, ): this { const group = new SubcommandGroup(name, config.description); setup(group); this.groups[name] = group; return this; } } export class Command { constructor( public name: string, public config: { description: string; options?: Record>; run: Function; }, public middlewares: Function[] = [], ) {} } export class CommandBuilder { constructor(private middlewares: Function[] = []) {} use>( mw: ( interaction: ChatInputCommandInteraction, ctx: Ctx, ) => Promise | NewCtx | void, ): CommandBuilder { return new CommandBuilder([...this.middlewares, mw]); } command>>( name: string, config: { description: string; options?: O; run: ( interaction: ChatInputCommandInteraction, args: InferOptions, ctx: Ctx, ) => Promise | void; }, ): Command; command(name: string, config: { description: string }): SubcommandGroupBuilder; command(name: string, config: any): any { if (config.run) { return new Command(name, config, this.middlewares); } return new SubcommandGroupBuilder(name, config.description, this.middlewares); } }