Files
discordeno/packages/bot/src/commandOptionsParser.ts
T
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

129 lines
5.2 KiB
TypeScript

import { ApplicationCommandOptionTypes } from '@discordeno/types';
import type { CompleteDesiredProperties, DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from './desiredProperties.js';
import type { Attachment, Channel, Interaction, InteractionDataOption, Member, Role, User } from './transformers/types.js';
export function commandOptionsParser<
TProps extends TransformersDesiredProperties & { interaction: { data: true } },
TBehavior extends DesiredPropertiesBehavior,
>(__interaction: SetupDesiredProps<Interaction, TProps, TBehavior>, options?: InteractionDataOption[]): ParsedInteractionOption<TProps, TBehavior> {
// This is necessary as typescript gets really confused when using __interaction alone, as it will say that 'data' does not exist despite it surely exist since we have the &
const interaction = __interaction as SetupDesiredProps<
Interaction,
CompleteDesiredProperties<{ interaction: { data: true } }>,
DesiredPropertiesBehavior.RemoveKey
>;
if (!interaction.data) return {};
if (!options) options = interaction.data.options ?? [];
const args: ParsedInteractionOption<TProps, TBehavior> = {};
for (const option of options) {
switch (option.type) {
case ApplicationCommandOptionTypes.SubCommandGroup:
case ApplicationCommandOptionTypes.SubCommand:
args[option.name] = commandOptionsParser(interaction, option.options) as InteractionResolvedData<TProps, TBehavior>;
break;
case ApplicationCommandOptionTypes.Channel:
args[option.name] = interaction.data.resolved?.channels?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>;
break;
case ApplicationCommandOptionTypes.Role:
args[option.name] = interaction.data.resolved?.roles?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>;
break;
case ApplicationCommandOptionTypes.User:
args[option.name] = {
user: interaction.data.resolved?.users?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>,
member: interaction.data.resolved?.members?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>,
};
break;
case ApplicationCommandOptionTypes.Attachment:
args[option.name] = interaction.data.resolved?.attachments?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>;
break;
case ApplicationCommandOptionTypes.Mentionable:
// Mentionable are roles or users
args[option.name] = (interaction.data.resolved?.roles?.get(BigInt(option.value!)) as ParsedInteractionOption<TProps, TBehavior>[string]) ?? {
user: interaction.data.resolved?.users?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>,
member: interaction.data.resolved?.members?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>,
};
break;
default:
args[option.name] = option.value as InteractionResolvedData<TProps, TBehavior>;
}
}
return args;
}
export interface ParsedInteractionOption<TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior> {
[key: string]: InteractionResolvedData<TProps, TBehavior>;
}
export type InteractionResolvedData<TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior> =
| string
| number
| boolean
| InteractionResolvedDataUser<TProps, TBehavior>
| InteractionResolvedDataChannel<TProps, TBehavior>
| SetupDesiredProps<Role, TProps, TBehavior>
| SetupDesiredProps<Attachment, TProps, TBehavior>
| ParsedInteractionOption<TProps, TBehavior>;
export interface InteractionResolvedDataUser<TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior> {
user: SetupDesiredProps<User, TProps, TBehavior>;
member: InteractionResolvedDataMember<TProps, TBehavior>;
}
export type InteractionResolvedDataChannel<TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior> = Pick<
SetupDesiredProps<Channel, TProps, TBehavior>,
Extract<
keyof SetupDesiredProps<Channel, TProps, TBehavior>,
| 'id'
| 'name'
| 'type'
| 'permissions'
| 'lastMessageId'
| 'lastPinTimestamp'
| 'nsfw'
| 'parentId'
| 'guildId'
| 'flags'
| 'rateLimitPerUser'
| 'topic'
| 'position'
| 'threadMetadata'
>
>;
export type InteractionResolvedDataMember<TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior> = Omit<
SetupDesiredProps<Member, TProps, TBehavior>,
'user' | 'deaf' | 'mute'
>;
/** @deprecated Use {@link InteractionResolvedDataUser} */
export interface InteractionResolvedUser {
user: User;
member: InteractionResolvedMember;
}
/** @deprecated Use {@link InteractionResolvedDataChannel} */
export type InteractionResolvedChannel = Pick<
Channel,
| 'id'
| 'name'
| 'type'
| 'permissions'
| 'lastMessageId'
| 'lastPinTimestamp'
| 'nsfw'
| 'parentId'
| 'guildId'
| 'flags'
| 'rateLimitPerUser'
| 'topic'
| 'position'
| 'threadMetadata'
>;
/** @deprecated Use {@link InteractionResolvedDataMember} */
export type InteractionResolvedMember = Omit<Member, 'user' | 'deaf' | 'mute'>;