mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-03 05:26:07 +00:00
fix: interaction option resolver
This commit is contained in:
parent
a765fddf32
commit
fecd90a6f4
@ -348,8 +348,8 @@ export interface CommandInteractionDataResolved {
|
|||||||
users: Map<Snowflake, User>;
|
users: Map<Snowflake, User>;
|
||||||
members: Map<Snowflake, Member>;
|
members: Map<Snowflake, Member>;
|
||||||
roles: Map<Snowflake, Role>;
|
roles: Map<Snowflake, Role>;
|
||||||
attachments: Map<Snowflake, Attachment>;
|
|
||||||
messages: Map<Snowflake, Message>;
|
messages: Map<Snowflake, Message>;
|
||||||
|
attachments: Map<Snowflake, Attachment>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CommandInteraction extends BaseInteraction implements Model {
|
export class CommandInteraction extends BaseInteraction implements Model {
|
||||||
|
@ -1,64 +1,10 @@
|
|||||||
import type {
|
import type {
|
||||||
DiscordInteractionDataOption,
|
DiscordInteractionDataOption,
|
||||||
DiscordInteractionDataResolved,
|
DiscordInteractionDataResolved,
|
||||||
|
Snowflake,
|
||||||
} from '@biscuitland/api-types';
|
} from '@biscuitland/api-types';
|
||||||
import { ApplicationCommandOptionTypes } from '@biscuitland/api-types';
|
import { ApplicationCommandOptionTypes } from '@biscuitland/api-types';
|
||||||
|
|
||||||
export function transformOasisInteractionDataOption(
|
|
||||||
o: DiscordInteractionDataOption
|
|
||||||
): CommandInteractionOption {
|
|
||||||
const output: CommandInteractionOption = {
|
|
||||||
...o,
|
|
||||||
Otherwise: o.value as string | boolean | number | undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (o.type) {
|
|
||||||
case ApplicationCommandOptionTypes.String:
|
|
||||||
output.String = o.value as string;
|
|
||||||
break;
|
|
||||||
case ApplicationCommandOptionTypes.Number:
|
|
||||||
output.Number = o.value as number;
|
|
||||||
break;
|
|
||||||
case ApplicationCommandOptionTypes.Integer:
|
|
||||||
output.Integer = o.value as number;
|
|
||||||
break;
|
|
||||||
case ApplicationCommandOptionTypes.Boolean:
|
|
||||||
output.Boolean = o.value as boolean;
|
|
||||||
break;
|
|
||||||
case ApplicationCommandOptionTypes.Role:
|
|
||||||
output.Role = BigInt(o.value as string);
|
|
||||||
break;
|
|
||||||
case ApplicationCommandOptionTypes.User:
|
|
||||||
output.User = BigInt(o.value as string);
|
|
||||||
break;
|
|
||||||
case ApplicationCommandOptionTypes.Channel:
|
|
||||||
output.Channel = BigInt(o.value as string);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ApplicationCommandOptionTypes.Mentionable:
|
|
||||||
case ApplicationCommandOptionTypes.SubCommand:
|
|
||||||
case ApplicationCommandOptionTypes.SubCommandGroup:
|
|
||||||
default:
|
|
||||||
output.Otherwise = o.value as string | boolean | number | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CommandInteractionOption
|
|
||||||
extends Omit<DiscordInteractionDataOption, 'value'> {
|
|
||||||
Attachment?: string;
|
|
||||||
Boolean?: boolean;
|
|
||||||
User?: bigint;
|
|
||||||
Role?: bigint;
|
|
||||||
Number?: number;
|
|
||||||
Integer?: number;
|
|
||||||
Channel?: bigint;
|
|
||||||
String?: string;
|
|
||||||
Mentionable?: string;
|
|
||||||
Otherwise: string | number | boolean | bigint | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to get the resolved options for a command
|
* Utility class to get the resolved options for a command
|
||||||
* It is really typesafe
|
* It is really typesafe
|
||||||
@ -68,15 +14,14 @@ export class CommandInteractionOptionResolver {
|
|||||||
#subcommand?: string;
|
#subcommand?: string;
|
||||||
#group?: string;
|
#group?: string;
|
||||||
|
|
||||||
hoistedOptions: CommandInteractionOption[];
|
hoistedOptions: DiscordInteractionDataOption[];
|
||||||
resolved?: DiscordInteractionDataResolved;
|
resolved?: DiscordInteractionDataResolved;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
options?: DiscordInteractionDataOption[],
|
options?: DiscordInteractionDataOption[],
|
||||||
resolved?: DiscordInteractionDataResolved
|
resolved?: DiscordInteractionDataResolved
|
||||||
) {
|
) {
|
||||||
this.hoistedOptions =
|
this.hoistedOptions = options ?? [];
|
||||||
options?.map(transformOasisInteractionDataOption) ?? [];
|
|
||||||
|
|
||||||
// warning: black magic do not edit and thank djs authors
|
// warning: black magic do not edit and thank djs authors
|
||||||
|
|
||||||
@ -85,9 +30,7 @@ export class CommandInteractionOptionResolver {
|
|||||||
ApplicationCommandOptionTypes.SubCommandGroup
|
ApplicationCommandOptionTypes.SubCommandGroup
|
||||||
) {
|
) {
|
||||||
this.#group = this.hoistedOptions[0].name;
|
this.#group = this.hoistedOptions[0].name;
|
||||||
this.hoistedOptions = (this.hoistedOptions[0].options ?? []).map(
|
this.hoistedOptions = this.hoistedOptions[0].options ?? [];
|
||||||
transformOasisInteractionDataOption
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -95,9 +38,7 @@ export class CommandInteractionOptionResolver {
|
|||||||
ApplicationCommandOptionTypes.SubCommand
|
ApplicationCommandOptionTypes.SubCommand
|
||||||
) {
|
) {
|
||||||
this.#subcommand = this.hoistedOptions[0].name;
|
this.#subcommand = this.hoistedOptions[0].name;
|
||||||
this.hoistedOptions = (this.hoistedOptions[0].options ?? []).map(
|
this.hoistedOptions = this.hoistedOptions[0].options ?? [];
|
||||||
transformOasisInteractionDataOption
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.resolved = resolved;
|
this.resolved = resolved;
|
||||||
@ -106,10 +47,10 @@ export class CommandInteractionOptionResolver {
|
|||||||
private getTypedOption(
|
private getTypedOption(
|
||||||
name: string | number,
|
name: string | number,
|
||||||
type: ApplicationCommandOptionTypes,
|
type: ApplicationCommandOptionTypes,
|
||||||
properties: (keyof CommandInteractionOption)[],
|
properties: (keyof DiscordInteractionDataOption)[],
|
||||||
required: boolean
|
required: boolean
|
||||||
): CommandInteractionOption | void {
|
): DiscordInteractionDataOption | void {
|
||||||
const option: CommandInteractionOption | undefined = this.get(
|
const option: DiscordInteractionDataOption | undefined = this.get(
|
||||||
name,
|
name,
|
||||||
required
|
required
|
||||||
);
|
);
|
||||||
@ -136,14 +77,14 @@ export class CommandInteractionOptionResolver {
|
|||||||
return option;
|
return option;
|
||||||
}
|
}
|
||||||
|
|
||||||
get(name: string | number, required: true): CommandInteractionOption;
|
get(name: string | number, required: true): DiscordInteractionDataOption;
|
||||||
get(
|
get(
|
||||||
name: string | number,
|
name: string | number,
|
||||||
required: boolean
|
required: boolean
|
||||||
): CommandInteractionOption | undefined;
|
): DiscordInteractionDataOption | undefined;
|
||||||
|
|
||||||
get(name: string | number, required?: boolean) {
|
get(name: string | number, required?: boolean) {
|
||||||
const option: CommandInteractionOption | undefined =
|
const option: DiscordInteractionDataOption | undefined =
|
||||||
this.hoistedOptions.find(o =>
|
this.hoistedOptions.find(o =>
|
||||||
typeof name === 'number'
|
typeof name === 'number'
|
||||||
? o.name === name.toString()
|
? o.name === name.toString()
|
||||||
@ -165,84 +106,84 @@ export class CommandInteractionOptionResolver {
|
|||||||
getString(name: string | number, required: true): string;
|
getString(name: string | number, required: true): string;
|
||||||
getString(name: string | number, required?: boolean): string | undefined;
|
getString(name: string | number, required?: boolean): string | undefined;
|
||||||
getString(name: string | number, required = false) {
|
getString(name: string | number, required = false) {
|
||||||
const option: CommandInteractionOption | void = this.getTypedOption(
|
const option: DiscordInteractionDataOption | void = this.getTypedOption(
|
||||||
name,
|
name,
|
||||||
ApplicationCommandOptionTypes.String,
|
ApplicationCommandOptionTypes.String,
|
||||||
['Otherwise'],
|
['value'],
|
||||||
required
|
required
|
||||||
);
|
);
|
||||||
|
|
||||||
return option?.Otherwise ?? undefined;
|
return option?.value ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** searches for a number option */
|
/** searches for a number option */
|
||||||
getNumber(name: string | number, required: true): number;
|
getNumber(name: string | number, required: true): number;
|
||||||
getNumber(name: string | number, required?: boolean): number | undefined;
|
getNumber(name: string | number, required?: boolean): number | undefined;
|
||||||
getNumber(name: string | number, required = false) {
|
getNumber(name: string | number, required = false) {
|
||||||
const option: CommandInteractionOption | void = this.getTypedOption(
|
const option: DiscordInteractionDataOption | void = this.getTypedOption(
|
||||||
name,
|
name,
|
||||||
ApplicationCommandOptionTypes.Number,
|
ApplicationCommandOptionTypes.Number,
|
||||||
['Otherwise'],
|
['value'],
|
||||||
required
|
required
|
||||||
);
|
);
|
||||||
|
|
||||||
return option?.Otherwise ?? undefined;
|
return option?.value ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** searhces for an integer option */
|
/** searhces for an integer option */
|
||||||
getInteger(name: string | number, required: true): number;
|
getInteger(name: string | number, required: true): number;
|
||||||
getInteger(name: string | number, required?: boolean): number | undefined;
|
getInteger(name: string | number, required?: boolean): number | undefined;
|
||||||
getInteger(name: string | number, required = false) {
|
getInteger(name: string | number, required = false) {
|
||||||
const option: CommandInteractionOption | void = this.getTypedOption(
|
const option: DiscordInteractionDataOption | void = this.getTypedOption(
|
||||||
name,
|
name,
|
||||||
ApplicationCommandOptionTypes.Integer,
|
ApplicationCommandOptionTypes.Integer,
|
||||||
['Otherwise'],
|
['value'],
|
||||||
required
|
required
|
||||||
);
|
);
|
||||||
|
|
||||||
return option?.Otherwise ?? undefined;
|
return option?.value ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** searches for a boolean option */
|
/** searches for a boolean option */
|
||||||
getBoolean(name: string | number, required: true): boolean;
|
getBoolean(name: string | number, required: true): boolean;
|
||||||
getBoolean(name: string | number, required?: boolean): boolean | undefined;
|
getBoolean(name: string | number, required?: boolean): boolean | undefined;
|
||||||
getBoolean(name: string | number, required = false) {
|
getBoolean(name: string | number, required = false) {
|
||||||
const option: CommandInteractionOption | void = this.getTypedOption(
|
const option: DiscordInteractionDataOption | void = this.getTypedOption(
|
||||||
name,
|
name,
|
||||||
ApplicationCommandOptionTypes.Boolean,
|
ApplicationCommandOptionTypes.Boolean,
|
||||||
['Otherwise'],
|
['value'],
|
||||||
required
|
required
|
||||||
);
|
);
|
||||||
|
|
||||||
return option?.Otherwise ?? undefined;
|
return option?.value ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** searches for a user option */
|
/** searches for a user option */
|
||||||
getUser(name: string | number, required: true): bigint;
|
getUser(name: string | number, required: true): Snowflake;
|
||||||
getUser(name: string | number, required?: boolean): bigint | undefined;
|
getUser(name: string | number, required?: boolean): Snowflake | undefined;
|
||||||
getUser(name: string | number, required = false) {
|
getUser(name: string | number, required = false) {
|
||||||
const option: CommandInteractionOption | void = this.getTypedOption(
|
const option: DiscordInteractionDataOption | void = this.getTypedOption(
|
||||||
name,
|
name,
|
||||||
ApplicationCommandOptionTypes.User,
|
ApplicationCommandOptionTypes.User,
|
||||||
['Otherwise'],
|
['value'],
|
||||||
required
|
required
|
||||||
);
|
);
|
||||||
|
|
||||||
return option?.Otherwise ?? undefined;
|
return option?.value ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** searches for a channel option */
|
/** searches for a channel option */
|
||||||
getChannel(name: string | number, required: true): bigint;
|
getChannel(name: string | number, required: true): Snowflake;
|
||||||
getChannel(name: string | number, required?: boolean): bigint | undefined;
|
getChannel(name: string | number, required?: boolean): Snowflake | undefined;
|
||||||
getChannel(name: string | number, required = false) {
|
getChannel(name: string | number, required = false) {
|
||||||
const option: CommandInteractionOption | void = this.getTypedOption(
|
const option: DiscordInteractionDataOption | void = this.getTypedOption(
|
||||||
name,
|
name,
|
||||||
ApplicationCommandOptionTypes.Channel,
|
ApplicationCommandOptionTypes.Channel,
|
||||||
['Otherwise'],
|
['value'],
|
||||||
required
|
required
|
||||||
);
|
);
|
||||||
|
|
||||||
return option?.Otherwise ?? undefined;
|
return option?.value ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** searches for a mentionable-based option */
|
/** searches for a mentionable-based option */
|
||||||
@ -253,71 +194,61 @@ export class CommandInteractionOptionResolver {
|
|||||||
): string | undefined;
|
): string | undefined;
|
||||||
|
|
||||||
getMentionable(name: string | number, required = false) {
|
getMentionable(name: string | number, required = false) {
|
||||||
const option: CommandInteractionOption | void = this.getTypedOption(
|
const option: DiscordInteractionDataOption | void = this.getTypedOption(
|
||||||
name,
|
name,
|
||||||
ApplicationCommandOptionTypes.Mentionable,
|
ApplicationCommandOptionTypes.Mentionable,
|
||||||
['Otherwise'],
|
['value'],
|
||||||
required
|
required
|
||||||
);
|
);
|
||||||
|
|
||||||
return option?.Otherwise ?? undefined;
|
return option?.value ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** searches for a mentionable-based option */
|
/** searches for a mentionable-based option */
|
||||||
getRole(name: string | number, required: true): bigint;
|
getRole(name: string | number, required: true): Snowflake;
|
||||||
getRole(name: string | number, required?: boolean): bigint | undefined;
|
getRole(name: string | number, required?: boolean): Snowflake | undefined;
|
||||||
getRole(name: string | number, required = false) {
|
getRole(name: string | number, required = false) {
|
||||||
const option: CommandInteractionOption | void = this.getTypedOption(
|
const option: DiscordInteractionDataOption | void = this.getTypedOption(
|
||||||
name,
|
name,
|
||||||
ApplicationCommandOptionTypes.Role,
|
ApplicationCommandOptionTypes.Role,
|
||||||
['Otherwise'],
|
['value'],
|
||||||
required
|
required
|
||||||
);
|
);
|
||||||
|
|
||||||
return option?.Otherwise ?? undefined;
|
return option?.value ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** searches for an attachment option */
|
/** searches for an attachment option */
|
||||||
getAttachment(name: string | number, required: true): string;
|
getAttachment(name: string | number, required: true): Snowflake;
|
||||||
getAttachment(
|
getAttachment(name: string | number, required?: boolean): Snowflake | undefined;
|
||||||
name: string | number,
|
|
||||||
required?: boolean
|
|
||||||
): string | undefined;
|
|
||||||
|
|
||||||
getAttachment(name: string | number, required = false) {
|
getAttachment(name: string | number, required = false) {
|
||||||
const option: CommandInteractionOption | void = this.getTypedOption(
|
const option: DiscordInteractionDataOption | void = this.getTypedOption(
|
||||||
name,
|
name,
|
||||||
ApplicationCommandOptionTypes.Attachment,
|
ApplicationCommandOptionTypes.Attachment,
|
||||||
['Otherwise'],
|
['value'],
|
||||||
required
|
required
|
||||||
);
|
);
|
||||||
|
|
||||||
return option?.Otherwise ?? undefined;
|
return option?.value ?? undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** searches for the focused option */
|
/** searches for the focused option */
|
||||||
getFocused(
|
getFocused(full: true): DiscordInteractionDataOption;
|
||||||
full = false
|
getFocused(full: false): DiscordInteractionDataOption["value"];
|
||||||
):
|
getFocused(full: boolean = false) {
|
||||||
| string
|
const focusedOption: DiscordInteractionDataOption | void =
|
||||||
| number
|
|
||||||
| bigint
|
|
||||||
| boolean
|
|
||||||
| undefined
|
|
||||||
| CommandInteractionOption {
|
|
||||||
const focusedOption: CommandInteractionOption | void =
|
|
||||||
this.hoistedOptions.find(option => option.focused);
|
this.hoistedOptions.find(option => option.focused);
|
||||||
|
|
||||||
if (!focusedOption) {
|
if (!focusedOption) {
|
||||||
throw new TypeError('No option found');
|
throw new TypeError('No option found');
|
||||||
}
|
}
|
||||||
|
|
||||||
return full ? focusedOption : focusedOption.Otherwise;
|
return full ? focusedOption : focusedOption.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
getSubCommand(
|
getSubCommand(
|
||||||
required = true
|
required = true
|
||||||
): (string | CommandInteractionOption[] | undefined)[] {
|
): [string | undefined, DiscordInteractionDataOption[]] {
|
||||||
if (required && !this.#subcommand) {
|
if (required && !this.#subcommand) {
|
||||||
throw new TypeError('Option marked as required was undefined');
|
throw new TypeError('Option marked as required was undefined');
|
||||||
}
|
}
|
||||||
@ -327,7 +258,7 @@ export class CommandInteractionOptionResolver {
|
|||||||
|
|
||||||
getSubCommandGroup(
|
getSubCommandGroup(
|
||||||
required = false
|
required = false
|
||||||
): (string | CommandInteractionOption[] | undefined)[] {
|
): [string | undefined, DiscordInteractionDataOption[]] {
|
||||||
if (required && !this.#group) {
|
if (required && !this.#group) {
|
||||||
throw new TypeError('Option marked as required was undefined');
|
throw new TypeError('Option marked as required was undefined');
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user