From 2444e9be43fe2824423716e9ae5c9a34174d70c0 Mon Sep 17 00:00:00 2001 From: Wolfsblvt Date: Sat, 28 Sep 2024 21:59:29 +0200 Subject: [PATCH 1/2] STscript allow named arguments to be an array - Use named args definition and "acceptsMultiple" to build arrays of values, if provided - Add a debug warning if non-multiple named args are provided multiple times --- public/scripts/slash-commands/SlashCommand.js | 4 +- .../slash-commands/SlashCommandClosure.js | 63 +++++++++++++++---- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/public/scripts/slash-commands/SlashCommand.js b/public/scripts/slash-commands/SlashCommand.js index f485e438e..5f8726ba0 100644 --- a/public/scripts/slash-commands/SlashCommand.js +++ b/public/scripts/slash-commands/SlashCommand.js @@ -15,13 +15,13 @@ import { SlashCommandScope } from './SlashCommandScope.js'; * _abortController:SlashCommandAbortController, * _debugController:SlashCommandDebugController, * _hasUnnamedArgument:boolean, - * [id:string]:string|SlashCommandClosure, + * [id:string]:string|SlashCommandClosure|(string|SlashCommandClosure)[], * }} NamedArguments */ /** * Alternative object for local JSDocs, where you don't need existing pipe, scope, etc. arguments - * @typedef {{[id:string]:string|SlashCommandClosure}} NamedArgumentsCapture + * @typedef {{[id:string]:string|SlashCommandClosure|(string|SlashCommandClosure)[]}} NamedArgumentsCapture */ /** diff --git a/public/scripts/slash-commands/SlashCommandClosure.js b/public/scripts/slash-commands/SlashCommandClosure.js index ecf1d968c..97a206138 100644 --- a/public/scripts/slash-commands/SlashCommandClosure.js +++ b/public/scripts/slash-commands/SlashCommandClosure.js @@ -2,6 +2,7 @@ import { substituteParams } from '../../script.js'; import { delay, escapeRegex, uuidv4 } from '../utils.js'; import { SlashCommand } from './SlashCommand.js'; import { SlashCommandAbortController } from './SlashCommandAbortController.js'; +import { SlashCommandNamedArgument } from './SlashCommandArgument.js'; import { SlashCommandBreak } from './SlashCommandBreak.js'; import { SlashCommandBreakController } from './SlashCommandBreakController.js'; import { SlashCommandBreakPoint } from './SlashCommandBreakPoint.js'; @@ -53,7 +54,7 @@ export class SlashCommandClosure { * * @param {string} text * @param {SlashCommandScope} scope - * @returns + * @returns {string|SlashCommandClosure|(string|SlashCommandClosure)[]} */ substituteParams(text, scope = null) { let isList = false; @@ -379,6 +380,52 @@ export class SlashCommandClosure { * @param {import('./SlashCommand.js').NamedArguments} args */ async substituteNamedArguments(executor, args) { + /** + * Handles the assignment of named arguments, considering if they accept multiple values + * @param {string} name The name of the argument, as defined for the command execution + * @param {string|SlashCommandClosure|(string|SlashCommandClosure)[]} value The value to be assigned + */ + const assign = (name, value) => { + // If an array is supposed to be assigned, assign it one by one + if (Array.isArray(value)) { + for (const val of value) { + assign(name, val); + } + return; + } + + const definition = executor.command.namedArgumentList.find(x => x.name == name); + + // Prefer definition name if a valid named args defintion is found + name = definition?.name ?? name; + + // Unescape named argument + if (value && typeof value == 'string') { + value = value + .replace(/\\\{/g, '{') + .replace(/\\\}/g, '}'); + } + + // If the named argument accepts multiple values, we have to make sure to build an array correctly + if (definition?.acceptsMultiple) { + if (args[name] !== undefined) { + // If there already is something for that named arg, make the value is an array and add to it + let currentValue = args[name]; + if (!Array.isArray(currentValue)) { + currentValue = [currentValue]; + } + currentValue.push(value); + args[name] = currentValue; + } else { + // If there is nothing in there, just assign it as singular value, until multiple values are found + args[name] = value; + } + } else { + args[name] !== undefined && console.debug(`Named argument assigned multiple times: ${name}`); + args[name] = value; + } + }; + // substitute named arguments for (const arg of executor.namedArgumentList) { if (arg.value instanceof SlashCommandClosure) { @@ -390,19 +437,12 @@ export class SlashCommandClosure { closure.debugController = this.debugController; } if (closure.executeNow) { - args[arg.name] = (await closure.execute())?.pipe; + assign(arg.name, (await closure.execute())?.pipe); } else { - args[arg.name] = closure; + assign(arg.name, closure); } } else { - args[arg.name] = this.substituteParams(arg.value); - } - // unescape named argument - if (typeof args[arg.name] == 'string') { - args[arg.name] = args[arg.name] - ?.replace(/\\\{/g, '{') - ?.replace(/\\\}/g, '}') - ; + assign(arg.name, this.substituteParams(arg.value)); } } } @@ -424,6 +464,7 @@ export class SlashCommandClosure { } else { value = []; for (let i = 0; i < executor.unnamedArgumentList.length; i++) { + /** @type {string|SlashCommandClosure|(string|SlashCommandClosure)[]} */ let v = executor.unnamedArgumentList[i].value; if (v instanceof SlashCommandClosure) { /**@type {SlashCommandClosure}*/ From d231b7f5f4bdcad0d4b3c341d5c59f7477856b0c Mon Sep 17 00:00:00 2001 From: Wolfsblvt Date: Sat, 28 Sep 2024 22:14:33 +0200 Subject: [PATCH 2/2] "acceptsMultiple" should always return array --- public/scripts/slash-commands/SlashCommandClosure.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/scripts/slash-commands/SlashCommandClosure.js b/public/scripts/slash-commands/SlashCommandClosure.js index 97a206138..45c4d48ba 100644 --- a/public/scripts/slash-commands/SlashCommandClosure.js +++ b/public/scripts/slash-commands/SlashCommandClosure.js @@ -417,8 +417,8 @@ export class SlashCommandClosure { currentValue.push(value); args[name] = currentValue; } else { - // If there is nothing in there, just assign it as singular value, until multiple values are found - args[name] = value; + // If there is nothing in there, we create an array with that singular value + args[name] = [value]; } } else { args[name] !== undefined && console.debug(`Named argument assigned multiple times: ${name}`);