mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-01-20 21:41:32 +01:00
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
This commit is contained in:
parent
c47e198664
commit
2444e9be43
@ -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
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -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}*/
|
||||
|
Loading…
Reference in New Issue
Block a user