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.}*/ variables = {}; // @ts-ignore /**@type {object.}*/ 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 {}