mirror of
				https://github.com/SillyTavern/SillyTavern.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			118 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { SlashCommandClosure } from './SlashCommandClosure.js';
 | |
| import { convertValueType } from '../utils.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, overwrite = true) {
 | |
|         if (overwrite || !this.macroList.find(it=>it.key == key)) {
 | |
|             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, type = 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] = convertValueType(value, type);
 | |
|                     } else {
 | |
|                         v[numIndex] = convertValueType(value, type);
 | |
|                     }
 | |
|                     v = JSON.stringify(v);
 | |
|                 } catch {
 | |
|                     v[index] = convertValueType(value, type);
 | |
|                 }
 | |
|                 this.variables[key] = v;
 | |
|             } else {
 | |
|                 this.variables[key] = value;
 | |
|             }
 | |
|             return value;
 | |
|         }
 | |
|         if (this.parent) {
 | |
|             return this.parent.setVariable(key, value, index, type);
 | |
|         }
 | |
|         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?.trim?.() === '' || 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 {}
 |