From d2eadc7f031835b3bb5245c679d6658b6bb6d640 Mon Sep 17 00:00:00 2001 From: Puechberty Arthur Date: Sun, 12 Apr 2026 13:36:58 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20ajouter=20la=20gestion=20des=20erreurs?= =?UTF-8?q?=20pour=20trop=20d'arguments=20et=20mise=20=C3=A0=20jour=20des?= =?UTF-8?q?=20commandes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/en.json | 3 ++- locales/es.json | 3 ++- locales/fr.json | 3 ++- src/commands/utility/advanced.ts | 14 ++++++------- src/framework/commands/argParser.ts | 10 +++++++++ src/framework/commands/defineCommand.ts | 27 +++++++++++++++++-------- 6 files changed, 42 insertions(+), 18 deletions(-) diff --git a/locales/en.json b/locales/en.json index 6241eb0..f6f4213 100644 --- a/locales/en.json +++ b/locales/en.json @@ -5,7 +5,8 @@ "invalidInt": "Argument must be an integer. Received: {{value}}", "invalidNumber": "Argument must be a number. Received: {{value}}", "invalidBoolean": "Argument must be a boolean value. Received: {{value}}", - "invalidUser": "Could not resolve a user from {{value}}" + "invalidUser": "Could not resolve a user from {{value}}", + "tooMany": "Too many arguments detected ({{count}}): {{extras}}. Usage: {{usage}}" }, "permissions": { "user": "You are missing permissions: {{permissions}}" diff --git a/locales/es.json b/locales/es.json index d4412b7..c9f7a5f 100644 --- a/locales/es.json +++ b/locales/es.json @@ -5,7 +5,8 @@ "invalidInt": "El argumento debe ser un entero. Recibido: {{value}}", "invalidNumber": "El argumento debe ser un numero. Recibido: {{value}}", "invalidBoolean": "El argumento debe ser un valor booleano. Recibido: {{value}}", - "invalidUser": "No se pudo resolver un usuario desde {{value}}" + "invalidUser": "No se pudo resolver un usuario desde {{value}}", + "tooMany": "Se detectaron demasiados argumentos ({{count}}): {{extras}}. Uso: {{usage}}" }, "permissions": { "user": "Te faltan permisos: {{permissions}}" diff --git a/locales/fr.json b/locales/fr.json index a49c4d3..da49567 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -5,7 +5,8 @@ "invalidInt": "L argument doit etre un entier. Recu: {{value}}", "invalidNumber": "L argument doit etre un nombre. Recu: {{value}}", "invalidBoolean": "L argument doit etre un booleen. Recu: {{value}}", - "invalidUser": "Impossible de trouver un utilisateur depuis {{value}}" + "invalidUser": "Impossible de trouver un utilisateur depuis {{value}}", + "tooMany": "Trop d arguments ({{count}}) detectes: {{extras}}. Usage: {{usage}}" }, "permissions": { "user": "Tu n as pas les permissions: {{permissions}}" diff --git a/src/commands/utility/advanced.ts b/src/commands/utility/advanced.ts index fe25166..f82cc3b 100644 --- a/src/commands/utility/advanced.ts +++ b/src/commands/utility/advanced.ts @@ -43,6 +43,12 @@ export const advancedCommand = defineCommand({ required: true, descriptionKey: "args.count", }, + { + name: "user", + type: "user", + required: true, + descriptionKey: "args.user", + }, { name: "ratio", type: "number", @@ -55,12 +61,6 @@ export const advancedCommand = defineCommand({ required: false, descriptionKey: "args.enabled", }, - { - name: "user", - type: "user", - required: true, - descriptionKey: "args.user", - }, { name: "channel", type: "channel", @@ -76,7 +76,7 @@ export const advancedCommand = defineCommand({ ], examples: [ { - args: '"hello world" 5 1.5 true @Arthur #general @Moderators', + args: '"hello world" 5 @Arthur 1.5 true #general @Moderators', descriptionKey: "examples.full", }, { diff --git a/src/framework/commands/argParser.ts b/src/framework/commands/argParser.ts index 7b9cd2d..6699177 100644 --- a/src/framework/commands/argParser.ts +++ b/src/framework/commands/argParser.ts @@ -59,6 +59,16 @@ export const parsePrefixArgs = async ( errors.push(parsed.error); } + if (tokens.length > 0) { + errors.push({ + key: "errors.args.tooMany", + vars: { + count: tokens.length, + extras: tokens.join(" "), + }, + }); + } + return { values, errors }; }; diff --git a/src/framework/commands/defineCommand.ts b/src/framework/commands/defineCommand.ts index d1c4bd8..b95fea2 100644 --- a/src/framework/commands/defineCommand.ts +++ b/src/framework/commands/defineCommand.ts @@ -1,18 +1,29 @@ import type { BotCommand, BotCommandInput } from "../types/command.js"; -export const defineCommand = (input: BotCommandInput): BotCommand => { - // Discord requires all required slash options before any optional ones. - const normalizedArgs = [...(input.args ?? [])].sort((a, b) => { - if (a.required === b.required) { - return 0; +const assertRequiredArgsBeforeOptional = (input: BotCommandInput): void => { + const args = input.args ?? []; + let firstOptionalArgName: string | null = null; + + for (const arg of args) { + if (!arg.required) { + firstOptionalArgName ??= arg.name; + continue; } - return a.required ? -1 : 1; - }); + if (firstOptionalArgName) { + throw new Error( + `Invalid argument order for command "${input.meta.name}": required argument "${arg.name}" cannot appear after optional argument "${firstOptionalArgName}". Declare all required arguments before optional ones.`, + ); + } + } +}; + +export const defineCommand = (input: BotCommandInput): BotCommand => { + assertRequiredArgsBeforeOptional(input); return { meta: input.meta, - args: normalizedArgs, + args: [...(input.args ?? [])], permissions: input.permissions ?? [], examples: input.examples ?? [], execute: input.execute,