Initial commit
This commit is contained in:
58
src/server/commands/command.ts
Normal file
58
src/server/commands/command.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import z from "zod";
|
||||
import { CommandExec } from "./cmdtypes.ts";
|
||||
|
||||
export interface CommandOptions {
|
||||
key: string[],
|
||||
subcommands?: Command[],
|
||||
exec?: CommandExec,
|
||||
zod?: z.ZodTuple,
|
||||
help?: string
|
||||
}
|
||||
|
||||
export default class Command {
|
||||
|
||||
subCmds: Command[];
|
||||
key: string[];
|
||||
exec: CommandExec | null;
|
||||
validate: z.ZodTuple | null;
|
||||
help: string | null;
|
||||
#argsLength: number;
|
||||
|
||||
constructor(options: CommandOptions) {
|
||||
this.subCmds = options.subcommands || [];
|
||||
this.key = options.key;
|
||||
this.exec = options.exec || null;
|
||||
this.validate = options.zod || null;
|
||||
this.help = options.help || null;
|
||||
this.#argsLength = options.zod ? options.zod.def.items.length : 0;
|
||||
}
|
||||
|
||||
getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
dispatch(...args: unknown[]): unknown | Promise<unknown> {
|
||||
const root = args[0] as string | undefined;
|
||||
if (!root && this.exec)
|
||||
return this.exec(...args);
|
||||
else if (!root) return new Error('No execution target for this root');
|
||||
|
||||
const cmd = this.subCmds.find(cmd => cmd.getKey().includes(root));
|
||||
if (cmd) {
|
||||
const newArgs = args.slice(1);
|
||||
if (cmd.#argsLength && newArgs.length !== cmd.#argsLength && cmd.help) return new Error(cmd.help);
|
||||
if (cmd.validate) {
|
||||
const res = cmd.validate.safeParse(newArgs);
|
||||
if (res.success) return cmd.dispatch(...res.data);
|
||||
else if (cmd.help) return new Error(cmd.help);
|
||||
else if (cmd.#argsLength) return new Error(`'${root}' validation error: expected ${cmd.#argsLength} args, got ${newArgs.length}`);
|
||||
else return new Error(`'${root}' validation error`);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.exec)
|
||||
return this.exec(...args);
|
||||
else return new Error(`'${root}': Subcommand not found (args: "${args.join(" ")}")`);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user