Blame Raw
Cohee · e3f41666 · · 115 lines (4.0 KB)
1 contributor
1import { SlashCommandClosure } from './SlashCommandClosure.js';
2import { convertValueType } from '../utils.js';
3
4export class SlashCommandScope {
5 /** @type {string[]} */ variableNames = [];
6 get allVariableNames() {
7 const names = [...this.variableNames, ...(this.parent?.allVariableNames ?? [])];
8 return names.filter((it, idx) => idx == names.indexOf(it));
9 }
10 // @ts-ignore
11 /** @type {object.<string, string|SlashCommandClosure>} */ variables = {};
12 // @ts-ignore
13 /** @type {object.<string, string|SlashCommandClosure>} */ macros = {};
14 /** @type {{key:string, value:string|SlashCommandClosure}[]} */
15 get macroList() {
16 return [...Object.keys(this.macros).map(key => ({ key, value: this.macros[key] })), ...(this.parent?.macroList ?? [])];
17 }
18 /** @type {SlashCommandScope} */ parent;
19 /** @type {string} */ #pipe;
20 get pipe() {
21 return this.#pipe ?? this.parent?.pipe;
22 }
23 set pipe(value) {
24 this.#pipe = value;
25 }
26
27
28 constructor(parent) {
29 this.parent = parent;
30 }
31
32 getCopy() {
33 const scope = new SlashCommandScope(this.parent);
34 scope.variableNames = [...this.variableNames];
35 scope.variables = Object.assign({}, this.variables);
36 scope.macros = Object.assign({}, this.macros);
37 scope.#pipe = this.#pipe;
38 return scope;
39 }
40
41
42 setMacro(key, value, overwrite = true) {
43 if (overwrite || !this.macroList.find(it => it.key == key)) {
44 this.macros[key] = value;
45 }
46 }
47
48
49 existsVariableInScope(key) {
50 return Object.keys(this.variables).includes(key);
51 }
52 existsVariable(key) {
53 return Object.keys(this.variables).includes(key) || this.parent?.existsVariable(key);
54 }
55 letVariable(key, value = undefined) {
56 if (this.existsVariableInScope(key)) throw new SlashCommandScopeVariableExistsError(`Variable named "${key}" already exists.`);
57 this.variables[key] = value;
58 }
59 setVariable(key, value, index = null, type = null) {
60 if (this.existsVariableInScope(key)) {
61 if (index !== null && index !== undefined) {
62 let v = this.variables[key];
63 try {
64 v = JSON.parse(v);
65 const numIndex = Number(index);
66 if (Number.isNaN(numIndex)) {
67 v[index] = convertValueType(value, type);
68 } else {
69 v[numIndex] = convertValueType(value, type);
70 }
71 v = JSON.stringify(v);
72 } catch {
73 v[index] = convertValueType(value, type);
74 }
75 this.variables[key] = v;
76 } else {
77 this.variables[key] = value;
78 }
79 return value;
80 }
81 if (this.parent) {
82 return this.parent.setVariable(key, value, index, type);
83 }
84 throw new SlashCommandScopeVariableNotFoundError(`No such variable: "${key}"`);
85 }
86 getVariable(key, index = null) {
87 if (this.existsVariableInScope(key)) {
88 if (index !== null && index !== undefined) {
89 let v = this.variables[key];
90 try { v = JSON.parse(v); } catch { /* empty */ }
91 const numIndex = Number(index);
92 if (Number.isNaN(numIndex)) {
93 v = v[index];
94 } else {
95 v = v[numIndex];
96 }
97 if (typeof v == 'object') return JSON.stringify(v);
98 return v ?? '';
99 } else {
100 const value = this.variables[key];
101 return (value?.trim?.() === '' || isNaN(Number(value))) ? (value || '') : Number(value);
102 }
103 }
104 if (this.parent) {
105 return this.parent.getVariable(key, index);
106 }
107 throw new SlashCommandScopeVariableNotFoundError(`No such variable: "${key}"`);
108 }
109}
110
111
112export class SlashCommandScopeVariableExistsError extends Error {}
113
114
115export class SlashCommandScopeVariableNotFoundError extends Error {}