mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
add callable closure vars
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
import { substituteParams } from '../../script.js';
|
||||
import { SlashCommandClosureExecutor } from './SlashCommandClosureExecutor.js';
|
||||
import { SlashCommandClosureResult } from './SlashCommandClosureResult.js';
|
||||
import { SlashCommandExecutor } from './SlashCommandExecutor.js';
|
||||
import { SlashCommandScope } from './SlashCommandScope.js';
|
||||
@ -10,7 +11,7 @@ export class SlashCommandClosure {
|
||||
/**@type {Map<string,string|SlashCommandClosure>}*/ arguments = {};
|
||||
// @ts-ignore
|
||||
/**@type {Map<string,string|SlashCommandClosure>}*/ providedArguments = {};
|
||||
/**@type {SlashCommandExecutor[]}*/ executorList = [];
|
||||
/**@type {(SlashCommandExecutor|SlashCommandClosureExecutor)[]}*/ executorList = [];
|
||||
/**@type {String}*/ keptText;
|
||||
|
||||
constructor(parent) {
|
||||
@ -39,6 +40,10 @@ export class SlashCommandClosure {
|
||||
return closure;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns Promise<SlashCommandClosureResult>
|
||||
*/
|
||||
async execute() {
|
||||
const closure = this.getCopy();
|
||||
return await closure.executeDirect();
|
||||
@ -98,82 +103,94 @@ export class SlashCommandClosure {
|
||||
}
|
||||
|
||||
for (const executor of this.executorList) {
|
||||
interrupt = executor.command.interruptsGeneration;
|
||||
let args = {
|
||||
_scope: this.scope,
|
||||
};
|
||||
let value;
|
||||
// substitute named arguments
|
||||
for (const key of Object.keys(executor.args)) {
|
||||
if (executor.args[key] instanceof SlashCommandClosure) {
|
||||
if (executor instanceof SlashCommandClosureExecutor) {
|
||||
const closure = this.scope.getVariable(executor.name);
|
||||
if (!closure || !(closure instanceof SlashCommandClosure)) throw new Error(`${name} is not a closure.`);
|
||||
closure.scope.parent = this.scope;
|
||||
closure.providedArguments = executor.providedArguments;
|
||||
const result = await closure.execute();
|
||||
this.scope.pipe = result.pipe;
|
||||
interrupt = result.interrupt;
|
||||
} else {
|
||||
interrupt = executor.command.interruptsGeneration;
|
||||
let args = {
|
||||
_scope: this.scope,
|
||||
};
|
||||
let value;
|
||||
// substitute named arguments
|
||||
for (const key of Object.keys(executor.args)) {
|
||||
if (executor.args[key] instanceof SlashCommandClosure) {
|
||||
/**@type {SlashCommandClosure}*/
|
||||
const closure = executor.args[key];
|
||||
closure.scope.parent = this.scope;
|
||||
if (closure.executeNow) {
|
||||
args[key] = (await closure.execute())?.pipe;
|
||||
} else {
|
||||
args[key] = closure;
|
||||
}
|
||||
} else {
|
||||
args[key] = this.substituteParams(executor.args[key]);
|
||||
}
|
||||
// unescape named argument
|
||||
if (typeof args[key] == 'string') {
|
||||
args[key] = args[key]
|
||||
?.replace(/\\\|/g, '|')
|
||||
?.replace(/\\\{/g, '{')
|
||||
?.replace(/\\\}/g, '}')
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// substitute unnamed argument
|
||||
if (executor.value === undefined) {
|
||||
value = this.scope.pipe;
|
||||
} else if (executor.value instanceof SlashCommandClosure) {
|
||||
/**@type {SlashCommandClosure}*/
|
||||
const closure = executor.args[key];
|
||||
const closure = executor.value;
|
||||
closure.scope.parent = this.scope;
|
||||
if (closure.executeNow) {
|
||||
args[key] = (await closure.execute())?.pipe;
|
||||
value = (await closure.execute())?.pipe;
|
||||
} else {
|
||||
args[key] = closure;
|
||||
value = closure;
|
||||
}
|
||||
} else if (Array.isArray(executor.value)) {
|
||||
value = [];
|
||||
for (let i = 0; i < executor.value.length; i++) {
|
||||
let v = executor.value[i];
|
||||
if (v instanceof SlashCommandClosure) {
|
||||
/**@type {SlashCommandClosure}*/
|
||||
const closure = v;
|
||||
closure.scope.parent = this.scope;
|
||||
if (closure.executeNow) {
|
||||
v = (await closure.execute())?.pipe;
|
||||
} else {
|
||||
v = closure;
|
||||
}
|
||||
} else {
|
||||
v = this.substituteParams(v);
|
||||
}
|
||||
value[i] = v;
|
||||
}
|
||||
if (!value.find(it=>it instanceof SlashCommandClosure)) {
|
||||
value = value.join(' ');
|
||||
}
|
||||
} else {
|
||||
args[key] = this.substituteParams(executor.args[key]);
|
||||
value = this.substituteParams(executor.value);
|
||||
}
|
||||
// unescape named argument
|
||||
if (typeof args[key] == 'string') {
|
||||
args[key] = args[key]
|
||||
// unescape unnamed argument
|
||||
if (typeof value == 'string') {
|
||||
value = value
|
||||
?.replace(/\\\|/g, '|')
|
||||
?.replace(/\\\{/g, '{')
|
||||
?.replace(/\\\}/g, '}')
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// substitute unnamed argument
|
||||
if (executor.value === undefined) {
|
||||
value = this.scope.pipe;
|
||||
} else if (executor.value instanceof SlashCommandClosure) {
|
||||
/**@type {SlashCommandClosure}*/
|
||||
const closure = executor.value;
|
||||
closure.scope.parent = this.scope;
|
||||
if (closure.executeNow) {
|
||||
value = (await closure.execute())?.pipe;
|
||||
} else {
|
||||
value = closure;
|
||||
}
|
||||
} else if (Array.isArray(executor.value)) {
|
||||
value = [];
|
||||
for (let i = 0; i < executor.value.length; i++) {
|
||||
let v = executor.value[i];
|
||||
if (v instanceof SlashCommandClosure) {
|
||||
/**@type {SlashCommandClosure}*/
|
||||
const closure = v;
|
||||
closure.scope.parent = this.scope;
|
||||
if (closure.executeNow) {
|
||||
v = (await closure.execute())?.pipe;
|
||||
} else {
|
||||
v = closure;
|
||||
}
|
||||
} else {
|
||||
v = this.substituteParams(v);
|
||||
}
|
||||
value[i] = v;
|
||||
}
|
||||
if (!value.find(it=>it instanceof SlashCommandClosure)) {
|
||||
value = value.join(' ');
|
||||
}
|
||||
} else {
|
||||
value = this.substituteParams(executor.value);
|
||||
this.scope.pipe = await executor.command.callback(args, value);
|
||||
}
|
||||
// unescape unnamed argument
|
||||
if (typeof value == 'string') {
|
||||
value = value
|
||||
?.replace(/\\\|/g, '|')
|
||||
?.replace(/\\\{/g, '{')
|
||||
?.replace(/\\\}/g, '}')
|
||||
;
|
||||
}
|
||||
|
||||
this.scope.pipe = await executor.command.callback(args, value);
|
||||
}
|
||||
return Object.assign(new SlashCommandClosureResult(), { interrupt, newText: this.keptText, pipe: this.scope.pipe });
|
||||
/**@type {SlashCommandClosureResult} */
|
||||
const result = Object.assign(new SlashCommandClosureResult(), { interrupt, newText: this.keptText, pipe: this.scope.pipe });
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user