Last active
May 29, 2021 23:44
-
-
Save itsMapleLeaf/d195fda7aebeeff33509aa35d5c51d95 to your computer and use it in GitHub Desktop.
command framework ideas
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export type BlockContext = { | |
| command: <Args extends ArgType<unknown>[]>( | |
| // using this [...Args] makes it infer a tuple for some reason, TS is weird | |
| options: CommandOptions<[...Args]> | |
| ) => void | |
| } | |
| export type CommandOptions<Args extends ArgType<unknown>[]> = { | |
| name: string | |
| description: string | |
| args: [...Args] | |
| action: (context: CommandActionContext<[...Args]>) => void | |
| } | |
| export type ArgType<T> = { parse: (input: unknown) => T } | |
| export type CommandActionContext<Args extends ArgType<unknown>[]> = { | |
| args: { [K in keyof Args]: Args[K] extends ArgType<infer V> ? V : unknown } | |
| reply: (message: string) => void | |
| setName: (name: string) => void | |
| } | |
| export function bot(block: (context: BlockContext) => void) { | |
| const commands = [] | |
| block({ | |
| command: (options) => commands.push(options), | |
| }) | |
| return { | |
| start(token: string) { | |
| // do it | |
| }, | |
| } | |
| } | |
| // simplified, these would probably return some special "invalid input" object or something, or even throw 🤷♂️ | |
| export const stringArg = { parse: (input: unknown) => String(input) } | |
| export const integerArg = { parse: (input: unknown) => Number(input) } | |
| export const booleanArg = { parse: (input: unknown) => Boolean(input) } | |
| /// usage | |
| bot(({ command }) => { | |
| command({ | |
| name: "double", | |
| description: "doubles a number", | |
| args: [integerArg], | |
| action: ({ args: [num], reply }) => { | |
| reply(String(num * 2)) | |
| }, | |
| }) | |
| command({ | |
| name: "rename", | |
| description: "set the name of the bot", | |
| args: [stringArg], | |
| action: ({ args: [name], setName }) => { | |
| setName(name) | |
| }, | |
| }) | |
| command({ | |
| name: "kitchensink", | |
| description: `demonstrates arg inference because I can't think of a realistic example`, | |
| args: [stringArg, integerArg, booleanArg], | |
| action: ({ args: [str, int, bool] }) => {}, | |
| }) | |
| }) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment