From c6a2b955b181f36765707baee6dd4e160c51f0d5 Mon Sep 17 00:00:00 2001 From: MARCROCK22 Date: Sat, 26 Oct 2024 22:27:01 +0000 Subject: [PATCH] fix: handle correctly options --- src/commands/applications/shared.ts | 3 +- src/commands/handle.ts | 194 ++++++++++++++-------------- src/common/it/constants.ts | 2 + 3 files changed, 98 insertions(+), 101 deletions(-) diff --git a/src/commands/applications/shared.ts b/src/commands/applications/shared.ts index 44bf1255..a89d8402 100644 --- a/src/commands/applications/shared.ts +++ b/src/commands/applications/shared.ts @@ -54,10 +54,11 @@ export type MessageCommandOptionErrors = | ['STRING_MIN_LENGTH', min: number] | ['STRING_MAX_LENGTH', max: number] | ['STRING_INVALID_CHOICE', choices: readonly { name: string; value: string }[]] - | ['NUMBER_NAN', value: string | undefined] + | ['NUMBER_NAN', value: string] | ['NUMBER_MIN_VALUE', min: number] | ['NUMBER_MAX_VALUE', max: number] | ['NUMBER_INVALID_CHOICE', choices: readonly { name: string; value: number }[]] + | ['NUMBER_OUT_OF_BOUNDS', value: number] | ['OPTION_REQUIRED'] | ['UNKNOWN', error: unknown]; diff --git a/src/commands/handle.ts b/src/commands/handle.ts index 8558b7dc..f117e3da 100644 --- a/src/commands/handle.ts +++ b/src/commands/handle.ts @@ -22,6 +22,7 @@ import { import type { Client, WorkerClient } from '../client'; import { type MessageStructure, type OptionResolverStructure, Transformers } from '../client/transformers'; import type { MakeRequired } from '../common'; +import { INTEGER_OPTION_VALUE_LIMIT } from '../common/it/constants'; import { ComponentContext, ModalContext } from '../components'; import { AutocompleteInteraction, @@ -635,7 +636,7 @@ export class HandleCommand { async argsOptionsParser( command: Command | SubCommand, message: GatewayMessageCreateDispatchData, - args: Partial>, + args: Record, resolved: MakeRequired, ) { const options: APIApplicationCommandInteractionDataOption[] = []; @@ -649,6 +650,7 @@ export class HandleCommand { type: ApplicationCommandOptionType; })[]) { try { + if (!args[i.name] && i.type !== ApplicationCommandOptionType.Attachment) continue; let value: string | boolean | number | undefined; switch (i.type) { case ApplicationCommandOptionType.Attachment: @@ -658,9 +660,7 @@ export class HandleCommand { } break; 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; case ApplicationCommandOptionType.Channel: { @@ -670,24 +670,22 @@ export class HandleCommand { if (!rawQuery) continue; const channel = (await this.client.cache.channels?.raw(rawQuery)) ?? (await this.fetchChannel(i, rawQuery)); - if (channel) { - if ('channel_types' in i) { - if (!(i as SeyfertChannelOption).channel_types!.includes(channel.type)) { - if (i.required) - errors.push({ - name: i.name, - error: `The entered channel type is not one of ${(i as SeyfertChannelOption) - .channel_types!.map(t => ChannelType[t]) - .join(', ')}`, - fullError: ['CHANNEL_TYPES', (i as SeyfertChannelOption).channel_types!], - }); - break; - } + if (!channel) break; + if ('channel_types' in i) { + if (!(i as SeyfertChannelOption).channel_types!.includes(channel.type)) { + errors.push({ + name: i.name, + error: `The entered channel type is not one of ${(i as SeyfertChannelOption) + .channel_types!.map(t => ChannelType[t]) + .join(', ')}`, + fullError: ['CHANNEL_TYPES', (i as SeyfertChannelOption).channel_types!], + }); + 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; case ApplicationCommandOptionType.Mentionable: @@ -754,115 +752,111 @@ export class HandleCommand { break; case ApplicationCommandOptionType.String: { - value = args[i.name]; 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], - }); + if (option.choices?.length) { + const choice = option.choices.find(x => x.name === args[i.name]); + if (!choice) { + errors.push({ + name: i.name, + error: `The entered choice is invalid. Please choose one of the following options: ${option.choices + .map(x => x.name) + .join(', ')}`, + fullError: ['STRING_INVALID_CHOICE', option.choices], + }); break; } + value = choice.value; + 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], - }); + 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.choices?.length) { - const choice = option.choices.find(x => x.name === value); - if (!choice) { - value = undefined; - if (i.required) - errors.push({ - name: i.name, - error: `The entered choice is invalid. Please choose one of the following options: ${option.choices - .map(x => x.name) - .join(', ')}.`, - fullError: ['STRING_INVALID_CHOICE', option.choices], - }); + 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 = choice.value; } + value = args[i.name]; } break; case ApplicationCommandOptionType.Number: case ApplicationCommandOptionType.Integer: { const option = i as SeyfertNumberOption | SeyfertIntegerOption; - if (!option.choices?.length) { - value = Number(args[i.name]); - if (args[i.name] === undefined) { - value = undefined; + if (option.choices?.length) { + const choice = option.choices.find(x => x.name === args[i.name]); + if (!choice) { + errors.push({ + name: i.name, + error: `The entered choice is invalid. Please choose one of the following options: ${option.choices + .map(x => x.name) + .join(', ')}`, + fullError: ['NUMBER_INVALID_CHOICE', option.choices], + }); break; } - if (Number.isNaN(value)) { + 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; - if (i.required) - errors.push({ - name: i.name, - error: 'The entered choice is an invalid number.', - fullError: ['NUMBER_NAN', args[i.name]], - }); + 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.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) + if (option.max_value !== undefined) { + if (value > option.max_value) { + value = undefined; errors.push({ name: i.name, - error: `The entered choice is invalid. Please choose one of the following options: ${option.choices - .map(x => x.name) - .join(', ')}.`, - fullError: ['NUMBER_INVALID_CHOICE', option.choices], + 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; } - value = choice.value; } break; - default: - break; } if (value !== undefined) { options.push({ diff --git a/src/common/it/constants.ts b/src/common/it/constants.ts index 4b26041e..38b777b7 100644 --- a/src/common/it/constants.ts +++ b/src/common/it/constants.ts @@ -38,3 +38,5 @@ export const DiscordEpoch = 1420070400000n; export const BASE_HOST = 'https://discord.com'; export const BASE_URL = `${BASE_HOST}/api`; export const CDN_URL = 'https://cdn.discordapp.com'; + +export const INTEGER_OPTION_VALUE_LIMIT = 2 ** 53;