fix: handle correctly options

This commit is contained in:
MARCROCK22 2024-10-26 22:27:01 +00:00
parent b1e66f05dc
commit c6a2b955b1
3 changed files with 104 additions and 107 deletions

View File

@ -54,10 +54,11 @@ export type MessageCommandOptionErrors =
| ['STRING_MIN_LENGTH', min: number] | ['STRING_MIN_LENGTH', min: number]
| ['STRING_MAX_LENGTH', max: number] | ['STRING_MAX_LENGTH', max: number]
| ['STRING_INVALID_CHOICE', choices: readonly { name: string; value: string }[]] | ['STRING_INVALID_CHOICE', choices: readonly { name: string; value: string }[]]
| ['NUMBER_NAN', value: string | undefined] | ['NUMBER_NAN', value: string]
| ['NUMBER_MIN_VALUE', min: number] | ['NUMBER_MIN_VALUE', min: number]
| ['NUMBER_MAX_VALUE', max: number] | ['NUMBER_MAX_VALUE', max: number]
| ['NUMBER_INVALID_CHOICE', choices: readonly { name: string; value: number }[]] | ['NUMBER_INVALID_CHOICE', choices: readonly { name: string; value: number }[]]
| ['NUMBER_OUT_OF_BOUNDS', value: number]
| ['OPTION_REQUIRED'] | ['OPTION_REQUIRED']
| ['UNKNOWN', error: unknown]; | ['UNKNOWN', error: unknown];

View File

@ -22,6 +22,7 @@ import {
import type { Client, WorkerClient } from '../client'; import type { Client, WorkerClient } from '../client';
import { type MessageStructure, type OptionResolverStructure, Transformers } from '../client/transformers'; import { type MessageStructure, type OptionResolverStructure, Transformers } from '../client/transformers';
import type { MakeRequired } from '../common'; import type { MakeRequired } from '../common';
import { INTEGER_OPTION_VALUE_LIMIT } from '../common/it/constants';
import { ComponentContext, ModalContext } from '../components'; import { ComponentContext, ModalContext } from '../components';
import { import {
AutocompleteInteraction, AutocompleteInteraction,
@ -635,7 +636,7 @@ export class HandleCommand {
async argsOptionsParser( async argsOptionsParser(
command: Command | SubCommand, command: Command | SubCommand,
message: GatewayMessageCreateDispatchData, message: GatewayMessageCreateDispatchData,
args: Partial<Record<string, string>>, args: Record<string, string>,
resolved: MakeRequired<ContextOptionsResolved>, resolved: MakeRequired<ContextOptionsResolved>,
) { ) {
const options: APIApplicationCommandInteractionDataOption[] = []; const options: APIApplicationCommandInteractionDataOption[] = [];
@ -649,6 +650,7 @@ export class HandleCommand {
type: ApplicationCommandOptionType; type: ApplicationCommandOptionType;
})[]) { })[]) {
try { try {
if (!args[i.name] && i.type !== ApplicationCommandOptionType.Attachment) continue;
let value: string | boolean | number | undefined; let value: string | boolean | number | undefined;
switch (i.type) { switch (i.type) {
case ApplicationCommandOptionType.Attachment: case ApplicationCommandOptionType.Attachment:
@ -658,9 +660,7 @@ export class HandleCommand {
} }
break; break;
case ApplicationCommandOptionType.Boolean: case ApplicationCommandOptionType.Boolean:
if (args[i.name]) { value = ['yes', 'y', 'true', 'treu'].includes(args[i.name].toLowerCase());
value = ['yes', 'y', 'true', 'treu'].includes(args[i.name]!.toLowerCase());
}
break; break;
case ApplicationCommandOptionType.Channel: case ApplicationCommandOptionType.Channel:
{ {
@ -670,24 +670,22 @@ export class HandleCommand {
if (!rawQuery) continue; if (!rawQuery) continue;
const channel = const channel =
(await this.client.cache.channels?.raw(rawQuery)) ?? (await this.fetchChannel(i, rawQuery)); (await this.client.cache.channels?.raw(rawQuery)) ?? (await this.fetchChannel(i, rawQuery));
if (channel) { if (!channel) break;
if ('channel_types' in i) { if ('channel_types' in i) {
if (!(i as SeyfertChannelOption).channel_types!.includes(channel.type)) { if (!(i as SeyfertChannelOption).channel_types!.includes(channel.type)) {
if (i.required) errors.push({
errors.push({ name: i.name,
name: i.name, error: `The entered channel type is not one of ${(i as SeyfertChannelOption)
error: `The entered channel type is not one of ${(i as SeyfertChannelOption) .channel_types!.map(t => ChannelType[t])
.channel_types!.map(t => ChannelType[t]) .join(', ')}`,
.join(', ')}`, fullError: ['CHANNEL_TYPES', (i as SeyfertChannelOption).channel_types!],
fullError: ['CHANNEL_TYPES', (i as SeyfertChannelOption).channel_types!], });
}); break;
break;
}
} }
value = channel.id;
//discord funny memoentnt!!!!!!!!
resolved.channels[channel.id] = channel as APIInteractionDataResolvedChannel;
} }
value = channel.id;
//discord funny memoentnt!!!!!!!!
resolved.channels[channel.id] = channel as APIInteractionDataResolvedChannel;
} }
break; break;
case ApplicationCommandOptionType.Mentionable: case ApplicationCommandOptionType.Mentionable:
@ -754,115 +752,111 @@ export class HandleCommand {
break; break;
case ApplicationCommandOptionType.String: case ApplicationCommandOptionType.String:
{ {
value = args[i.name];
const option = i as SeyfertStringOption; const option = i as SeyfertStringOption;
if (!value) break;
if (option.min_length) {
if (value.length < option.min_length) {
value = undefined;
if (i.required)
errors.push({
name: i.name,
error: `The entered string has less than ${option.min_length} characters. The minimum required is ${option.min_length} characters.`,
fullError: ['STRING_MIN_LENGTH', option.min_length],
});
break;
}
}
if (option.max_length) {
if (value.length > option.max_length) {
value = undefined;
if (i.required)
errors.push({
name: i.name,
error: `The entered string has more than ${option.max_length} characters. The maximum required is ${option.max_length} characters.`,
fullError: ['STRING_MAX_LENGTH', option.max_length],
});
break;
}
}
if (option.choices?.length) { if (option.choices?.length) {
const choice = option.choices.find(x => x.name === value); const choice = option.choices.find(x => x.name === args[i.name]);
if (!choice) { if (!choice) {
value = undefined; errors.push({
if (i.required) name: i.name,
errors.push({ error: `The entered choice is invalid. Please choose one of the following options: ${option.choices
name: i.name, .map(x => x.name)
error: `The entered choice is invalid. Please choose one of the following options: ${option.choices .join(', ')}`,
.map(x => x.name) fullError: ['STRING_INVALID_CHOICE', option.choices],
.join(', ')}.`, });
fullError: ['STRING_INVALID_CHOICE', option.choices],
});
break; break;
} }
value = choice.value; value = choice.value;
break;
} }
if (option.min_length !== undefined) {
if (args[i.name].length < option.min_length) {
errors.push({
name: i.name,
error: `The entered string has less than ${option.min_length} characters. The minimum required is ${option.min_length} characters`,
fullError: ['STRING_MIN_LENGTH', option.min_length],
});
break;
}
}
if (option.max_length !== undefined) {
if (args[i.name].length > option.max_length) {
errors.push({
name: i.name,
error: `The entered string has more than ${option.max_length} characters. The maximum required is ${option.max_length} characters`,
fullError: ['STRING_MAX_LENGTH', option.max_length],
});
break;
}
}
value = args[i.name];
} }
break; break;
case ApplicationCommandOptionType.Number: case ApplicationCommandOptionType.Number:
case ApplicationCommandOptionType.Integer: case ApplicationCommandOptionType.Integer:
{ {
const option = i as SeyfertNumberOption | SeyfertIntegerOption; const option = i as SeyfertNumberOption | SeyfertIntegerOption;
if (!option.choices?.length) { if (option.choices?.length) {
value = Number(args[i.name]); const choice = option.choices.find(x => x.name === args[i.name]);
if (args[i.name] === undefined) { if (!choice) {
value = undefined;
break;
}
if (Number.isNaN(value)) {
value = undefined;
if (i.required)
errors.push({
name: i.name,
error: 'The entered choice is an invalid number.',
fullError: ['NUMBER_NAN', args[i.name]],
});
break;
}
if (option.min_value) {
if (value < option.min_value) {
value = undefined;
if (i.required)
errors.push({
name: i.name,
error: `The entered number is less than ${option.min_value}. The minimum allowed is ${option.min_value}`,
fullError: ['NUMBER_MIN_VALUE', option.min_value],
});
break;
}
}
if (option.max_value) {
if (value > option.max_value) {
value = undefined;
if (i.required)
errors.push({
name: i.name,
error: `The entered number is greater than ${option.max_value}. The maximum allowed is ${option.max_value}`,
fullError: ['NUMBER_MAX_VALUE', option.max_value],
});
break;
}
}
break;
}
const choice = option.choices.find(x => x.name === args[i.name]);
if (!choice) {
value = undefined;
if (i.required)
errors.push({ errors.push({
name: i.name, name: i.name,
error: `The entered choice is invalid. Please choose one of the following options: ${option.choices error: `The entered choice is invalid. Please choose one of the following options: ${option.choices
.map(x => x.name) .map(x => x.name)
.join(', ')}.`, .join(', ')}`,
fullError: ['NUMBER_INVALID_CHOICE', option.choices], fullError: ['NUMBER_INVALID_CHOICE', option.choices],
}); });
break;
}
value = choice.value;
break;
}
value =
i.type === ApplicationCommandOptionType.Integer
? Math.trunc(Number(args[i.name]))
: Number(args[i.name]);
if (Number.isNaN(value)) {
value = undefined;
errors.push({
name: i.name,
error: 'The entered choice is an invalid number',
fullError: ['NUMBER_NAN', args[i.name]],
});
break;
}
if (value <= -INTEGER_OPTION_VALUE_LIMIT || value >= INTEGER_OPTION_VALUE_LIMIT) {
value = undefined;
errors.push({
name: i.name,
error: 'The entered number must be between -2^53 and 2^53',
fullError: ['NUMBER_OUT_OF_BOUNDS', INTEGER_OPTION_VALUE_LIMIT],
});
break;
}
if (option.min_value !== undefined) {
if (value < option.min_value) {
value = undefined;
errors.push({
name: i.name,
error: `The entered number is less than ${option.min_value}. The minimum allowed is ${option.min_value}`,
fullError: ['NUMBER_MIN_VALUE', option.min_value],
});
break;
}
}
if (option.max_value !== undefined) {
if (value > option.max_value) {
value = undefined;
errors.push({
name: i.name,
error: `The entered number is greater than ${option.max_value}. The maximum allowed is ${option.max_value}`,
fullError: ['NUMBER_MAX_VALUE', option.max_value],
});
break;
}
break; break;
} }
value = choice.value;
} }
break; break;
default:
break;
} }
if (value !== undefined) { if (value !== undefined) {
options.push({ options.push({

View File

@ -38,3 +38,5 @@ export const DiscordEpoch = 1420070400000n;
export const BASE_HOST = 'https://discord.com'; export const BASE_HOST = 'https://discord.com';
export const BASE_URL = `${BASE_HOST}/api`; export const BASE_URL = `${BASE_HOST}/api`;
export const CDN_URL = 'https://cdn.discordapp.com'; export const CDN_URL = 'https://cdn.discordapp.com';
export const INTEGER_OPTION_VALUE_LIMIT = 2 ** 53;