Files
discordeno/examples/bigbot/src/bot/commands.ts
Fleny 27c261fee2 formatter: Use semicolons (#4686)
I prefer semicolors, they also help avoiding certain pitfalls in JavaScript/TypeScript, such as the following code sample:
```js
const xyz = "test"
(something.else as string) = "another"
```
This results in a TypeError: "test" is not a function, this is because js thinks we are trying to call the string "test" as a function.
To fix this it requires a `;` somewhere before the `(`, such as `;(something ... ` which in my opinion is ugly and less clean overall.
2026-01-17 21:54:15 +01:00

86 lines
3.7 KiB
TypeScript

import type {
ApplicationCommandOptionTypes,
Bot,
Camelize,
CreateApplicationCommand,
DiscordApplicationCommandOption,
ParsedInteractionOption,
} from '@discordeno/bot';
import { bot } from './bot.js';
export default function createCommand<const TOptions extends CommandOptions>(command: Command<TOptions>): void {
bot.commands.set(command.name, command as Command);
}
export type Command<TOptions extends CommandOptions = CommandOptions> = CreateApplicationCommand & {
/** @inheritdoc */
options?: TOptions;
/**
* Should this command be only deployed on the Dev guild?
*
* @default false
*/
devOnly?: boolean;
/** Function to run when the interaction is executed */
run: (interaction: typeof bot.transformers.$inferredTypes.interaction, options: GetCommandOptions<TOptions>) => unknown;
/** Function to run when an autocomplete interaction is fired */
autoComplete?: (interaction: typeof bot.transformers.$inferredTypes.interaction, options: GetCommandOptions<TOptions>) => unknown;
};
export type GetCommandOptions<T extends CommandOptions> = T extends CommandOptions
? { [Prop in keyof BuildOptions<T> as Prop]: BuildOptions<T>[Prop] }
: never;
export type CommandOption = Camelize<DiscordApplicationCommandOption>;
export type CommandOptions = CommandOption[];
// Option parsing
type ResolvedValues = ParsedInteractionOption<ExtractDesiredProps<typeof bot>, ExtractDesiredBehavior<typeof bot>>[string];
// Using omit + exclude is a slight trick to avoid a type error on Pick
export type InteractionResolvedChannel = Omit<
typeof bot.transformers.$inferredTypes.channel,
Exclude<keyof typeof bot.transformers.$inferredTypes.channel, 'id' | 'name' | 'type' | 'permissions' | 'threadMetadata' | 'parentId'>
>;
export type InteractionResolvedMember = Omit<typeof bot.transformers.$inferredTypes.member, 'user' | 'deaf' | 'mute'>;
export interface InteractionResolvedUser {
user: typeof bot.transformers.$inferredTypes.user;
member: InteractionResolvedMember;
}
/**
* From here SubCommandGroup and SubCommand are missing, this is wanted.
*
* The entries are sorted based on the enum value
*/
interface TypeToResolvedMap {
[ApplicationCommandOptionTypes.String]: string;
[ApplicationCommandOptionTypes.Integer]: number;
[ApplicationCommandOptionTypes.Boolean]: boolean;
[ApplicationCommandOptionTypes.User]: InteractionResolvedUser;
[ApplicationCommandOptionTypes.Channel]: InteractionResolvedChannel;
[ApplicationCommandOptionTypes.Role]: typeof bot.transformers.$inferredTypes.role;
[ApplicationCommandOptionTypes.Mentionable]: typeof bot.transformers.$inferredTypes.role | InteractionResolvedUser;
[ApplicationCommandOptionTypes.Number]: number;
[ApplicationCommandOptionTypes.Attachment]: typeof bot.transformers.$inferredTypes.attachment;
}
type ConvertTypeToResolved<T extends ApplicationCommandOptionTypes> = T extends keyof TypeToResolvedMap ? TypeToResolvedMap[T] : ResolvedValues;
type SubCommandApplicationCommand = ApplicationCommandOptionTypes.SubCommand | ApplicationCommandOptionTypes.SubCommandGroup;
type GetOptionName<T> = T extends { name: string } ? T['name'] : never;
type GetOptionValue<T> = T extends { type: ApplicationCommandOptionTypes; required?: boolean }
? T extends { type: SubCommandApplicationCommand; options?: CommandOptions }
? BuildOptions<T['options']>
: ConvertTypeToResolved<T['type']> | (T['required'] extends true ? never : undefined)
: never;
type BuildOptions<T extends CommandOptions | undefined> = {
[Prop in keyof Omit<T, keyof unknown[]> as GetOptionName<T[Prop]>]: GetOptionValue<T[Prop]>;
};
type ExtractDesiredProps<T> = T extends Bot<infer Props, infer _Behavior> ? Props : never;
type ExtractDesiredBehavior<T> = T extends Bot<infer _Props, infer Behavior> ? Behavior : never;