mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2024-12-13 18:07:20 +01:00
5cb319771d
* set pipe to empty string on empty closure * fix missing parser flags and scope * add closure serializing * add enum provider function to slash command arguments * add enum providers for /bg, /ask, and /go * fix index out of bounds returning undefined * keep whitespace as is in mixed unnamed args (string+closure) * add _hasUnnamedArgument to named arguments dictionary * allow /var key=x retrieval * add enum provider to /tag-add * fix typo (case) * add option to make enum matching optional * add executor to enum provider * change /tag-add enum provider to only show tags not already assigned * add enum provider to /tag-remove * fix name enum provider excluding groups * remove void from slash command callback return types * Lint undefined and null pipes * enable pointer events in chat autocomplete * fix type hint --------- Co-authored-by: LenAnderson <Anderson.Len@outlook.com> Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
115 lines
3.8 KiB
JavaScript
115 lines
3.8 KiB
JavaScript
import { SlashCommandClosure } from './SlashCommandClosure.js';
|
|
|
|
export class SlashCommandScope {
|
|
/**@type {string[]}*/ variableNames = [];
|
|
get allVariableNames() {
|
|
const names = [...this.variableNames, ...(this.parent?.allVariableNames ?? [])];
|
|
return names.filter((it,idx)=>idx == names.indexOf(it));
|
|
}
|
|
// @ts-ignore
|
|
/**@type {object.<string, string|SlashCommandClosure>}*/ variables = {};
|
|
// @ts-ignore
|
|
/**@type {object.<string, string|SlashCommandClosure>}*/ macros = {};
|
|
/**@type {{key:string, value:string|SlashCommandClosure}[]} */
|
|
get macroList() {
|
|
return [...Object.keys(this.macros).map(key=>({ key, value:this.macros[key] })), ...(this.parent?.macroList ?? [])];
|
|
}
|
|
/**@type {SlashCommandScope}*/ parent;
|
|
/**@type {string}*/ #pipe;
|
|
get pipe() {
|
|
return this.#pipe ?? this.parent?.pipe;
|
|
}
|
|
set pipe(value) {
|
|
this.#pipe = value;
|
|
}
|
|
|
|
|
|
constructor(parent) {
|
|
this.parent = parent;
|
|
}
|
|
|
|
getCopy() {
|
|
const scope = new SlashCommandScope(this.parent);
|
|
scope.variableNames = [...this.variableNames];
|
|
scope.variables = Object.assign({}, this.variables);
|
|
scope.macros = Object.assign({}, this.macros);
|
|
scope.#pipe = this.#pipe;
|
|
return scope;
|
|
}
|
|
|
|
|
|
setMacro(key, value) {
|
|
this.macros[key] = value;
|
|
}
|
|
|
|
|
|
existsVariableInScope(key) {
|
|
return Object.keys(this.variables).includes(key);
|
|
}
|
|
existsVariable(key) {
|
|
return Object.keys(this.variables).includes(key) || this.parent?.existsVariable(key);
|
|
}
|
|
letVariable(key, value = undefined) {
|
|
if (this.existsVariableInScope(key)) throw new SlashCommandScopeVariableExistsError(`Variable named "${key}" already exists.`);
|
|
this.variables[key] = value;
|
|
}
|
|
setVariable(key, value, index = null) {
|
|
if (this.existsVariableInScope(key)) {
|
|
if (index !== null && index !== undefined) {
|
|
let v = this.variables[key];
|
|
try {
|
|
v = JSON.parse(v);
|
|
const numIndex = Number(index);
|
|
if (Number.isNaN(numIndex)) {
|
|
v[index] = value;
|
|
} else {
|
|
v[numIndex] = value;
|
|
}
|
|
v = JSON.stringify(v);
|
|
} catch {
|
|
v[index] = value;
|
|
}
|
|
this.variables[key] = v;
|
|
} else {
|
|
this.variables[key] = value;
|
|
}
|
|
return value;
|
|
}
|
|
if (this.parent) {
|
|
return this.parent.setVariable(key, value, index);
|
|
}
|
|
throw new SlashCommandScopeVariableNotFoundError(`No such variable: "${key}"`);
|
|
}
|
|
getVariable(key, index = null) {
|
|
if (this.existsVariableInScope(key)) {
|
|
if (index !== null && index !== undefined) {
|
|
let v = this.variables[key];
|
|
try { v = JSON.parse(v); } catch { /* empty */ }
|
|
const numIndex = Number(index);
|
|
if (Number.isNaN(numIndex)) {
|
|
v = v[index];
|
|
} else {
|
|
v = v[numIndex];
|
|
}
|
|
if (typeof v == 'object') return JSON.stringify(v);
|
|
return v ?? '';
|
|
} else {
|
|
const value = this.variables[key];
|
|
return (value === '' || isNaN(Number(value))) ? (value || '') : Number(value);
|
|
}
|
|
}
|
|
if (this.parent) {
|
|
return this.parent.getVariable(key, index);
|
|
}
|
|
throw new SlashCommandScopeVariableNotFoundError(`No such variable: "${key}"`);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
export class SlashCommandScopeVariableExistsError extends Error {}
|
|
|
|
|
|
export class SlashCommandScopeVariableNotFoundError extends Error {}
|