mirror of
https://github.com/discordeno/discordeno.git
synced 2026-05-21 02:40:08 +00:00
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.
86 lines
3.7 KiB
TypeScript
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;
|