@open-discord-bots/framework 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,977 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ODCliEditConfigInstance = void 0;
7
+ const index_1 = require("../index");
8
+ const terminal_kit_1 = require("terminal-kit");
9
+ const ansis_1 = __importDefault(require("ansis"));
10
+ const cli_1 = require("./cli");
11
+ class ODCliEditConfigInstance {
12
+ opts;
13
+ opendiscord;
14
+ constructor(opts, opendiscord) {
15
+ this.opts = opts;
16
+ this.opendiscord = opendiscord;
17
+ }
18
+ async renderEditConfig(backFn) {
19
+ (0, cli_1.renderHeader)(this.opts, []);
20
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("Please select which config you would like to edit.\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
21
+ const checkerList = this.opendiscord.checkers.getAll();
22
+ const checkerNameList = checkerList.map((checker) => (checker.options.cliDisplayName ? checker.options.cliDisplayName + " (" + checker.config.file + ")" : checker.config.file));
23
+ const checkerNameLength = index_1.utilities.getLongestLength(checkerNameList);
24
+ const finalCheckerNameList = checkerNameList.map((name, index) => name.padEnd(checkerNameLength + 5, " ") + ansis_1.default.gray(checkerList[index].options.cliDisplayDescription ? "=> " + checkerList[index].options.cliDisplayDescription : ""));
25
+ const answer = await terminal_kit_1.terminal.singleColumnMenu(finalCheckerNameList, {
26
+ leftPadding: "> ",
27
+ style: terminal_kit_1.terminal.cyan,
28
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
29
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
30
+ extraLines: 2,
31
+ cancelable: true
32
+ }).promise;
33
+ if (answer.canceled)
34
+ return await backFn();
35
+ const checker = checkerList[answer.selectedIndex];
36
+ const configData = checker.config.data;
37
+ await this.chooseConfigStructure(checker, async () => { await this.renderEditConfig(backFn); }, checker.structure, configData, {}, NaN, ["(" + checker.config.path + ")"]);
38
+ }
39
+ async chooseConfigStructure(checker, backFn, structure, data, parent, parentIndex, path) {
40
+ if (structure instanceof index_1.api.ODCheckerObjectStructure && typeof data == "object" && !Array.isArray(data) && data)
41
+ await this.renderConfigObjectStructureSelector(checker, backFn, structure, data, parent, parentIndex, path);
42
+ else if (structure instanceof index_1.api.ODCheckerEnabledObjectStructure && typeof data == "object" && !Array.isArray(data) && data)
43
+ await this.renderConfigEnabledObjectStructureSelector(checker, backFn, structure, data, parent, parentIndex, path);
44
+ else if (structure instanceof index_1.api.ODCheckerObjectSwitchStructure && typeof data == "object" && !Array.isArray(data) && data)
45
+ await this.renderConfigObjectSwitchStructureSelector(checker, backFn, structure, data, parent, parentIndex, path);
46
+ else if (structure instanceof index_1.api.ODCheckerArrayStructure && Array.isArray(data))
47
+ await this.renderConfigArrayStructureSelector(checker, backFn, structure, data, parent, parentIndex, path);
48
+ else if (structure instanceof index_1.api.ODCheckerBooleanStructure && typeof data == "boolean")
49
+ await this.renderConfigBooleanStructureEditor(checker, backFn, structure, data, parent, parentIndex, path);
50
+ else if (structure instanceof index_1.api.ODCheckerNumberStructure && typeof data == "number")
51
+ await this.renderConfigNumberStructureEditor(checker, backFn, structure, data, parent, parentIndex, path);
52
+ else if (structure instanceof index_1.api.ODCheckerStringStructure && typeof data == "string")
53
+ await this.renderConfigStringStructureEditor(checker, backFn, structure, data, parent, parentIndex, path);
54
+ else if (structure instanceof index_1.api.ODCheckerNullStructure && data === null)
55
+ await this.renderConfigNullStructureEditor(checker, backFn, structure, data, parent, parentIndex, path);
56
+ else if (structure instanceof index_1.api.ODCheckerTypeSwitchStructure)
57
+ await this.renderConfigTypeSwitchStructureEditor(checker, backFn, structure, data, parent, parentIndex, path);
58
+ else
59
+ terminal_kit_1.terminal.red.bold("❌ Unable to detect type of variable! Please try to edit this property in the JSON file itself!");
60
+ }
61
+ async renderConfigObjectStructureSelector(checker, backFn, structure, data, parent, parentIndex, path) {
62
+ if (typeof data != "object" || Array.isArray(data))
63
+ throw new index_1.api.ODSystemError("OD CLI => Property is not of the type 'object'. Please check your config for possible errors. (index: " + parentIndex + ", path: " + path.join(".") + ")");
64
+ (0, cli_1.renderHeader)(this.opts, path);
65
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("Please select which variable you would like to edit.\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
66
+ if (!structure.options.children)
67
+ return await backFn();
68
+ if (structure.options.cliDisplayName) {
69
+ terminal_kit_1.terminal.gray("\nProperty: " + ansis_1.default.bold.blue(structure.options.cliDisplayName) + "\n");
70
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
71
+ }
72
+ const list = structure.options.children.filter((child) => !child.cliHideInEditMode);
73
+ const nameList = list.map((child) => (child.checker.options.cliDisplayName ? child.checker.options.cliDisplayName : child.key));
74
+ const nameLength = index_1.utilities.getLongestLength(nameList);
75
+ const finalnameList = nameList.map((name, index) => name.padEnd(nameLength + 5, " ") + ansis_1.default.gray((!list[index].checker.options.cliHideDescriptionInParent && list[index].checker.options.cliDisplayDescription) ? "=> " + list[index].checker.options.cliDisplayDescription : ""));
76
+ const answer = await terminal_kit_1.terminal.singleColumnMenu(finalnameList, {
77
+ leftPadding: "> ",
78
+ style: terminal_kit_1.terminal.cyan,
79
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold.defaultColor,
80
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
81
+ extraLines: 2,
82
+ cancelable: true
83
+ }).promise;
84
+ if (answer.canceled)
85
+ return await backFn();
86
+ const subStructure = list[answer.selectedIndex];
87
+ const subData = data[subStructure.key];
88
+ await this.chooseConfigStructure(checker, async () => { await this.renderConfigObjectStructureSelector(checker, backFn, structure, data, parent, parentIndex, path); }, subStructure.checker, subData, data, subStructure.key, [...path, subStructure.key]);
89
+ }
90
+ async renderConfigEnabledObjectStructureSelector(checker, backFn, structure, data, parent, parentIndex, path) {
91
+ if (typeof data != "object" || Array.isArray(data))
92
+ throw new index_1.api.ODSystemError("OD CLI => Property is not of the type 'object'. Please check your config for possible errors. (index: " + parentIndex + ", path: " + path.join(".") + ")");
93
+ const enabledProperty = structure.options.property;
94
+ const subStructure = structure.options.checker;
95
+ if (!enabledProperty || !subStructure || !subStructure.options.children)
96
+ return await backFn();
97
+ if (!subStructure.options.children.find((child) => child.key === structure.options.property)) {
98
+ if (typeof structure.options.enabledValue == "string")
99
+ subStructure.options.children.unshift({ key: enabledProperty, optional: false, priority: 1, checker: new index_1.api.ODCheckerStringStructure("opendiscord:CLI-checker-enabled-object-structure", {}) });
100
+ else if (typeof structure.options.enabledValue == "number")
101
+ subStructure.options.children.unshift({ key: enabledProperty, optional: false, priority: 1, checker: new index_1.api.ODCheckerNumberStructure("opendiscord:CLI-checker-enabled-object-structure", {}) });
102
+ else if (typeof structure.options.enabledValue == "boolean")
103
+ subStructure.options.children.unshift({ key: enabledProperty, optional: false, priority: 1, checker: new index_1.api.ODCheckerBooleanStructure("opendiscord:CLI-checker-enabled-object-structure", {}) });
104
+ }
105
+ await this.chooseConfigStructure(checker, backFn, subStructure, data, parent, parentIndex, path);
106
+ }
107
+ async renderConfigObjectSwitchStructureSelector(checker, backFn, structure, data, parent, parentIndex, path) {
108
+ if (typeof data != "object" || Array.isArray(data))
109
+ throw new index_1.api.ODSystemError("OD CLI => Property is not of the type 'object'. Please check your config for possible errors. (index: " + parentIndex + ", path: " + path.join(".") + ")");
110
+ if (!structure.options.objects)
111
+ return await backFn();
112
+ let didMatch = false;
113
+ for (const objectTemplate of structure.options.objects) {
114
+ if (objectTemplate.properties.every((prop) => data[prop.key] === prop.value)) {
115
+ //object template matches data
116
+ const subStructure = objectTemplate.checker;
117
+ didMatch = true;
118
+ await this.chooseConfigStructure(checker, backFn, subStructure, data, parent, parentIndex, path);
119
+ }
120
+ }
121
+ if (!didMatch)
122
+ throw new index_1.api.ODSystemError("OD CLI => Unable to detect type of object in the object switch. Please check your config for possible errors. (index: " + parentIndex + ", path: " + path.join(".") + ")");
123
+ }
124
+ async renderConfigArrayStructureSelector(checker, backFn, structure, data, parent, parentIndex, path) {
125
+ if (!Array.isArray(data))
126
+ throw new index_1.api.ODSystemError("OD CLI => Property is not of the type 'array'. Please check your config for possible errors. (index: " + parentIndex + ", path: " + path.join(".") + ")");
127
+ (0, cli_1.renderHeader)(this.opts, path);
128
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("Please select what you would like to do.\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
129
+ if (!structure.options.propertyChecker)
130
+ return await backFn();
131
+ if (structure.options.cliDisplayName || typeof parentIndex == "string" || !isNaN(parentIndex)) {
132
+ terminal_kit_1.terminal.gray("\nProperty: " + ansis_1.default.bold.blue(structure.options.cliDisplayName ?? parentIndex.toString()) + "\n");
133
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
134
+ }
135
+ const propertyName = structure.options.cliDisplayPropertyName ?? "index";
136
+ const answer = await terminal_kit_1.terminal.singleColumnMenu(data.length < 1 ? ["Add " + propertyName] : [
137
+ "Add " + propertyName,
138
+ "Edit " + propertyName,
139
+ "Move " + propertyName,
140
+ "Remove " + propertyName,
141
+ "Duplicate " + propertyName
142
+ ], {
143
+ leftPadding: "> ",
144
+ style: terminal_kit_1.terminal.cyan,
145
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
146
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
147
+ extraLines: 2,
148
+ cancelable: true
149
+ }).promise;
150
+ const backFnFunc = async () => { await this.renderConfigArrayStructureSelector(checker, backFn, structure, data, parent, parentIndex, path); };
151
+ if (answer.canceled)
152
+ return await backFn();
153
+ if (answer.selectedIndex == 0)
154
+ await this.chooseAdditionConfigStructure(checker, backFnFunc, async (newData) => {
155
+ data[data.length] = newData;
156
+ await checker.config.save();
157
+ await backFnFunc();
158
+ }, structure.options.propertyChecker, data, data.length, path, []);
159
+ else if (answer.selectedIndex == 1)
160
+ await this.renderConfigArrayStructureEditSelector(checker, backFnFunc, structure, structure.options.propertyChecker, data, parent, parentIndex, path);
161
+ else if (answer.selectedIndex == 2)
162
+ await this.renderConfigArrayStructureMoveSelector(checker, backFnFunc, structure, structure.options.propertyChecker, data, parent, parentIndex, path);
163
+ else if (answer.selectedIndex == 3)
164
+ await this.renderConfigArrayStructureRemoveSelector(checker, backFnFunc, structure, structure.options.propertyChecker, data, parent, parentIndex, path);
165
+ else if (answer.selectedIndex == 4)
166
+ await this.renderConfigArrayStructureDuplicateSelector(checker, backFnFunc, structure, structure.options.propertyChecker, data, parent, parentIndex, path);
167
+ }
168
+ async renderConfigArrayStructureEditSelector(checker, backFn, arrayStructure, structure, data, parent, parentIndex, path) {
169
+ const propertyName = arrayStructure.options.cliDisplayPropertyName ?? "index";
170
+ (0, cli_1.renderHeader)(this.opts, path);
171
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("Please select the " + propertyName + " you would like to edit.\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
172
+ const longestDataListName = Math.max(...data.map((d, i) => this.getArrayPreviewStructureNameLength(structure, d, data, i)));
173
+ const dataList = data.map((d, i) => (i + 1) + ". " + this.getArrayPreviewFromStructure(structure, d, data, i, longestDataListName));
174
+ const dataAnswer = await terminal_kit_1.terminal.singleColumnMenu(dataList, {
175
+ leftPadding: "> ",
176
+ style: terminal_kit_1.terminal.cyan,
177
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
178
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
179
+ extraLines: 2,
180
+ cancelable: true
181
+ }).promise;
182
+ if (dataAnswer.canceled)
183
+ return await backFn();
184
+ const subData = data[dataAnswer.selectedIndex];
185
+ await this.chooseConfigStructure(checker, async () => { await this.renderConfigArrayStructureEditSelector(checker, backFn, arrayStructure, structure, data, parent, parentIndex, path); }, structure, subData, data, dataAnswer.selectedIndex, [...path, dataAnswer.selectedIndex]);
186
+ }
187
+ async renderConfigArrayStructureMoveSelector(checker, backFn, arrayStructure, structure, data, parent, parentIndex, path) {
188
+ const propertyName = arrayStructure.options.cliDisplayPropertyName ?? "index";
189
+ (0, cli_1.renderHeader)(this.opts, path);
190
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("Please select the " + propertyName + " you would like to move.\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
191
+ const longestDataListName = Math.max(...data.map((d, i) => this.getArrayPreviewStructureNameLength(structure, d, data, i)));
192
+ const dataList = data.map((d, i) => (i + 1) + ". " + this.getArrayPreviewFromStructure(structure, d, data, i, longestDataListName));
193
+ const dataAnswer = await terminal_kit_1.terminal.singleColumnMenu(dataList, {
194
+ leftPadding: "> ",
195
+ style: terminal_kit_1.terminal.cyan,
196
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
197
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
198
+ extraLines: 2,
199
+ cancelable: true
200
+ }).promise;
201
+ if (dataAnswer.canceled)
202
+ return await backFn();
203
+ (0, cli_1.renderHeader)(this.opts, [...path, dataAnswer.selectedIndex]);
204
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("Please select the position you would like to move to.\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
205
+ const moveAnswer = await terminal_kit_1.terminal.singleColumnMenu(data.map((d, i) => "Position " + (i + 1)), {
206
+ leftPadding: "> ",
207
+ style: terminal_kit_1.terminal.cyan,
208
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
209
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
210
+ extraLines: 2,
211
+ cancelable: true
212
+ }).promise;
213
+ if (moveAnswer.canceled)
214
+ return await this.renderConfigArrayStructureMoveSelector(checker, backFn, arrayStructure, structure, data, parent, parentIndex, path);
215
+ const subData = data[dataAnswer.selectedIndex];
216
+ const slicedData = [...data.slice(0, dataAnswer.selectedIndex), ...data.slice(dataAnswer.selectedIndex + 1)];
217
+ const insertedData = [...slicedData.slice(0, moveAnswer.selectedIndex), subData, ...slicedData.slice(moveAnswer.selectedIndex)];
218
+ insertedData.forEach((d, i) => data[i] = d);
219
+ await checker.config.save();
220
+ terminal_kit_1.terminal.bold.blue("\n\n✅ Property moved succesfully!");
221
+ await index_1.utilities.timer(400);
222
+ await backFn();
223
+ }
224
+ async renderConfigArrayStructureRemoveSelector(checker, backFn, arrayStructure, structure, data, parent, parentIndex, path) {
225
+ const propertyName = arrayStructure.options.cliDisplayPropertyName ?? "index";
226
+ (0, cli_1.renderHeader)(this.opts, path);
227
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("Please select the " + propertyName + " you would like to delete.\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
228
+ const longestDataListName = Math.max(...data.map((d, i) => this.getArrayPreviewStructureNameLength(structure, d, data, i)));
229
+ const dataList = data.map((d, i) => (i + 1) + ". " + this.getArrayPreviewFromStructure(structure, d, data, i, longestDataListName));
230
+ const dataAnswer = await terminal_kit_1.terminal.singleColumnMenu(dataList, {
231
+ leftPadding: "> ",
232
+ style: terminal_kit_1.terminal.cyan,
233
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
234
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
235
+ extraLines: 2,
236
+ cancelable: true
237
+ }).promise;
238
+ if (dataAnswer.canceled)
239
+ return await backFn();
240
+ data.splice(dataAnswer.selectedIndex, 1);
241
+ await checker.config.save();
242
+ terminal_kit_1.terminal.bold.blue("\n\n✅ Property deleted succesfully!");
243
+ await index_1.utilities.timer(400);
244
+ await backFn();
245
+ }
246
+ async renderConfigArrayStructureDuplicateSelector(checker, backFn, arrayStructure, structure, data, parent, parentIndex, path) {
247
+ const propertyName = arrayStructure.options.cliDisplayPropertyName ?? "index";
248
+ (0, cli_1.renderHeader)(this.opts, path);
249
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("Please select the " + propertyName + " you would like to duplicate.\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
250
+ const longestDataListName = Math.max(...data.map((d, i) => this.getArrayPreviewStructureNameLength(structure, d, data, i)));
251
+ const dataList = data.map((d, i) => (i + 1) + ". " + this.getArrayPreviewFromStructure(structure, d, data, i, longestDataListName));
252
+ const dataAnswer = await terminal_kit_1.terminal.singleColumnMenu(dataList, {
253
+ leftPadding: "> ",
254
+ style: terminal_kit_1.terminal.cyan,
255
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
256
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
257
+ extraLines: 2,
258
+ cancelable: true
259
+ }).promise;
260
+ if (dataAnswer.canceled)
261
+ return await backFn();
262
+ data.push(JSON.parse(JSON.stringify(data[dataAnswer.selectedIndex])));
263
+ await checker.config.save();
264
+ terminal_kit_1.terminal.bold.blue("\n\n✅ Property duplicated succesfully!");
265
+ await index_1.utilities.timer(400);
266
+ await backFn();
267
+ }
268
+ async renderConfigBooleanStructureEditor(checker, backFn, structure, data, parent, parentIndex, path) {
269
+ if (typeof data != "boolean")
270
+ throw new index_1.api.ODSystemError("OD CLI => Property is not of the type 'boolean'. Please check your config for possible errors. (index: " + parentIndex + ", path: " + path.join(".") + ")");
271
+ (0, cli_1.renderHeader)(this.opts, path);
272
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("You are now editing " + (typeof parentIndex == "string" ? "the boolean property " + ansis_1.default.blue("\"" + parentIndex + "\"") : "boolean property " + ansis_1.default.blue("#" + (parentIndex + 1))) + ".\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
273
+ terminal_kit_1.terminal.gray("\nCurrent value: " + ansis_1.default.bold[data ? "green" : "red"](data.toString()) + "\n");
274
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
275
+ const answer = await terminal_kit_1.terminal.singleColumnMenu(["false (Disabled)", "true (Enabled)"], {
276
+ leftPadding: "> ",
277
+ style: terminal_kit_1.terminal.cyan,
278
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
279
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
280
+ extraLines: 2,
281
+ cancelable: true
282
+ }).promise;
283
+ if (answer.canceled)
284
+ return await backFn();
285
+ //run config checker
286
+ const newValue = (answer.selectedIndex == 0) ? false : true;
287
+ const newPath = [...path];
288
+ newPath.shift();
289
+ checker.messages = []; //manually clear previous messages
290
+ const isDataValid = structure.check(checker, newValue, newPath);
291
+ if (isDataValid) {
292
+ parent[parentIndex] = newValue;
293
+ await checker.config.save();
294
+ terminal_kit_1.terminal.bold.blue("\n\n✅ Variable saved succesfully!");
295
+ await index_1.utilities.timer(400);
296
+ await backFn();
297
+ }
298
+ else {
299
+ const messages = checker.messages.map((msg) => "=> [" + msg.type.toUpperCase() + "] " + msg.message).join("\n");
300
+ terminal_kit_1.terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!");
301
+ terminal_kit_1.terminal.gray("\n" + messages);
302
+ await index_1.utilities.timer(1000 + (2000 * checker.messages.length));
303
+ await this.renderConfigBooleanStructureEditor(checker, backFn, structure, data, parent, parentIndex, path);
304
+ }
305
+ }
306
+ async renderConfigNumberStructureEditor(checker, backFn, structure, data, parent, parentIndex, path, prefillValue) {
307
+ if (typeof data != "number")
308
+ throw new index_1.api.ODSystemError("OD CLI => Property is not of the type 'number'. Please check your config for possible errors. (index: " + parentIndex + ", path: " + path.join(".") + ")");
309
+ (0, cli_1.renderHeader)(this.opts, path);
310
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("You are now editing " + (typeof parentIndex == "string" ? "the number property " + ansis_1.default.blue("\"" + parentIndex + "\"") : "number property " + ansis_1.default.blue("#" + (parentIndex + 1))) + ".\n") + ansis_1.default.italic.gray("(insert a new value and press enter, go back using escape)\n"));
311
+ terminal_kit_1.terminal.gray("\nCurrent value: " + ansis_1.default.bold.blue(data.toString()) + "\n");
312
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
313
+ const answer = await terminal_kit_1.terminal.inputField({
314
+ default: prefillValue,
315
+ style: terminal_kit_1.terminal.cyan,
316
+ cancelable: true
317
+ }).promise;
318
+ if (typeof answer != "string")
319
+ return await backFn();
320
+ //run config checker
321
+ const newValue = Number(answer.replaceAll(",", "."));
322
+ const newPath = [...path];
323
+ newPath.shift();
324
+ checker.messages = []; //manually clear previous messages
325
+ const isDataValid = structure.check(checker, newValue, newPath);
326
+ if (isDataValid) {
327
+ parent[parentIndex] = newValue;
328
+ await checker.config.save();
329
+ terminal_kit_1.terminal.bold.blue("\n\n✅ Variable saved succesfully!");
330
+ await index_1.utilities.timer(400);
331
+ await backFn();
332
+ }
333
+ else {
334
+ const messages = checker.messages.map((msg) => "=> [" + msg.type.toUpperCase() + "] " + msg.message).join("\n");
335
+ terminal_kit_1.terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!");
336
+ terminal_kit_1.terminal.red("\n" + messages);
337
+ await index_1.utilities.timer(1000 + (2000 * checker.messages.length));
338
+ await this.renderConfigNumberStructureEditor(checker, backFn, structure, data, parent, parentIndex, path, answer);
339
+ }
340
+ }
341
+ async renderConfigStringStructureEditor(checker, backFn, structure, data, parent, parentIndex, path, prefillValue) {
342
+ if (typeof data != "string")
343
+ throw new index_1.api.ODSystemError("OD CLI => Property is not of the type 'string'. Please check your config for possible errors. (index: " + parentIndex + ", path: " + path.join(".") + ")");
344
+ (0, cli_1.renderHeader)(this.opts, path);
345
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("You are now editing " + (typeof parentIndex == "string" ? "the string property " + ansis_1.default.blue("\"" + parentIndex + "\"") : "string property " + ansis_1.default.blue("#" + (parentIndex + 1))) + ".\n") + ansis_1.default.italic.gray("(insert a new value and press enter, go back using escape)\n"));
346
+ terminal_kit_1.terminal.gray("\nCurrent value:" + (data.includes("\n") ? "\n" : " \"") + ansis_1.default.bold.blue(data) + ansis_1.default.gray(!data.includes("\n") ? "\"\n" : "\n"));
347
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
348
+ const customExtraOptions = (structure instanceof index_1.api.ODCheckerCustomStructure_DiscordId) ? structure.extraOptions : undefined;
349
+ const customAutocompleteFunc = structure.options.cliAutocompleteFunc ? await structure.options.cliAutocompleteFunc() : null;
350
+ const autocompleteList = ((customAutocompleteFunc ?? structure.options.cliAutocompleteList) ?? customExtraOptions) ?? structure.options.choices;
351
+ const autoCompleteMenuOpts = {
352
+ style: terminal_kit_1.terminal.white,
353
+ selectedStyle: terminal_kit_1.terminal.bgBlue.white
354
+ };
355
+ const input = terminal_kit_1.terminal.inputField({
356
+ default: prefillValue,
357
+ style: terminal_kit_1.terminal.cyan,
358
+ hintStyle: terminal_kit_1.terminal.gray,
359
+ cancelable: false,
360
+ autoComplete: autocompleteList,
361
+ autoCompleteHint: (!!autocompleteList),
362
+ autoCompleteMenu: (autocompleteList) ? autoCompleteMenuOpts : false
363
+ });
364
+ terminal_kit_1.terminal.on("key", async (name, matches, data) => {
365
+ if (name == "ESCAPE") {
366
+ terminal_kit_1.terminal.removeListener("key", "cli-render-string-structure-edit");
367
+ input.abort();
368
+ await backFn();
369
+ }
370
+ }, { id: "cli-render-string-structure-edit" });
371
+ const answer = await input.promise;
372
+ terminal_kit_1.terminal.removeListener("key", "cli-render-string-structure-edit");
373
+ if (typeof answer != "string")
374
+ return;
375
+ //run config checker
376
+ const newValue = answer.replaceAll("\\n", "\n");
377
+ const newPath = [...path];
378
+ newPath.shift();
379
+ checker.messages = []; //manually clear previous messages
380
+ const isDataValid = structure.check(checker, newValue, newPath);
381
+ if (isDataValid) {
382
+ parent[parentIndex] = newValue;
383
+ await checker.config.save();
384
+ terminal_kit_1.terminal.bold.blue("\n\n✅ Variable saved succesfully!");
385
+ await index_1.utilities.timer(400);
386
+ await backFn();
387
+ }
388
+ else {
389
+ const messages = checker.messages.map((msg) => "=> [" + msg.type.toUpperCase() + "] " + msg.message).join("\n");
390
+ terminal_kit_1.terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!");
391
+ terminal_kit_1.terminal.red("\n" + messages);
392
+ await index_1.utilities.timer(1000 + (2000 * checker.messages.length));
393
+ await this.renderConfigStringStructureEditor(checker, backFn, structure, data, parent, parentIndex, path, answer);
394
+ }
395
+ }
396
+ async renderConfigNullStructureEditor(checker, backFn, structure, data, parent, parentIndex, path) {
397
+ if (data !== null)
398
+ throw new index_1.api.ODSystemError("OD CLI => Property is not of the type 'null'. Please check your config for possible errors. (index: " + parentIndex + ", path: " + path.join(".") + ")");
399
+ (0, cli_1.renderHeader)(this.opts, path);
400
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("You are now editing " + (typeof parentIndex == "string" ? "the null property " + ansis_1.default.blue("\"" + parentIndex + "\"") : "null property " + ansis_1.default.blue("#" + (parentIndex + 1))) + ".\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
401
+ terminal_kit_1.terminal.gray("\nCurrent value: " + ansis_1.default.bold.blue("null") + "\n");
402
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
403
+ const answer = await terminal_kit_1.terminal.singleColumnMenu(["null"], {
404
+ leftPadding: "> ",
405
+ style: terminal_kit_1.terminal.cyan,
406
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
407
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
408
+ extraLines: 2,
409
+ cancelable: true
410
+ }).promise;
411
+ if (answer.canceled)
412
+ return await backFn();
413
+ //run config checker
414
+ const newValue = null;
415
+ const newPath = [...path];
416
+ newPath.shift();
417
+ checker.messages = []; //manually clear previous messages
418
+ const isDataValid = structure.check(checker, newValue, newPath);
419
+ if (isDataValid) {
420
+ parent[parentIndex] = newValue;
421
+ await checker.config.save();
422
+ terminal_kit_1.terminal.bold.blue("\n\n✅ Variable saved succesfully!");
423
+ await index_1.utilities.timer(400);
424
+ await backFn();
425
+ }
426
+ else {
427
+ const messages = checker.messages.map((msg) => "=> [" + msg.type.toUpperCase() + "] " + msg.message).join("\n");
428
+ terminal_kit_1.terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!");
429
+ terminal_kit_1.terminal.red("\n" + messages);
430
+ await index_1.utilities.timer(1000 + (2000 * checker.messages.length));
431
+ await this.renderConfigNullStructureEditor(checker, backFn, structure, data, parent, parentIndex, path);
432
+ }
433
+ }
434
+ async renderConfigTypeSwitchStructureEditor(checker, backFn, structure, data, parent, parentIndex, path) {
435
+ (0, cli_1.renderHeader)(this.opts, path);
436
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("You are now editing " + (typeof parentIndex == "string" ? "the property " + ansis_1.default.blue("\"" + parentIndex + "\"") : "property " + ansis_1.default.blue("#" + (parentIndex + 1))) + ".\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
437
+ terminal_kit_1.terminal.gray("\nCurrent value: " + ansis_1.default.bold.blue(data.toString()) + "\n");
438
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
439
+ const actionsList = [];
440
+ if (structure.options.boolean)
441
+ actionsList.push("Edit as boolean");
442
+ if (structure.options.string)
443
+ actionsList.push("Edit as string");
444
+ if (structure.options.number)
445
+ actionsList.push("Edit as number");
446
+ if (structure.options.object)
447
+ actionsList.push("Edit as object");
448
+ if (structure.options.array)
449
+ actionsList.push("Edit as array/list");
450
+ if (structure.options.null)
451
+ actionsList.push("Edit as null");
452
+ const answer = await terminal_kit_1.terminal.singleColumnMenu(actionsList, {
453
+ leftPadding: "> ",
454
+ style: terminal_kit_1.terminal.cyan,
455
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
456
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
457
+ extraLines: 2,
458
+ cancelable: true
459
+ }).promise;
460
+ if (answer.canceled)
461
+ return await backFn();
462
+ //run selected structure editor (untested)
463
+ if (answer.selectedText.startsWith("Edit as boolean") && structure.options.boolean)
464
+ await this.renderConfigBooleanStructureEditor(checker, async () => { await this.renderConfigTypeSwitchStructureEditor(checker, backFn, structure, data, parent, parentIndex, path); }, structure.options.boolean, false, parent, parentIndex, path);
465
+ else if (answer.selectedText.startsWith("Edit as string") && structure.options.string)
466
+ await this.renderConfigStringStructureEditor(checker, async () => { await this.renderConfigTypeSwitchStructureEditor(checker, backFn, structure, data, parent, parentIndex, path); }, structure.options.string, data.toString(), parent, parentIndex, path);
467
+ else if (answer.selectedText.startsWith("Edit as number") && structure.options.number)
468
+ await this.renderConfigNumberStructureEditor(checker, async () => { await this.renderConfigTypeSwitchStructureEditor(checker, backFn, structure, data, parent, parentIndex, path); }, structure.options.number, 0, parent, parentIndex, path);
469
+ else if (answer.selectedText.startsWith("Edit as object") && structure.options.object)
470
+ await this.renderConfigObjectStructureSelector(checker, async () => { await this.renderConfigTypeSwitchStructureEditor(checker, backFn, structure, data, parent, parentIndex, path); }, structure.options.object, data, parent, parentIndex, path);
471
+ else if (answer.selectedText.startsWith("Edit as array/list") && structure.options.array)
472
+ await this.renderConfigArrayStructureSelector(checker, async () => { await this.renderConfigTypeSwitchStructureEditor(checker, backFn, structure, data, parent, parentIndex, path); }, structure.options.array, data, parent, parentIndex, path);
473
+ else if (answer.selectedText.startsWith("Edit as null") && structure.options.null)
474
+ await this.renderConfigNullStructureEditor(checker, async () => { await this.renderConfigTypeSwitchStructureEditor(checker, backFn, structure, data, parent, parentIndex, path); }, structure.options.null, null, parent, parentIndex, path);
475
+ }
476
+ getArrayPreviewStructureNameLength(structure, data, parent, parentIndex) {
477
+ if (structure instanceof index_1.api.ODCheckerBooleanStructure && typeof data == "boolean")
478
+ return data.toString().length;
479
+ else if (structure instanceof index_1.api.ODCheckerNumberStructure && typeof data == "number")
480
+ return data.toString().length;
481
+ else if (structure instanceof index_1.api.ODCheckerStringStructure && typeof data == "string")
482
+ return data.length;
483
+ else if (structure instanceof index_1.api.ODCheckerNullStructure && data === null)
484
+ return "Null".length;
485
+ else if (structure instanceof index_1.api.ODCheckerArrayStructure && Array.isArray(data))
486
+ return "Array".length;
487
+ else if (structure instanceof index_1.api.ODCheckerObjectStructure && typeof data == "object" && !Array.isArray(data) && data) {
488
+ if (!structure.options.cliDisplayKeyInParentArray)
489
+ return "Object".length;
490
+ else
491
+ return data[structure.options.cliDisplayKeyInParentArray].toString().length;
492
+ }
493
+ else if (structure instanceof index_1.api.ODCheckerEnabledObjectStructure && typeof data == "object" && !Array.isArray(data) && data) {
494
+ const subStructure = structure.options.checker;
495
+ if (!subStructure)
496
+ return "<unknown-property>".length;
497
+ return this.getArrayPreviewStructureNameLength(subStructure, data, parent, parentIndex);
498
+ }
499
+ else if (structure instanceof index_1.api.ODCheckerObjectSwitchStructure && typeof data == "object" && !Array.isArray(data) && data) {
500
+ for (const objectTemplate of (structure.options.objects ?? [])) {
501
+ if (objectTemplate.properties.every((prop) => data[prop.key] === prop.value)) {
502
+ //object template matches data
503
+ const subStructure = objectTemplate.checker;
504
+ return this.getArrayPreviewStructureNameLength(subStructure, data, parent, parentIndex);
505
+ }
506
+ }
507
+ return "<unknown-property>".length;
508
+ }
509
+ else if (structure instanceof index_1.api.ODCheckerTypeSwitchStructure) {
510
+ if (typeof data == "boolean" && structure.options.boolean)
511
+ return this.getArrayPreviewStructureNameLength(structure.options.boolean, data, parent, parentIndex);
512
+ else if (typeof data == "number" && structure.options.number)
513
+ return this.getArrayPreviewStructureNameLength(structure.options.number, data, parent, parentIndex);
514
+ else if (typeof data == "string" && structure.options.string)
515
+ return this.getArrayPreviewStructureNameLength(structure.options.string, data, parent, parentIndex);
516
+ else if (typeof data == "object" && !Array.isArray(data) && data && structure.options.object)
517
+ return this.getArrayPreviewStructureNameLength(structure.options.object, data, parent, parentIndex);
518
+ else if (Array.isArray(data) && structure.options.array)
519
+ return this.getArrayPreviewStructureNameLength(structure.options.array, data, parent, parentIndex);
520
+ else if (data === null && structure.options.null)
521
+ return this.getArrayPreviewStructureNameLength(structure.options.null, data, parent, parentIndex);
522
+ else
523
+ return "<unknown-property>".length;
524
+ }
525
+ else
526
+ return "<unknown-property>".length;
527
+ }
528
+ getArrayPreviewFromStructure(structure, data, parent, parentIndex, nameLength) {
529
+ if (structure instanceof index_1.api.ODCheckerBooleanStructure && typeof data == "boolean")
530
+ return data.toString();
531
+ else if (structure instanceof index_1.api.ODCheckerNumberStructure && typeof data == "number")
532
+ return data.toString();
533
+ else if (structure instanceof index_1.api.ODCheckerStringStructure && typeof data == "string")
534
+ return data;
535
+ else if (structure instanceof index_1.api.ODCheckerNullStructure && data === null)
536
+ return "Null";
537
+ else if (structure instanceof index_1.api.ODCheckerArrayStructure && Array.isArray(data))
538
+ return "Array";
539
+ else if (structure instanceof index_1.api.ODCheckerObjectStructure && typeof data == "object" && !Array.isArray(data) && data) {
540
+ const additionalKeys = (structure.options.cliDisplayAdditionalKeysInParentArray ?? []).map((key) => key + ": " + data[key].toString()).join(", ");
541
+ if (!structure.options.cliDisplayKeyInParentArray)
542
+ return "Object";
543
+ else
544
+ return data[structure.options.cliDisplayKeyInParentArray].toString().padEnd(nameLength + 5, " ") + ansis_1.default.gray(additionalKeys.length > 0 ? "(" + additionalKeys + ")" : "");
545
+ }
546
+ else if (structure instanceof index_1.api.ODCheckerEnabledObjectStructure && typeof data == "object" && !Array.isArray(data) && data) {
547
+ const subStructure = structure.options.checker;
548
+ if (!subStructure)
549
+ return "<unknown-property>";
550
+ return this.getArrayPreviewFromStructure(subStructure, data, parent, parentIndex, nameLength);
551
+ }
552
+ else if (structure instanceof index_1.api.ODCheckerObjectSwitchStructure && typeof data == "object" && !Array.isArray(data) && data) {
553
+ for (const objectTemplate of (structure.options.objects ?? [])) {
554
+ if (objectTemplate.properties.every((prop) => data[prop.key] === prop.value)) {
555
+ //object template matches data
556
+ const subStructure = objectTemplate.checker;
557
+ return this.getArrayPreviewFromStructure(subStructure, data, parent, parentIndex, nameLength);
558
+ }
559
+ }
560
+ return "<unknown-property>";
561
+ }
562
+ else if (structure instanceof index_1.api.ODCheckerTypeSwitchStructure) {
563
+ if (typeof data == "boolean" && structure.options.boolean)
564
+ return this.getArrayPreviewFromStructure(structure.options.boolean, data, parent, parentIndex, nameLength);
565
+ else if (typeof data == "number" && structure.options.number)
566
+ return this.getArrayPreviewFromStructure(structure.options.number, data, parent, parentIndex, nameLength);
567
+ else if (typeof data == "string" && structure.options.string)
568
+ return this.getArrayPreviewFromStructure(structure.options.string, data, parent, parentIndex, nameLength);
569
+ else if (typeof data == "object" && !Array.isArray(data) && data && structure.options.object)
570
+ return this.getArrayPreviewFromStructure(structure.options.object, data, parent, parentIndex, nameLength);
571
+ else if (Array.isArray(data) && structure.options.array)
572
+ return this.getArrayPreviewFromStructure(structure.options.array, data, parent, parentIndex, nameLength);
573
+ else if (data === null && structure.options.null)
574
+ return this.getArrayPreviewFromStructure(structure.options.null, data, parent, parentIndex, nameLength);
575
+ else
576
+ return "<unknown-property>";
577
+ }
578
+ else
579
+ return "<unknown-property>";
580
+ }
581
+ async chooseAdditionConfigStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath) {
582
+ if (structure instanceof index_1.api.ODCheckerObjectStructure)
583
+ await this.renderAdditionConfigObjectStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath);
584
+ else if (structure instanceof index_1.api.ODCheckerBooleanStructure)
585
+ await this.renderAdditionConfigBooleanStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath);
586
+ else if (structure instanceof index_1.api.ODCheckerNumberStructure)
587
+ await this.renderAdditionConfigNumberStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath);
588
+ else if (structure instanceof index_1.api.ODCheckerStringStructure)
589
+ await this.renderAdditionConfigStringStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath);
590
+ else if (structure instanceof index_1.api.ODCheckerNullStructure)
591
+ await this.renderAdditionConfigNullStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath);
592
+ else if (structure instanceof index_1.api.ODCheckerEnabledObjectStructure)
593
+ await this.renderAdditionConfigEnabledObjectStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath);
594
+ else if (structure instanceof index_1.api.ODCheckerObjectSwitchStructure)
595
+ await this.renderAdditionConfigObjectSwitchStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath);
596
+ else if (structure instanceof index_1.api.ODCheckerArrayStructure)
597
+ await this.renderAdditionConfigArrayStructureSelector(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath);
598
+ else if (structure instanceof index_1.api.ODCheckerTypeSwitchStructure)
599
+ await this.renderAdditionConfigTypeSwitchStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath);
600
+ else
601
+ await backFn();
602
+ }
603
+ async renderAdditionConfigObjectStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath, localData = {}) {
604
+ const children = structure.options.children ?? [];
605
+ const skipKeys = (structure.options.cliInitSkipKeys ?? []);
606
+ //add skipped properties
607
+ for (const key of skipKeys) {
608
+ const childStructure = children.find((c) => c.key == key);
609
+ if (childStructure) {
610
+ const defaultValue = childStructure.checker.options.cliInitDefaultValue;
611
+ if (childStructure.checker instanceof index_1.api.ODCheckerBooleanStructure)
612
+ localData[key] = (typeof defaultValue == "boolean" ? defaultValue : false);
613
+ else if (childStructure.checker instanceof index_1.api.ODCheckerNumberStructure)
614
+ localData[key] = (typeof defaultValue == "number" ? defaultValue : 0);
615
+ else if (childStructure.checker instanceof index_1.api.ODCheckerStringStructure)
616
+ localData[key] = (typeof defaultValue == "string" ? defaultValue : "");
617
+ else if (childStructure.checker instanceof index_1.api.ODCheckerNullStructure)
618
+ localData[key] = (defaultValue === null ? defaultValue : null);
619
+ else if (childStructure.checker instanceof index_1.api.ODCheckerArrayStructure)
620
+ localData[key] = (Array.isArray(defaultValue) ? JSON.parse(JSON.stringify(defaultValue)) : []);
621
+ else if (childStructure.checker instanceof index_1.api.ODCheckerObjectStructure)
622
+ localData[key] = ((typeof defaultValue == "object" && !Array.isArray(defaultValue) && defaultValue) ? JSON.parse(JSON.stringify(defaultValue)) : {});
623
+ else if (childStructure.checker instanceof index_1.api.ODCheckerObjectSwitchStructure)
624
+ localData[key] = ((typeof defaultValue == "object" && !Array.isArray(defaultValue) && defaultValue) ? JSON.parse(JSON.stringify(defaultValue)) : {});
625
+ else if (childStructure.checker instanceof index_1.api.ODCheckerEnabledObjectStructure)
626
+ localData[key] = ((typeof defaultValue == "object" && !Array.isArray(defaultValue) && defaultValue) ? JSON.parse(JSON.stringify(defaultValue)) : {});
627
+ else if (childStructure.checker instanceof index_1.api.ODCheckerTypeSwitchStructure && typeof defaultValue != "undefined")
628
+ localData[key] = JSON.parse(JSON.stringify(defaultValue));
629
+ else
630
+ throw new index_1.api.ODSystemError("OD CLI => Object skip key has an invalid checker structure! key: " + key);
631
+ }
632
+ }
633
+ //add properties that need to be configured
634
+ const configChildren = children.filter((c) => !skipKeys.includes(c.key)).map((c) => { return { key: c.key, checker: c.checker }; });
635
+ await this.configureAdditionObjectProperties(checker, configChildren, 0, localData, [...path, parentIndex], (typeof parentIndex == "number") ? [...localPath] : [...localPath, parentIndex], async () => {
636
+ //go back to previous screen
637
+ await backFn();
638
+ }, async () => {
639
+ //finish setup
640
+ terminal_kit_1.terminal.bold.blue("\n\n✅ Variable saved succesfully!");
641
+ await index_1.utilities.timer(400);
642
+ await nextFn(localData);
643
+ });
644
+ }
645
+ async configureAdditionObjectProperties(checker, children, currentIndex, localData, path, localPath, backFn, nextFn) {
646
+ if (children.length < 1)
647
+ return await nextFn();
648
+ const child = children[currentIndex];
649
+ await this.chooseAdditionConfigStructure(checker, async () => {
650
+ if (children[currentIndex - 1])
651
+ await this.configureAdditionObjectProperties(checker, children, currentIndex - 1, localData, path, localPath, backFn, nextFn);
652
+ else
653
+ await backFn();
654
+ }, async (data) => {
655
+ localData[child.key] = data;
656
+ if (children[currentIndex + 1])
657
+ await this.configureAdditionObjectProperties(checker, children, currentIndex + 1, localData, path, localPath, backFn, nextFn);
658
+ else
659
+ await nextFn();
660
+ }, child.checker, localData, child.key, path, localPath);
661
+ }
662
+ async renderAdditionConfigEnabledObjectStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath) {
663
+ const enabledProperty = structure.options.property;
664
+ const enabledValue = structure.options.enabledValue;
665
+ const subStructure = structure.options.checker;
666
+ if (!enabledProperty || !subStructure || !subStructure.options.children)
667
+ return await backFn();
668
+ let propertyStructure;
669
+ if (typeof enabledValue == "string")
670
+ propertyStructure = new index_1.api.ODCheckerStringStructure("opendiscord:CLI-checker-enabled-object-structure", {});
671
+ else if (typeof enabledValue == "number")
672
+ propertyStructure = new index_1.api.ODCheckerNumberStructure("opendiscord:CLI-checker-enabled-object-structure", {});
673
+ else if (typeof enabledValue == "boolean")
674
+ propertyStructure = new index_1.api.ODCheckerBooleanStructure("opendiscord:CLI-checker-enabled-object-structure", {});
675
+ else
676
+ throw new Error("OD CLI => enabled object structure has an invalid type of enabledProperty. It must be a primitive boolean/number/string.");
677
+ const localData = {};
678
+ await this.chooseAdditionConfigStructure(checker, backFn, async (data) => {
679
+ if (data === enabledValue)
680
+ await this.renderAdditionConfigObjectStructure(checker, async () => { await this.renderAdditionConfigEnabledObjectStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath); }, nextFn, subStructure, parent, parentIndex, path, localPath, localData);
681
+ else {
682
+ localData[enabledProperty] = data;
683
+ //copy old object checker to new object checker => all options get de-referenced (this is needed for the new object skip keys are temporary)
684
+ const newStructure = new index_1.api.ODCheckerObjectStructure(subStructure.id, { children: [] });
685
+ //copy all options over to the new checker
686
+ newStructure.options.children = [...subStructure.options.children];
687
+ newStructure.options.cliInitSkipKeys = subStructure.options.children.map((child) => child.key);
688
+ for (const key of Object.keys(subStructure.options)) {
689
+ if (key != "children" && key != "cliInitSkipKeys")
690
+ newStructure.options[key] = subStructure.options[key];
691
+ }
692
+ //adds all properties to object as "skipKeys", then continues to next function
693
+ await this.renderAdditionConfigObjectStructure(checker, async () => { await this.renderAdditionConfigEnabledObjectStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath); }, nextFn, newStructure, parent, parentIndex, path, localPath, localData);
694
+ await nextFn(localData);
695
+ }
696
+ }, propertyStructure, localData, enabledProperty, [...path, parentIndex], [...localPath, parentIndex]);
697
+ }
698
+ async renderAdditionConfigObjectSwitchStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath) {
699
+ (0, cli_1.renderHeader)(this.opts, [...path, parentIndex]);
700
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("What type of object would you like to add?\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
701
+ const answer = await terminal_kit_1.terminal.singleColumnMenu(structure.options.objects.map((obj) => obj.name), {
702
+ leftPadding: "> ",
703
+ style: terminal_kit_1.terminal.cyan,
704
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
705
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
706
+ extraLines: 2,
707
+ cancelable: true
708
+ }).promise;
709
+ if (answer.canceled)
710
+ return await backFn();
711
+ const objectTemplate = structure.options.objects[answer.selectedIndex];
712
+ //copy old object checker to new object checker => all options get de-referenced (this is needed for the new object switch properties which are temporary)
713
+ const oldStructure = objectTemplate.checker;
714
+ const newStructure = new index_1.api.ODCheckerObjectStructure(oldStructure.id, { children: [] });
715
+ //copy all options over to the new checker
716
+ newStructure.options.children = [...oldStructure.options.children];
717
+ newStructure.options.cliInitSkipKeys = [...(oldStructure.options.cliInitSkipKeys ?? [])];
718
+ for (const key of Object.keys(oldStructure.options)) {
719
+ if (key != "children" && key != "cliInitSkipKeys")
720
+ newStructure.options[key] = oldStructure.options[key];
721
+ }
722
+ //add the keys of the object switch properties to the 'cliInitSkipKeys' because they need to be skipped.
723
+ objectTemplate.properties.map((p) => p.key).forEach((p) => {
724
+ if (!newStructure.options.cliInitSkipKeys)
725
+ newStructure.options.cliInitSkipKeys = [p];
726
+ else if (!newStructure.options.cliInitSkipKeys.includes(p))
727
+ newStructure.options.cliInitSkipKeys.push(p);
728
+ });
729
+ //add structure checkers for all properties
730
+ for (const prop of objectTemplate.properties) {
731
+ if (!newStructure.options.children.find((child) => child.key === prop.key)) {
732
+ if (typeof prop.value == "string")
733
+ newStructure.options.children.unshift({ key: prop.key, optional: false, priority: 1, checker: new index_1.api.ODCheckerStringStructure("opendiscord:CLI-checker-object-switch-structure", { cliInitDefaultValue: prop.value }) });
734
+ else if (typeof prop.value == "number")
735
+ newStructure.options.children.unshift({ key: prop.key, optional: false, priority: 1, checker: new index_1.api.ODCheckerNumberStructure("opendiscord:CLI-checker-object-switch-structure", { cliInitDefaultValue: prop.value }) });
736
+ else if (typeof prop.value == "boolean")
737
+ newStructure.options.children.unshift({ key: prop.key, optional: false, priority: 1, checker: new index_1.api.ODCheckerBooleanStructure("opendiscord:CLI-checker-object-switch-structure", { cliInitDefaultValue: prop.value }) });
738
+ }
739
+ }
740
+ await this.chooseAdditionConfigStructure(checker, backFn, nextFn, newStructure, parent, parentIndex, path, localPath);
741
+ }
742
+ async renderAdditionConfigBooleanStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath) {
743
+ (0, cli_1.renderHeader)(this.opts, [...path, parentIndex]);
744
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("You are now creating " + (typeof parentIndex == "string" ? "the boolean property " + ansis_1.default.blue("\"" + parentIndex + "\"") : "boolean property " + ansis_1.default.blue("#" + (parentIndex + 1))) + ".\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
745
+ terminal_kit_1.terminal.gray("\nProperty: " + ansis_1.default.bold.blue(structure.options.cliDisplayName ?? [...localPath, parentIndex].join(".")) + "\n");
746
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
747
+ const answer = await terminal_kit_1.terminal.singleColumnMenu(["false (Disabled)", "true (Enabled)"], {
748
+ leftPadding: "> ",
749
+ style: terminal_kit_1.terminal.cyan,
750
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
751
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
752
+ extraLines: 2,
753
+ cancelable: true
754
+ }).promise;
755
+ if (answer.canceled)
756
+ return await backFn();
757
+ //run config checker
758
+ const newValue = (answer.selectedIndex == 0) ? false : true;
759
+ const newPath = [...path];
760
+ newPath.shift();
761
+ checker.messages = []; //manually clear previous messages
762
+ const isDataValid = structure.check(checker, newValue, newPath);
763
+ if (isDataValid) {
764
+ terminal_kit_1.terminal.bold.blue("\n\n✅ Variable saved succesfully!");
765
+ await index_1.utilities.timer(400);
766
+ await nextFn(newValue);
767
+ }
768
+ else {
769
+ const messages = checker.messages.map((msg) => "=> [" + msg.type.toUpperCase() + "] " + msg.message).join("\n");
770
+ terminal_kit_1.terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!");
771
+ terminal_kit_1.terminal.gray("\n" + messages);
772
+ await index_1.utilities.timer(1000 + (2000 * checker.messages.length));
773
+ await this.renderAdditionConfigBooleanStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath);
774
+ }
775
+ }
776
+ async renderAdditionConfigNumberStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath, prefillValue) {
777
+ (0, cli_1.renderHeader)(this.opts, [...path, parentIndex]);
778
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("You are now creating " + (typeof parentIndex == "string" ? "the number property " + ansis_1.default.blue("\"" + parentIndex + "\"") : "number property " + ansis_1.default.blue("#" + (parentIndex + 1))) + ".\n") + ansis_1.default.italic.gray("(insert a new value and press enter, go back using escape)\n"));
779
+ terminal_kit_1.terminal.gray("\nProperty: " + ansis_1.default.bold.blue(structure.options.cliDisplayName ?? [...localPath, parentIndex].join(".")) + "\n");
780
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
781
+ const answer = await terminal_kit_1.terminal.inputField({
782
+ default: prefillValue,
783
+ style: terminal_kit_1.terminal.cyan,
784
+ cancelable: true
785
+ }).promise;
786
+ if (typeof answer != "string")
787
+ return await backFn();
788
+ //run config checker
789
+ const newValue = Number(answer.replaceAll(",", "."));
790
+ const newPath = [...path];
791
+ newPath.shift();
792
+ checker.messages = []; //manually clear previous messages
793
+ const isDataValid = structure.check(checker, newValue, newPath);
794
+ if (isDataValid) {
795
+ terminal_kit_1.terminal.bold.blue("\n\n✅ Variable saved succesfully!");
796
+ await index_1.utilities.timer(400);
797
+ await nextFn(newValue);
798
+ }
799
+ else {
800
+ const messages = checker.messages.map((msg) => "=> [" + msg.type.toUpperCase() + "] " + msg.message).join("\n");
801
+ terminal_kit_1.terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!");
802
+ terminal_kit_1.terminal.red("\n" + messages);
803
+ await index_1.utilities.timer(1000 + (2000 * checker.messages.length));
804
+ await this.renderAdditionConfigNumberStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath, answer);
805
+ }
806
+ }
807
+ async renderAdditionConfigStringStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath, prefillValue) {
808
+ (0, cli_1.renderHeader)(this.opts, [...path, parentIndex]);
809
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("You are now creating " + (typeof parentIndex == "string" ? "the string property " + ansis_1.default.blue("\"" + parentIndex + "\"") : "string property " + ansis_1.default.blue("#" + (parentIndex + 1))) + ".\n") + ansis_1.default.italic.gray("(insert a new value and press enter, go back using escape)\n"));
810
+ terminal_kit_1.terminal.gray("\nProperty: " + ansis_1.default.bold.blue(structure.options.cliDisplayName ?? [...localPath, parentIndex].join(".")) + "\n");
811
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
812
+ const customExtraOptions = (structure instanceof index_1.api.ODCheckerCustomStructure_DiscordId) ? structure.extraOptions : undefined;
813
+ const customAutocompleteFunc = structure.options.cliAutocompleteFunc ? await structure.options.cliAutocompleteFunc() : null;
814
+ const autocompleteList = ((customAutocompleteFunc ?? structure.options.cliAutocompleteList) ?? customExtraOptions) ?? structure.options.choices;
815
+ const autoCompleteMenuOpts = {
816
+ style: terminal_kit_1.terminal.white,
817
+ selectedStyle: terminal_kit_1.terminal.bgBlue.white
818
+ };
819
+ const input = terminal_kit_1.terminal.inputField({
820
+ default: prefillValue,
821
+ style: terminal_kit_1.terminal.cyan,
822
+ hintStyle: terminal_kit_1.terminal.gray,
823
+ cancelable: false,
824
+ autoComplete: autocompleteList,
825
+ autoCompleteHint: (!!autocompleteList),
826
+ autoCompleteMenu: (autocompleteList) ? autoCompleteMenuOpts : false
827
+ });
828
+ terminal_kit_1.terminal.on("key", async (name, matches, data) => {
829
+ if (name == "ESCAPE") {
830
+ terminal_kit_1.terminal.removeListener("key", "cli-render-string-structure-add");
831
+ input.abort();
832
+ await backFn();
833
+ }
834
+ }, { id: "cli-render-string-structure-add" });
835
+ const answer = await input.promise;
836
+ terminal_kit_1.terminal.removeListener("key", "cli-render-string-structure-add");
837
+ if (typeof answer != "string")
838
+ return;
839
+ //run config checker
840
+ const newValue = answer.replaceAll("\\n", "\n");
841
+ const newPath = [...path];
842
+ newPath.shift();
843
+ checker.messages = []; //manually clear previous messages
844
+ const isDataValid = structure.check(checker, newValue, newPath);
845
+ if (isDataValid) {
846
+ terminal_kit_1.terminal.bold.blue("\n\n✅ Variable saved succesfully!");
847
+ await index_1.utilities.timer(400);
848
+ await nextFn(newValue);
849
+ }
850
+ else {
851
+ const messages = checker.messages.map((msg) => "=> [" + msg.type.toUpperCase() + "] " + msg.message).join("\n");
852
+ terminal_kit_1.terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!");
853
+ terminal_kit_1.terminal.red("\n" + messages);
854
+ await index_1.utilities.timer(1000 + (2000 * checker.messages.length));
855
+ await this.renderAdditionConfigStringStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath, answer);
856
+ }
857
+ }
858
+ async renderAdditionConfigNullStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath) {
859
+ (0, cli_1.renderHeader)(this.opts, [...path, parentIndex]);
860
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("You are now creating " + (typeof parentIndex == "string" ? "the null property " + ansis_1.default.blue("\"" + parentIndex + "\"") : "null property " + ansis_1.default.blue("#" + (parentIndex + 1))) + ".\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
861
+ terminal_kit_1.terminal.gray("\nProperty: " + ansis_1.default.bold.blue(structure.options.cliDisplayName ?? [...localPath, parentIndex].join(".")) + "\n");
862
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
863
+ const answer = await terminal_kit_1.terminal.singleColumnMenu(["null"], {
864
+ leftPadding: "> ",
865
+ style: terminal_kit_1.terminal.cyan,
866
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
867
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
868
+ extraLines: 2,
869
+ cancelable: true
870
+ }).promise;
871
+ if (answer.canceled)
872
+ return await backFn();
873
+ //run config checker
874
+ const newValue = null;
875
+ const newPath = [...path];
876
+ newPath.shift();
877
+ checker.messages = []; //manually clear previous messages
878
+ const isDataValid = structure.check(checker, newValue, newPath);
879
+ if (isDataValid) {
880
+ terminal_kit_1.terminal.bold.blue("\n\n✅ Variable saved succesfully!");
881
+ await index_1.utilities.timer(400);
882
+ await nextFn(newValue);
883
+ }
884
+ else {
885
+ const messages = checker.messages.map((msg) => "=> [" + msg.type.toUpperCase() + "] " + msg.message).join("\n");
886
+ terminal_kit_1.terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!");
887
+ terminal_kit_1.terminal.red("\n" + messages);
888
+ await index_1.utilities.timer(1000 + (2000 * checker.messages.length));
889
+ await this.renderAdditionConfigNullStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath);
890
+ }
891
+ }
892
+ async renderAdditionConfigArrayStructureSelector(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath, localData = []) {
893
+ (0, cli_1.renderHeader)(this.opts, [...path, parentIndex]);
894
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("Please select what you would like to do with the new array.\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
895
+ if (!structure.options.propertyChecker)
896
+ return await backFn();
897
+ terminal_kit_1.terminal.gray("\nProperty: " + ansis_1.default.bold.blue(structure.options.cliDisplayName ?? [...localPath, parentIndex].join(".")) + "\n");
898
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
899
+ const propertyName = structure.options.cliDisplayPropertyName ?? "index";
900
+ const answer = await terminal_kit_1.terminal.singleColumnMenu(localData.length < 1 ? [ansis_1.default.magenta("-> Continue to next variable"), "Add " + propertyName] : [
901
+ ansis_1.default.magenta("-> Continue to next variable"),
902
+ "Add " + propertyName,
903
+ "Edit " + propertyName,
904
+ "Move " + propertyName,
905
+ "Remove " + propertyName,
906
+ "Duplicate " + propertyName,
907
+ ], {
908
+ leftPadding: "> ",
909
+ style: terminal_kit_1.terminal.cyan,
910
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
911
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
912
+ extraLines: 2,
913
+ cancelable: true
914
+ }).promise;
915
+ const backFnFunc = async () => { await this.renderAdditionConfigArrayStructureSelector(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath, localData); };
916
+ if (answer.canceled)
917
+ return await backFn();
918
+ if (answer.selectedIndex == 0)
919
+ await nextFn(localData);
920
+ else if (answer.selectedIndex == 1)
921
+ await this.chooseAdditionConfigStructure(checker, backFnFunc, async (newData) => {
922
+ localData[localData.length] = newData;
923
+ await backFnFunc();
924
+ }, structure.options.propertyChecker, localData, localData.length, path, []);
925
+ else if (answer.selectedIndex == 2)
926
+ await this.renderConfigArrayStructureEditSelector(checker, backFnFunc, structure, structure.options.propertyChecker, localData, parent, parentIndex, path);
927
+ else if (answer.selectedIndex == 3)
928
+ await this.renderConfigArrayStructureMoveSelector(checker, backFnFunc, structure, structure.options.propertyChecker, localData, parent, parentIndex, path);
929
+ else if (answer.selectedIndex == 4)
930
+ await this.renderConfigArrayStructureRemoveSelector(checker, backFnFunc, structure, structure.options.propertyChecker, localData, parent, parentIndex, path);
931
+ else if (answer.selectedIndex == 5)
932
+ await this.renderConfigArrayStructureDuplicateSelector(checker, backFnFunc, structure, structure.options.propertyChecker, localData, parent, parentIndex, path);
933
+ }
934
+ async renderAdditionConfigTypeSwitchStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath) {
935
+ (0, cli_1.renderHeader)(this.opts, path);
936
+ (0, terminal_kit_1.terminal)(ansis_1.default.bold.green("You are now creating " + (typeof parentIndex == "string" ? "the property " + ansis_1.default.blue("\"" + parentIndex + "\"") : "property " + ansis_1.default.blue("#" + (parentIndex + 1))) + ".\n") + ansis_1.default.italic.gray("(use arrow keys to navigate, go back using escape)\n"));
937
+ terminal_kit_1.terminal.gray("\nProperty: " + ansis_1.default.bold.blue(structure.options.cliDisplayName ?? [...localPath, parentIndex].join(".")) + "\n");
938
+ terminal_kit_1.terminal.gray("Description: " + ansis_1.default.bold(structure.options.cliDisplayDescription ?? "/") + "\n");
939
+ const actionsList = [];
940
+ if (structure.options.boolean)
941
+ actionsList.push("Create as boolean");
942
+ if (structure.options.string)
943
+ actionsList.push("Create as string");
944
+ if (structure.options.number)
945
+ actionsList.push("Create as number");
946
+ if (structure.options.object)
947
+ actionsList.push("Create as object");
948
+ if (structure.options.array)
949
+ actionsList.push("Create as array/list");
950
+ if (structure.options.null)
951
+ actionsList.push("Create as null");
952
+ const answer = await terminal_kit_1.terminal.singleColumnMenu(actionsList, {
953
+ leftPadding: "> ",
954
+ style: terminal_kit_1.terminal.cyan,
955
+ selectedStyle: terminal_kit_1.terminal.bgDefaultColor.bold,
956
+ submittedStyle: terminal_kit_1.terminal.bgBlue,
957
+ extraLines: 2,
958
+ cancelable: true
959
+ }).promise;
960
+ if (answer.canceled)
961
+ return await backFn();
962
+ //run selected structure editor (untested)
963
+ if (answer.selectedText.startsWith("Create as boolean") && structure.options.boolean)
964
+ await this.renderAdditionConfigBooleanStructure(checker, async () => { await this.renderAdditionConfigTypeSwitchStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath); }, nextFn, structure.options.boolean, parent, parentIndex, path, localPath);
965
+ else if (answer.selectedText.startsWith("Create as string") && structure.options.string)
966
+ await this.renderAdditionConfigStringStructure(checker, async () => { await this.renderAdditionConfigTypeSwitchStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath); }, nextFn, structure.options.string, parent, parentIndex, path, localPath);
967
+ else if (answer.selectedText.startsWith("Create as number") && structure.options.number)
968
+ await this.renderAdditionConfigNumberStructure(checker, async () => { await this.renderAdditionConfigTypeSwitchStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath); }, nextFn, structure.options.number, parent, parentIndex, path, localPath);
969
+ else if (answer.selectedText.startsWith("Create as object") && structure.options.object)
970
+ await this.renderAdditionConfigObjectStructure(checker, async () => { await this.renderAdditionConfigTypeSwitchStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath); }, nextFn, structure.options.object, parent, parentIndex, path, localPath);
971
+ else if (answer.selectedText.startsWith("Create as array/list") && structure.options.array)
972
+ await this.renderAdditionConfigArrayStructureSelector(checker, async () => { await this.renderAdditionConfigTypeSwitchStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath); }, nextFn, structure.options.array, parent, parentIndex, path, localPath);
973
+ else if (answer.selectedText.startsWith("Create as null") && structure.options.null)
974
+ await this.renderAdditionConfigNullStructure(checker, async () => { await this.renderAdditionConfigTypeSwitchStructure(checker, backFn, nextFn, structure, parent, parentIndex, path, localPath); }, nextFn, structure.options.null, parent, parentIndex, path, localPath);
975
+ }
976
+ }
977
+ exports.ODCliEditConfigInstance = ODCliEditConfigInstance;