@open-discord-bots/framework 0.0.1 → 0.0.2

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.
Files changed (103) hide show
  1. package/LICENSE.md +713 -0
  2. package/README.md +104 -0
  3. package/dist/api/api.d.ts +26 -0
  4. package/dist/api/api.js +44 -0
  5. package/dist/api/main.d.ts +133 -0
  6. package/dist/api/main.js +87 -0
  7. package/dist/api/modules/action.d.ts +34 -0
  8. package/dist/api/modules/action.js +58 -0
  9. package/dist/api/modules/base.d.ts +329 -0
  10. package/dist/api/modules/base.js +804 -0
  11. package/dist/api/modules/builder.d.ts +647 -0
  12. package/dist/api/modules/builder.js +1441 -0
  13. package/dist/api/modules/checker.d.ts +648 -0
  14. package/dist/api/modules/checker.js +1324 -0
  15. package/dist/api/modules/client.d.ts +768 -0
  16. package/dist/api/modules/client.js +1859 -0
  17. package/dist/api/modules/code.d.ts +33 -0
  18. package/dist/api/modules/code.js +57 -0
  19. package/dist/api/modules/config.d.ts +70 -0
  20. package/dist/api/modules/config.js +206 -0
  21. package/dist/api/modules/console.d.ts +305 -0
  22. package/dist/api/modules/console.js +598 -0
  23. package/dist/api/modules/cooldown.d.ts +138 -0
  24. package/dist/api/modules/cooldown.js +359 -0
  25. package/dist/api/modules/database.d.ts +135 -0
  26. package/dist/api/modules/database.js +271 -0
  27. package/dist/api/modules/event.d.ts +43 -0
  28. package/dist/api/modules/event.js +100 -0
  29. package/dist/api/modules/flag.d.ts +40 -0
  30. package/dist/api/modules/flag.js +72 -0
  31. package/dist/api/modules/fuse.d.ts +218 -0
  32. package/dist/api/modules/fuse.js +123 -0
  33. package/dist/api/modules/helpmenu.d.ts +106 -0
  34. package/dist/api/modules/helpmenu.js +167 -0
  35. package/dist/api/modules/language.d.ts +85 -0
  36. package/dist/api/modules/language.js +195 -0
  37. package/dist/api/modules/permission.d.ts +121 -0
  38. package/dist/api/modules/permission.js +314 -0
  39. package/dist/api/modules/plugin.d.ts +128 -0
  40. package/dist/api/modules/plugin.js +168 -0
  41. package/dist/api/modules/post.d.ts +44 -0
  42. package/dist/api/modules/post.js +92 -0
  43. package/dist/api/modules/progressbar.d.ts +108 -0
  44. package/dist/api/modules/progressbar.js +233 -0
  45. package/dist/api/modules/responder.d.ts +506 -0
  46. package/dist/api/modules/responder.js +1468 -0
  47. package/dist/api/modules/session.d.ts +58 -0
  48. package/dist/api/modules/session.js +171 -0
  49. package/dist/api/modules/startscreen.d.ts +165 -0
  50. package/dist/api/modules/startscreen.js +293 -0
  51. package/dist/api/modules/stat.d.ts +142 -0
  52. package/dist/api/modules/stat.js +293 -0
  53. package/dist/api/modules/verifybar.d.ts +54 -0
  54. package/dist/api/modules/verifybar.js +60 -0
  55. package/dist/api/modules/worker.d.ts +41 -0
  56. package/dist/api/modules/worker.js +93 -0
  57. package/dist/api/utils.d.ts +61 -0
  58. package/dist/api/utils.js +254 -0
  59. package/dist/index.d.ts +4 -1
  60. package/dist/index.js +40 -0
  61. package/dist/startup/dump.d.ts +14 -0
  62. package/dist/startup/dump.js +79 -0
  63. package/dist/startup/errorHandling.d.ts +2 -0
  64. package/dist/startup/errorHandling.js +43 -0
  65. package/dist/startup/pluginLauncher.d.ts +2 -0
  66. package/dist/startup/pluginLauncher.js +202 -0
  67. package/package.json +9 -3
  68. package/src/api/api.ts +29 -0
  69. package/src/api/main.ts +189 -0
  70. package/src/api/modules/action.ts +58 -0
  71. package/src/api/modules/base.ts +811 -0
  72. package/src/api/modules/builder.ts +1554 -0
  73. package/src/api/modules/checker.ts +1549 -0
  74. package/src/api/modules/client.ts +2247 -0
  75. package/src/api/modules/code.ts +58 -0
  76. package/src/api/modules/config.ts +159 -0
  77. package/src/api/modules/console.ts +665 -0
  78. package/src/api/modules/cooldown.ts +348 -0
  79. package/src/api/modules/database.ts +278 -0
  80. package/src/api/modules/event.ts +99 -0
  81. package/src/api/modules/flag.ts +73 -0
  82. package/src/api/modules/fuse.ts +348 -0
  83. package/src/api/modules/helpmenu.ts +216 -0
  84. package/src/api/modules/language.ts +201 -0
  85. package/src/api/modules/permission.ts +340 -0
  86. package/src/api/modules/plugin.ts +242 -0
  87. package/src/api/modules/post.ts +90 -0
  88. package/src/api/modules/progressbar.ts +232 -0
  89. package/src/api/modules/responder.ts +1420 -0
  90. package/src/api/modules/session.ts +155 -0
  91. package/src/api/modules/startscreen.ts +320 -0
  92. package/src/api/modules/stat.ts +313 -0
  93. package/src/api/modules/verifybar.ts +61 -0
  94. package/src/api/modules/worker.ts +93 -0
  95. package/src/api/utils.ts +206 -0
  96. package/src/cli/cli.ts +151 -0
  97. package/src/cli/editConfig.ts +943 -0
  98. package/src/index.ts +6 -1
  99. package/src/startup/compilation.ts +186 -0
  100. package/src/startup/dump.ts +45 -0
  101. package/src/startup/errorHandling.ts +38 -0
  102. package/src/startup/pluginLauncher.ts +261 -0
  103. package/LICENSE +0 -21
@@ -0,0 +1,1324 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ODCheckerCustomStructure_UniqueIdArray = exports.ODCheckerCustomStructure_UniqueId = exports.ODCheckerCustomStructure_UrlString = exports.ODCheckerCustomStructure_EmojiString = exports.ODCheckerCustomStructure_HexColor = exports.ODCheckerCustomStructure_DiscordToken = exports.ODCheckerCustomStructure_DiscordIdArray = exports.ODCheckerCustomStructure_DiscordId = exports.ODCheckerEnabledObjectStructure = exports.ODCheckerObjectSwitchStructure = exports.ODCheckerTypeSwitchStructure = exports.ODCheckerNullStructure = exports.ODCheckerArrayStructure = exports.ODCheckerBooleanStructure = exports.ODCheckerNumberStructure = exports.ODCheckerStringStructure = exports.ODCheckerObjectStructure = exports.ODCheckerStructure = exports.ODChecker = exports.ODCheckerFunctionManager = exports.ODCheckerFunction = exports.ODCheckerTranslationRegister = exports.ODCheckerRenderer = exports.ODCheckerStorage = exports.ODCheckerManager = void 0;
4
+ ///////////////////////////////////////
5
+ //CONFIG CHECKER MODULE
6
+ ///////////////////////////////////////
7
+ const base_1 = require("./base");
8
+ const config_1 = require("./config");
9
+ /**## ODCheckerManager `class`
10
+ * This is an Open Discord checker manager.
11
+ *
12
+ * It manages all config checkers in the bot and allows plugins to access config checkers from Open Discord & other plugins!
13
+ *
14
+ * You can use this class to get/add a config checker (`ODChecker`) in your plugin!
15
+ */
16
+ class ODCheckerManager extends base_1.ODManager {
17
+ /**The global temporary storage shared between all config checkers. */
18
+ storage;
19
+ /**The class responsible for rendering the config checker report. */
20
+ renderer;
21
+ /**The class responsible for translating the config checker report. */
22
+ translation;
23
+ /**Final functions are global functions executed just before the report is created. */
24
+ functions;
25
+ /**A variable containing the last result returned from `checkAll()` */
26
+ lastResult = null;
27
+ constructor(debug, storage, renderer, translation, functions) {
28
+ super(debug, "config checker");
29
+ this.storage = storage;
30
+ this.renderer = renderer;
31
+ this.translation = translation;
32
+ this.functions = functions;
33
+ }
34
+ /**Check all config checkers registered in this manager.*/
35
+ checkAll(sort) {
36
+ this.storage.reset();
37
+ let isValid = true;
38
+ const final = [];
39
+ const checkers = this.getAll();
40
+ checkers.sort((a, b) => b.priority - a.priority);
41
+ checkers.forEach((checker) => {
42
+ const res = checker.check();
43
+ final.push(...res.messages);
44
+ if (!res.valid)
45
+ isValid = false;
46
+ });
47
+ this.functions.getAll().forEach((func) => {
48
+ const res = func.func(this, this.functions);
49
+ final.push(...res.messages);
50
+ if (!res.valid)
51
+ isValid = false;
52
+ });
53
+ //sort messages => (info, warning, error)
54
+ if (sort)
55
+ final.sort((a, b) => {
56
+ const typeA = (a.type == "error") ? 2 : (a.type == "warning") ? 1 : 0;
57
+ const typeB = (b.type == "error") ? 2 : (b.type == "warning") ? 1 : 0;
58
+ return typeA - typeB;
59
+ });
60
+ this.lastResult = {
61
+ valid: isValid,
62
+ messages: final
63
+ };
64
+ return {
65
+ valid: isValid,
66
+ messages: final
67
+ };
68
+ }
69
+ /**Create temporary and unlisted `ODConfig`, `ODChecker` & `ODCheckerStorage` classes. This will help you use a `ODCheckerStructure` validator without officially registering it in `opendiscord.checkers`. */
70
+ createTemporaryCheckerEnvironment() {
71
+ return new ODChecker("opendiscord:temporary-environment", new ODCheckerStorage(), 0, new config_1.ODConfig("opendiscord:temporary-environment", {}), new ODCheckerStructure("opendiscord:temporary-environment", {}));
72
+ }
73
+ }
74
+ exports.ODCheckerManager = ODCheckerManager;
75
+ /**## ODCheckerStorage `class`
76
+ * This is an Open Discord checker storage.
77
+ *
78
+ * It stores temporary data to share between config checkers!
79
+ * (e.g. The `messages.json` needs to access the `"id"` from `options.json`)
80
+ *
81
+ *
82
+ * You can use this class when you create your own config checker implementation! (not required for using the built-in config checker)
83
+ */
84
+ class ODCheckerStorage {
85
+ /**This is the array that stores all the data. ❌ **(don't edit unless really needed!)***/
86
+ storage = [];
87
+ /**Get data from the database (`source` => id of `ODChecker`) */
88
+ get(source, key) {
89
+ const result = this.storage.find(d => (d.source.value == new base_1.ODId(source).value) && (d.key == key));
90
+ return (result) ? result.value : null;
91
+ }
92
+ /**Add data to the database (`source` => id of `ODChecker`). This function also overwrites existing data!*/
93
+ set(source, key, value) {
94
+ const index = this.storage.findIndex(d => (d.source.value == new base_1.ODId(source).value) && (d.key == key));
95
+ if (index > -1) {
96
+ //overwrite
97
+ this.storage[index] = {
98
+ source: new base_1.ODId(source),
99
+ key, value
100
+ };
101
+ return true;
102
+ }
103
+ else {
104
+ this.storage.push({
105
+ source: new base_1.ODId(source),
106
+ key, value
107
+ });
108
+ return false;
109
+ }
110
+ }
111
+ /**Delete data from the database (`source` => id of `ODChecker`) */
112
+ delete(source, key) {
113
+ const index = this.storage.findIndex(d => (d.source.value == new base_1.ODId(source).value) && (d.key == key));
114
+ if (index > -1) {
115
+ //delete
116
+ this.storage.splice(index, 1);
117
+ return true;
118
+ }
119
+ else
120
+ return false;
121
+ }
122
+ /**Reset the entire database */
123
+ reset() {
124
+ this.storage = [];
125
+ }
126
+ }
127
+ exports.ODCheckerStorage = ODCheckerStorage;
128
+ /**## ODCheckerRenderer `class`
129
+ * This is an Open Discord checker renderer.
130
+ *
131
+ * It's responsible for rendering the config checker result in the console.
132
+ * This class doesn't provide any components! You need to create them by extending this class
133
+ *
134
+ * You can use this class if you want to change how the config checker looks!
135
+ */
136
+ class ODCheckerRenderer {
137
+ /**Get all components */
138
+ getComponents(compact, renderEmpty, translation, data) {
139
+ return [];
140
+ }
141
+ /**Render all components */
142
+ render(components) {
143
+ if (components.length < 1)
144
+ return;
145
+ console.log("\n");
146
+ components.forEach((c) => {
147
+ console.log(c);
148
+ });
149
+ console.log("\n");
150
+ }
151
+ }
152
+ exports.ODCheckerRenderer = ODCheckerRenderer;
153
+ /**## ODCheckerTranslationRegister `class`
154
+ * This is an Open Discord checker translation register.
155
+ *
156
+ * It's used to store & manage the translation for each message from the config checker!
157
+ * Most translations are stored by message id, but there are some exceptions like the additional text on the checker report.
158
+ *
159
+ * You can use this class if you want to translate your config checker messages! **This is optional & isn't required for the checker to work!**
160
+ */
161
+ class ODCheckerTranslationRegister {
162
+ /**This is the array that stores all the data. ❌ **(don't edit unless really needed!)***/
163
+ #translations = [];
164
+ /**Get the translation from a config checker message/sentence */
165
+ get(type, id) {
166
+ const result = this.#translations.find(d => (d.id == id) && (d.type == type));
167
+ return (result) ? result.translation : null;
168
+ }
169
+ /**Set the translation for a config checker message/sentence. This function also overwrites existing translations!*/
170
+ set(type, id, translation) {
171
+ const index = this.#translations.findIndex(d => (d.id == id) && (d.type == type));
172
+ if (index > -1) {
173
+ //overwrite
174
+ this.#translations[index] = { type, id, translation };
175
+ return true;
176
+ }
177
+ else {
178
+ this.#translations.push({ type, id, translation });
179
+ return false;
180
+ }
181
+ }
182
+ /**Delete the translation for a config checker message/sentence. */
183
+ delete(type, id) {
184
+ const index = this.#translations.findIndex(d => (d.id == id) && (d.type == type));
185
+ if (index > -1) {
186
+ //delete
187
+ this.#translations.splice(index, 1);
188
+ return true;
189
+ }
190
+ else
191
+ return false;
192
+ }
193
+ /**Get all translations */
194
+ getAll() {
195
+ return this.#translations;
196
+ }
197
+ /**Insert the translation params into the text. */
198
+ insertTranslationParams(text, translationParams) {
199
+ translationParams.forEach((value, index) => {
200
+ text = text.replace(`{${index}}`, value);
201
+ });
202
+ return text;
203
+ }
204
+ /**A shortcut to copy translations from the `ODLanguageManager` to `ODCheckerTranslationRegister` */
205
+ quickTranslate(manager, translationId, type, id) {
206
+ const translation = manager.getTranslation(translationId);
207
+ if (translation)
208
+ this.set(type, id, translation);
209
+ }
210
+ }
211
+ exports.ODCheckerTranslationRegister = ODCheckerTranslationRegister;
212
+ /**## ODCheckerFunction `class`
213
+ * This is an Open Discord config checker function.
214
+ *
215
+ * It is a global function that will be executed after all config checkers. It can do additional checks for invalid/missing configurations.
216
+ * It's mostly used for things that need to be checked globally!
217
+ */
218
+ class ODCheckerFunction extends base_1.ODManagerData {
219
+ /**The function which will be executed globally after all config checkers. */
220
+ func;
221
+ constructor(id, func) {
222
+ super(id);
223
+ this.func = func;
224
+ }
225
+ }
226
+ exports.ODCheckerFunction = ODCheckerFunction;
227
+ /**## ODCheckerFunctionManager `class`
228
+ * This is an Open Discord config checker function manager.
229
+ *
230
+ * It manages all `ODCheckerFunction`'s and it has some extra shortcuts for frequently used methods.
231
+ */
232
+ class ODCheckerFunctionManager extends base_1.ODManager {
233
+ constructor(debug) {
234
+ super(debug, "config checker function");
235
+ }
236
+ /**A shortcut to create a warning, info or error message */
237
+ createMessage(checkerId, id, filepath, type, message, locationTrace, docs, translationParams, locationId, locationDocs) {
238
+ return {
239
+ checkerId: new base_1.ODId(checkerId),
240
+ messageId: new base_1.ODId(id),
241
+ locationId,
242
+ type, message,
243
+ path: this.locationTraceToString(locationTrace),
244
+ filepath,
245
+ translationParams,
246
+ messageDocs: docs,
247
+ locationDocs
248
+ };
249
+ }
250
+ /**Create a string from the location trace (path)*/
251
+ locationTraceToString(trace) {
252
+ const final = [];
253
+ trace.forEach((t) => {
254
+ if (typeof t == "number") {
255
+ final.push(`:${t}`);
256
+ }
257
+ else {
258
+ final.push(`."${t}"`);
259
+ }
260
+ });
261
+ return final.join("").substring(1);
262
+ }
263
+ /**De-reference the locationTrace array. Use this before adding a value to the array*/
264
+ locationTraceDeref(trace) {
265
+ return JSON.parse(JSON.stringify(trace));
266
+ }
267
+ }
268
+ exports.ODCheckerFunctionManager = ODCheckerFunctionManager;
269
+ /**## ODChecker `class`
270
+ * This is an Open Discord config checker.
271
+ *
272
+ * It checks a specific config file for invalid/missing configurations. This data can then be used to show to the user what's wrong!
273
+ * You can check for example if a string is longer/shorter than a certain amount of characters & more!
274
+ *
275
+ * You can use this class when you create your own custom config file & you want to check it for syntax errors.
276
+ */
277
+ class ODChecker extends base_1.ODManagerData {
278
+ /**The storage of this checker (reference for `ODCheckerManager.storage`) */
279
+ storage;
280
+ /**The higher the priority, the faster it gets checked! */
281
+ priority;
282
+ /**The config file that needs to be checked */
283
+ config;
284
+ /**The structure of the config file */
285
+ structure;
286
+ /**Temporary storage for all error messages from the check() method (not recommended to use) */
287
+ messages = [];
288
+ /**Temporary storage for the quit status from the check() method (not recommended to use) */
289
+ quit = false;
290
+ /**All additional properties of this config checker. */
291
+ options;
292
+ constructor(id, storage, priority, config, structure, options) {
293
+ super(id);
294
+ this.storage = storage;
295
+ this.priority = priority;
296
+ this.config = config;
297
+ this.structure = structure;
298
+ this.options = options ?? {};
299
+ }
300
+ /**Get a human-readable number string. */
301
+ #ordinalNumber(num) {
302
+ const i = Math.abs(Math.round(num));
303
+ const cent = i % 100;
304
+ if (cent >= 10 && cent <= 20)
305
+ return i + 'th';
306
+ const dec = i % 10;
307
+ if (dec === 1)
308
+ return i + 'st';
309
+ if (dec === 2)
310
+ return i + 'nd';
311
+ if (dec === 3)
312
+ return i + 'rd';
313
+ return i + 'th';
314
+ }
315
+ /**Run this checker. Returns all errors*/
316
+ check() {
317
+ this.messages = [];
318
+ this.quit = false;
319
+ this.structure.check(this, this.config.data, []);
320
+ return {
321
+ valid: !this.quit,
322
+ messages: this.messages
323
+ };
324
+ }
325
+ /**Create a string from the location trace/path in a human readable format. */
326
+ locationTraceToString(trace) {
327
+ const final = [];
328
+ trace.forEach((t) => {
329
+ if (typeof t == "number") {
330
+ final.push(`:(${this.#ordinalNumber(t + 1)})`);
331
+ }
332
+ else {
333
+ final.push(`."${t}"`);
334
+ }
335
+ });
336
+ return final.join("").substring(1);
337
+ }
338
+ /**De-reference the locationTrace array. Use this before adding a value to the array*/
339
+ locationTraceDeref(trace) {
340
+ return JSON.parse(JSON.stringify(trace));
341
+ }
342
+ /**A shortcut to create a warning, info or error message */
343
+ createMessage(id, type, message, locationTrace, docs, translationParams, locationId, locationDocs) {
344
+ if (type == "error")
345
+ this.quit = true;
346
+ this.messages.push({
347
+ checkerId: this.id,
348
+ messageId: new base_1.ODId(id),
349
+ locationId,
350
+ type, message,
351
+ path: this.locationTraceToString(locationTrace),
352
+ filepath: this.config.path,
353
+ translationParams,
354
+ messageDocs: docs,
355
+ locationDocs
356
+ });
357
+ }
358
+ }
359
+ exports.ODChecker = ODChecker;
360
+ /**## ODCheckerStructure `class`
361
+ * This is an Open Discord config checker structure.
362
+ *
363
+ * This class will check for a single variable in a config file, customise it in the settings!
364
+ * If you want prebuilt checkers (for strings, booleans, numbers, ...), check the other `ODCheckerStructure`'s!
365
+ *
366
+ * **Not recommended to use!** It's recommended to extend from another `ODConfigCheckerStructure` class!
367
+ */
368
+ class ODCheckerStructure {
369
+ /**The id of this checker structure */
370
+ id;
371
+ /**The options for this checker structure */
372
+ options;
373
+ constructor(id, options) {
374
+ this.id = new base_1.ODId(id);
375
+ this.options = options;
376
+ }
377
+ /**Check a variable if it matches all settings in this checker. This function is automatically executed by Open Discord! */
378
+ check(checker, value, locationTrace) {
379
+ if (typeof this.options.custom != "undefined") {
380
+ return this.options.custom(checker, value, locationTrace, this.id, (this.options.docs ?? null));
381
+ }
382
+ else
383
+ return true;
384
+ }
385
+ }
386
+ exports.ODCheckerStructure = ODCheckerStructure;
387
+ /**## ODCheckerObjectStructure `class`
388
+ * This is an Open Discord config checker structure.
389
+ *
390
+ * This class will check for an object variable in a config file, customise it in the settings!
391
+ * A checker for the children can be set in the settings.
392
+ */
393
+ class ODCheckerObjectStructure extends ODCheckerStructure {
394
+ constructor(id, options) {
395
+ super(id, options);
396
+ }
397
+ check(checker, value, locationTrace) {
398
+ const lt = checker.locationTraceDeref(locationTrace);
399
+ //check type & options
400
+ if (typeof value != "object") {
401
+ checker.createMessage("opendiscord:invalid-type", "error", "This property needs to be the type: object!", lt, null, ["object"], this.id, (this.options.docs ?? null));
402
+ return false;
403
+ }
404
+ //sort children
405
+ if (typeof this.options.children == "undefined")
406
+ return super.check(checker, value, locationTrace);
407
+ const sortedChildren = this.options.children.sort((a, b) => {
408
+ if ((a.priority ?? 0) < (b.priority ?? 0))
409
+ return -1;
410
+ else if ((a.priority ?? 0) > (b.priority ?? 0))
411
+ return 1;
412
+ else
413
+ return 0;
414
+ });
415
+ //check children
416
+ let localQuit = false;
417
+ sortedChildren.forEach((child) => {
418
+ const localLt = checker.locationTraceDeref(lt);
419
+ localLt.push(child.key);
420
+ if (typeof value[child.key] == "undefined") {
421
+ if (!child.optional) {
422
+ localQuit = true;
423
+ checker.createMessage("opendiscord:property-missing", "error", `The property "${child.key}" is mising from this object!`, lt, null, [`"${child.key}"`], this.id, (this.options.docs ?? null));
424
+ }
425
+ else {
426
+ checker.createMessage("opendiscord:property-optional", "info", `The property "${child.key}" is optional in this object!`, lt, null, [`"${child.key}"`], this.id, (this.options.docs ?? null));
427
+ }
428
+ }
429
+ else if (!child.checker.check(checker, value[child.key], localLt))
430
+ localQuit = true;
431
+ });
432
+ //do local quit or check custom function
433
+ if (localQuit)
434
+ return false;
435
+ else
436
+ return super.check(checker, value, locationTrace);
437
+ }
438
+ }
439
+ exports.ODCheckerObjectStructure = ODCheckerObjectStructure;
440
+ /**## ODCheckerStringStructure `class`
441
+ * This is an Open Discord config checker structure.
442
+ *
443
+ * This class will check for a string variable in a config file, customise it in the settings!
444
+ */
445
+ class ODCheckerStringStructure extends ODCheckerStructure {
446
+ constructor(id, options) {
447
+ super(id, options);
448
+ }
449
+ check(checker, value, locationTrace) {
450
+ const lt = checker.locationTraceDeref(locationTrace);
451
+ //check type & options
452
+ if (typeof value != "string") {
453
+ checker.createMessage("opendiscord:invalid-type", "error", "This property needs to be the type: string!", lt, null, ["string"], this.id, (this.options.docs ?? null));
454
+ return false;
455
+ }
456
+ else if (typeof this.options.minLength != "undefined" && value.length < this.options.minLength) {
457
+ checker.createMessage("opendiscord:string-too-short", "error", `This string can't be shorter than ${this.options.minLength} characters!`, lt, null, [this.options.minLength.toString()], this.id, (this.options.docs ?? null));
458
+ return false;
459
+ }
460
+ else if (typeof this.options.maxLength != "undefined" && value.length > this.options.maxLength) {
461
+ checker.createMessage("opendiscord:string-too-long", "error", `This string can't be longer than ${this.options.maxLength} characters!`, lt, null, [this.options.maxLength.toString()], this.id, (this.options.docs ?? null));
462
+ return false;
463
+ }
464
+ else if (typeof this.options.length != "undefined" && value.length !== this.options.length) {
465
+ checker.createMessage("opendiscord:string-length-invalid", "error", `This string needs to be ${this.options.length} characters long!`, lt, null, [this.options.length.toString()], this.id, (this.options.docs ?? null));
466
+ return false;
467
+ }
468
+ else if (typeof this.options.startsWith != "undefined" && !value.startsWith(this.options.startsWith)) {
469
+ checker.createMessage("opendiscord:string-starts-with", "error", `This string needs to start with "${this.options.startsWith}"!`, lt, null, [`"${this.options.startsWith}"`], this.id, (this.options.docs ?? null));
470
+ return false;
471
+ }
472
+ else if (typeof this.options.endsWith != "undefined" && !value.endsWith(this.options.endsWith)) {
473
+ checker.createMessage("opendiscord:string-ends-with", "error", `This string needs to end with "${this.options.endsWith}"!`, lt, null, [`"${this.options.endsWith}"`], this.id, (this.options.docs ?? null));
474
+ return false;
475
+ }
476
+ else if (typeof this.options.contains != "undefined" && !value.includes(this.options.contains)) {
477
+ checker.createMessage("opendiscord:string-contains", "error", `This string needs to contain "${this.options.contains}"!`, lt, null, [`"${this.options.contains}"`], this.id, (this.options.docs ?? null));
478
+ return false;
479
+ }
480
+ else if (typeof this.options.invertedContains != "undefined" && value.includes(this.options.invertedContains)) {
481
+ checker.createMessage("opendiscord:string-inverted-contains", "error", `This string is not allowed to contain "${this.options.invertedContains}"!`, lt, null, [`"${this.options.invertedContains}"`], this.id, (this.options.docs ?? null));
482
+ return false;
483
+ }
484
+ else if (typeof this.options.choices != "undefined" && !this.options.choices.includes(value)) {
485
+ checker.createMessage("opendiscord:string-choices", "error", `This string can only be one of the following values: "${this.options.choices.join(`", "`)}"!`, lt, null, [`"${this.options.choices.join(`", "`)}"`], this.id, (this.options.docs ?? null));
486
+ return false;
487
+ }
488
+ else if (this.options.lowercaseOnly && value !== value.toLowerCase()) {
489
+ checker.createMessage("opendiscord:string-lowercase", "error", `This string must be written in lowercase only!`, lt, null, [], this.id, (this.options.docs ?? null));
490
+ return false;
491
+ }
492
+ else if (this.options.uppercaseOnly && value !== value.toUpperCase()) {
493
+ checker.createMessage("opendiscord:string-uppercase", "error", `This string must be written in uppercase only!`, lt, null, [], this.id, (this.options.docs ?? null));
494
+ return false;
495
+ }
496
+ else if (this.options.noSpecialCharacters && !/^[A-Za-z0-9 ]*$/.test(value)) {
497
+ checker.createMessage("opendiscord:string-special-characters", "error", `This string is not allowed to contain any special characters! (a-z, 0-9 & space only)`, lt, null, [], this.id, (this.options.docs ?? null));
498
+ return false;
499
+ }
500
+ else if (this.options.withoutSpaces && value.includes(" ")) {
501
+ checker.createMessage("opendiscord:string-no-spaces", "error", `This string is not allowed to contain spaces!`, lt, null, [], this.id, (this.options.docs ?? null));
502
+ return false;
503
+ }
504
+ else if (typeof this.options.regex != "undefined" && !this.options.regex.test(value)) {
505
+ checker.createMessage("opendiscord:string-regex", "error", "This string is invalid!", lt, null, [], this.id, (this.options.docs ?? null));
506
+ return false;
507
+ }
508
+ else {
509
+ //warnings
510
+ if ((this.options.capitalLetterWarning == "word" && !value.split(" ").every((word) => word.length == 0 || /^[^a-z].*/.test(word))))
511
+ checker.createMessage("opendiscord:string-capital-word", "warning", `It's recommended that each word in this string starts with a capital letter!`, lt, null, [], this.id, (this.options.docs ?? null));
512
+ if ((this.options.capitalLetterWarning == "sentence" && !value.split(/ *[.?!] */).every((sentence) => sentence.length == 0 || /^[^a-z].*/.test(sentence))))
513
+ checker.createMessage("opendiscord:string-capital-sentence", "warning", `It looks like some sentences in this string don't start with a capital letter!`, lt, null, [], this.id, (this.options.docs ?? null));
514
+ if (this.options.punctuationWarning && value.length > 0 && (!value.endsWith(".") && !value.endsWith("?") && !value.endsWith("!") && !value.endsWith("'") && !value.endsWith('"') && !value.endsWith(",") && !value.endsWith(";") && !value.endsWith(":") && !value.endsWith("=")))
515
+ checker.createMessage("opendiscord:string-punctuation", "warning", `It looks like the sentence in this string doesn't end with a punctuation mark!`, lt, null, [], this.id, (this.options.docs ?? null));
516
+ return super.check(checker, value, locationTrace);
517
+ }
518
+ }
519
+ }
520
+ exports.ODCheckerStringStructure = ODCheckerStringStructure;
521
+ /**## ODCheckerNumberStructure `class`
522
+ * This is an Open Discord config checker structure.
523
+ *
524
+ * This class will check for a number variable in a config file, customise it in the settings!
525
+ */
526
+ class ODCheckerNumberStructure extends ODCheckerStructure {
527
+ constructor(id, options) {
528
+ super(id, options);
529
+ }
530
+ check(checker, value, locationTrace) {
531
+ const lt = checker.locationTraceDeref(locationTrace);
532
+ //offset for step
533
+ const stepOffset = (typeof this.options.offset != "undefined") ? this.options.offset : 0;
534
+ //check type & options
535
+ if (typeof value != "number") {
536
+ checker.createMessage("opendiscord:invalid-type", "error", "This property needs to be the type: number!", lt, null, ["number"], this.id, (this.options.docs ?? null));
537
+ return false;
538
+ }
539
+ else if (!this.options.nanAllowed && isNaN(value)) {
540
+ checker.createMessage("opendiscord:number-nan", "error", `This number can't be NaN (Not A Number)!`, lt, null, [], this.id, (this.options.docs ?? null));
541
+ return false;
542
+ }
543
+ else if (typeof this.options.minLength != "undefined" && value.toString().length < this.options.minLength) {
544
+ checker.createMessage("opendiscord:number-too-short", "error", `This number can't be shorter than ${this.options.minLength} characters!`, lt, null, [this.options.minLength.toString()], this.id, (this.options.docs ?? null));
545
+ return false;
546
+ }
547
+ else if (typeof this.options.maxLength != "undefined" && value.toString().length > this.options.maxLength) {
548
+ checker.createMessage("opendiscord:number-too-long", "error", `This number can't be longer than ${this.options.maxLength} characters!`, lt, null, [this.options.maxLength.toString()], this.id, (this.options.docs ?? null));
549
+ return false;
550
+ }
551
+ else if (typeof this.options.length != "undefined" && value.toString().length !== this.options.length) {
552
+ checker.createMessage("opendiscord:number-length-invalid", "error", `This number needs to be ${this.options.length} characters long!`, lt, null, [this.options.length.toString()], this.id, (this.options.docs ?? null));
553
+ return false;
554
+ }
555
+ else if (typeof this.options.min != "undefined" && value < this.options.min) {
556
+ checker.createMessage("opendiscord:number-too-small", "error", `This number needs to be at least ${this.options.min}!`, lt, null, [this.options.min.toString()], this.id, (this.options.docs ?? null));
557
+ return false;
558
+ }
559
+ else if (typeof this.options.max != "undefined" && value > this.options.max) {
560
+ checker.createMessage("opendiscord:number-too-large", "error", `This number needs to be at most ${this.options.max}!`, lt, null, [this.options.max.toString()], this.id, (this.options.docs ?? null));
561
+ return false;
562
+ }
563
+ else if (typeof this.options.is != "undefined" && value == this.options.is) {
564
+ checker.createMessage("opendiscord:number-not-equal", "error", `This number needs to be ${this.options.is}!`, lt, null, [this.options.is.toString()], this.id, (this.options.docs ?? null));
565
+ return false;
566
+ }
567
+ else if (typeof this.options.step != "undefined" && ((value - stepOffset) % this.options.step) !== 0) {
568
+ if (stepOffset > 0)
569
+ checker.createMessage("opendiscord:number-step-offset", "error", `This number needs to be a multiple of ${this.options.step} starting with ${stepOffset}!`, lt, null, [this.options.step.toString(), stepOffset.toString()], this.id, (this.options.docs ?? null));
570
+ else
571
+ checker.createMessage("opendiscord:number-step", "error", `This number needs to be a multiple of ${this.options.step}!`, lt, null, [this.options.step.toString()], this.id, (this.options.docs ?? null));
572
+ return false;
573
+ }
574
+ else if (typeof this.options.startsWith != "undefined" && !value.toString().startsWith(this.options.startsWith)) {
575
+ checker.createMessage("opendiscord:number-starts-with", "error", `This number needs to start with "${this.options.startsWith}"!`, lt, null, [`"${this.options.startsWith}"`], this.id, (this.options.docs ?? null));
576
+ return false;
577
+ }
578
+ else if (typeof this.options.endsWith != "undefined" && !value.toString().endsWith(this.options.endsWith)) {
579
+ checker.createMessage("opendiscord:number-ends-with", "error", `This number needs to end with "${this.options.endsWith}"!`, lt, null, [`"${this.options.endsWith}"`], this.id, (this.options.docs ?? null));
580
+ return false;
581
+ }
582
+ else if (typeof this.options.contains != "undefined" && !value.toString().includes(this.options.contains)) {
583
+ checker.createMessage("opendiscord:number-contains", "error", `This number needs to contain "${this.options.contains}"!`, lt, null, [`"${this.options.contains}"`], this.id, (this.options.docs ?? null));
584
+ return false;
585
+ }
586
+ else if (typeof this.options.invertedContains != "undefined" && value.toString().includes(this.options.invertedContains)) {
587
+ checker.createMessage("opendiscord:number-inverted-contains", "error", `This number is not allowed to contain "${this.options.invertedContains}"!`, lt, null, [`"${this.options.invertedContains}"`], this.id, (this.options.docs ?? null));
588
+ return false;
589
+ }
590
+ else if (typeof this.options.choices != "undefined" && !this.options.choices.includes(value)) {
591
+ checker.createMessage("opendiscord:number-choices", "error", `This number can only be one of the following values: "${this.options.choices.join(`", "`)}"!`, lt, null, [`"${this.options.choices.join(`", "`)}"`], this.id, (this.options.docs ?? null));
592
+ return false;
593
+ }
594
+ else if (typeof this.options.floatAllowed != "undefined" && !this.options.floatAllowed && (value % 1) !== 0) {
595
+ checker.createMessage("opendiscord:number-float", "error", "This number can't be a decimal!", lt, null, [], this.id, (this.options.docs ?? null));
596
+ return false;
597
+ }
598
+ else if (typeof this.options.negativeAllowed != "undefined" && !this.options.negativeAllowed && value < 0) {
599
+ checker.createMessage("opendiscord:number-negative", "error", "This number can't be negative!", lt, null, [], this.id, (this.options.docs ?? null));
600
+ return false;
601
+ }
602
+ else if (typeof this.options.positiveAllowed != "undefined" && !this.options.positiveAllowed && value > 0) {
603
+ checker.createMessage("opendiscord:number-positive", "error", "This number can't be positive!", lt, null, [], this.id, (this.options.docs ?? null));
604
+ return false;
605
+ }
606
+ else if (typeof this.options.zeroAllowed != "undefined" && !this.options.zeroAllowed && value === 0) {
607
+ checker.createMessage("opendiscord:number-zero", "error", "This number can't be zero!", lt, null, [], this.id, (this.options.docs ?? null));
608
+ return false;
609
+ }
610
+ else
611
+ return super.check(checker, value, locationTrace);
612
+ }
613
+ }
614
+ exports.ODCheckerNumberStructure = ODCheckerNumberStructure;
615
+ /**## ODCheckerBooleanStructure `class`
616
+ * This is an Open Discord config checker structure.
617
+ *
618
+ * This class will check for a boolean variable in a config file, customise it in the settings!
619
+ */
620
+ class ODCheckerBooleanStructure extends ODCheckerStructure {
621
+ constructor(id, options) {
622
+ super(id, options);
623
+ }
624
+ check(checker, value, locationTrace) {
625
+ const lt = checker.locationTraceDeref(locationTrace);
626
+ //check type & options
627
+ if (typeof value != "boolean") {
628
+ checker.createMessage("opendiscord:invalid-type", "error", "This property needs to be the type: boolean!", lt, null, ["boolean"], this.id, (this.options.docs ?? null));
629
+ return false;
630
+ }
631
+ else if (typeof this.options.trueAllowed != "undefined" && !this.options.trueAllowed && value == true) {
632
+ checker.createMessage("opendiscord:boolean-true", "error", "This boolean can't be true!", lt, null, [], this.id, (this.options.docs ?? null));
633
+ return false;
634
+ }
635
+ else if (typeof this.options.falseAllowed != "undefined" && !this.options.falseAllowed && value == false) {
636
+ checker.createMessage("opendiscord:boolean-false", "error", "This boolean can't be false!", lt, null, [], this.id, (this.options.docs ?? null));
637
+ return false;
638
+ }
639
+ else
640
+ return super.check(checker, value, locationTrace);
641
+ }
642
+ }
643
+ exports.ODCheckerBooleanStructure = ODCheckerBooleanStructure;
644
+ /**## ODCheckerArrayStructure `class`
645
+ * This is an Open Discord config checker structure.
646
+ *
647
+ * This class will check for an array variable in a config file, customise it in the settings!
648
+ */
649
+ class ODCheckerArrayStructure extends ODCheckerStructure {
650
+ constructor(id, options) {
651
+ super(id, options);
652
+ }
653
+ check(checker, value, locationTrace) {
654
+ const lt = checker.locationTraceDeref(locationTrace);
655
+ if (!Array.isArray(value)) {
656
+ checker.createMessage("opendiscord:invalid-type", "error", "This property needs to be the type: array!", lt, null, ["array"], this.id, (this.options.docs ?? null));
657
+ return false;
658
+ }
659
+ else if (typeof this.options.disableEmpty != "undefined" && this.options.disableEmpty && value.length == 0) {
660
+ checker.createMessage("opendiscord:array-empty-disabled", "error", "This array isn't allowed to be empty!", lt, null, [], this.id, (this.options.docs ?? null));
661
+ return false;
662
+ }
663
+ else if (typeof this.options.emptyRequired != "undefined" && this.options.emptyRequired && value.length != 0) {
664
+ checker.createMessage("opendiscord:array-empty-required", "error", "This array is required to be empty!", lt, null, [], this.id, (this.options.docs ?? null));
665
+ return false;
666
+ }
667
+ else if (typeof this.options.minLength != "undefined" && value.length < this.options.minLength) {
668
+ checker.createMessage("opendiscord:array-too-short", "error", `This array needs to have a length of at least ${this.options.minLength}!`, lt, null, [this.options.minLength.toString()], this.id, (this.options.docs ?? null));
669
+ return false;
670
+ }
671
+ else if (typeof this.options.maxLength != "undefined" && value.length > this.options.maxLength) {
672
+ checker.createMessage("opendiscord:array-too-long", "error", `This array needs to have a length of at most ${this.options.maxLength}!`, lt, null, [this.options.maxLength.toString()], this.id, (this.options.docs ?? null));
673
+ return false;
674
+ }
675
+ else if (typeof this.options.length != "undefined" && value.length == this.options.length) {
676
+ checker.createMessage("opendiscord:array-length-invalid", "error", `This array needs to have a length of ${this.options.length}!`, lt, null, [this.options.length.toString()], this.id, (this.options.docs ?? null));
677
+ return false;
678
+ }
679
+ else if (typeof this.options.allowedTypes != "undefined" && !this.#arrayAllowedTypesCheck(value, this.options.allowedTypes)) {
680
+ checker.createMessage("opendiscord:array-invalid-types", "error", `This array can only contain the following types: ${this.options.allowedTypes.join(", ")}!`, lt, null, [this.options.allowedTypes.join(", ").toString()], this.id, (this.options.docs ?? null));
681
+ return false;
682
+ }
683
+ else if (typeof this.options.allowDoubles != "undefined" && !this.options.allowDoubles && this.#arrayHasDoubles(value)) {
684
+ checker.createMessage("opendiscord:array-double", "error", "This array doesn't allow the same value twice!", lt, null, [], this.id, (this.options.docs ?? null));
685
+ return false;
686
+ }
687
+ else {
688
+ //check all properties
689
+ let localQuit = false;
690
+ if (this.options.propertyChecker)
691
+ value.forEach((property, index) => {
692
+ if (!this.options.propertyChecker)
693
+ return;
694
+ const localLt = checker.locationTraceDeref(lt);
695
+ localLt.push(index);
696
+ if (!this.options.propertyChecker.check(checker, property, localLt))
697
+ localQuit = true;
698
+ });
699
+ //return false if invalid properties
700
+ if (localQuit) {
701
+ checker.quit = true;
702
+ return false;
703
+ }
704
+ else
705
+ return super.check(checker, value, locationTrace);
706
+ }
707
+ }
708
+ /**Check this array for the allowed types */
709
+ #arrayAllowedTypesCheck(array, allowedTypes) {
710
+ //return TRUE if ALL values are valid
711
+ return !array.some((value) => {
712
+ if (allowedTypes.includes("string") && typeof value == "string") {
713
+ return false; //this value is valid
714
+ }
715
+ else if (allowedTypes.includes("number") && typeof value == "number") {
716
+ return false; //this value is valid
717
+ }
718
+ else if (allowedTypes.includes("boolean") && typeof value == "boolean") {
719
+ return false; //this value is valid
720
+ }
721
+ else if (allowedTypes.includes("object") && typeof value == "object") {
722
+ return false; //this value is valid
723
+ }
724
+ else if (allowedTypes.includes("array") && Array.isArray(value)) {
725
+ return false; //this value is valid
726
+ }
727
+ else if (allowedTypes.includes("null") && value === null) {
728
+ return false; //this value is valid
729
+ }
730
+ else if (allowedTypes.includes("other")) {
731
+ return false; //this value is valid
732
+ }
733
+ else {
734
+ return true; //this value is invalid
735
+ }
736
+ });
737
+ }
738
+ /**Check this array for doubles */
739
+ #arrayHasDoubles(array) {
740
+ const alreadyFound = [];
741
+ let hasDoubles = false;
742
+ array.forEach((value) => {
743
+ if (alreadyFound.includes(value))
744
+ hasDoubles = true;
745
+ else
746
+ alreadyFound.push(value);
747
+ });
748
+ return hasDoubles;
749
+ }
750
+ }
751
+ exports.ODCheckerArrayStructure = ODCheckerArrayStructure;
752
+ /**## ODCheckerNullStructure `class`
753
+ * This is an Open Discord config checker structure.
754
+ *
755
+ * This class will check for a null variable in a config file, customise it in the settings!
756
+ */
757
+ class ODCheckerNullStructure extends ODCheckerStructure {
758
+ constructor(id, options) {
759
+ super(id, options);
760
+ }
761
+ check(checker, value, locationTrace) {
762
+ const lt = checker.locationTraceDeref(locationTrace);
763
+ //check type & options
764
+ if (typeof this.options.nullAllowed != "undefined" && !this.options.nullAllowed && value == null) {
765
+ checker.createMessage("opendiscord:null-invalid", "error", "This property can't be null!", lt, null, [], this.id, (this.options.docs ?? null));
766
+ return false;
767
+ }
768
+ else if (value !== null) {
769
+ checker.createMessage("opendiscord:invalid-type", "error", "This property needs to be the type: null!", lt, null, ["null"], this.id, (this.options.docs ?? null));
770
+ return false;
771
+ }
772
+ else
773
+ return super.check(checker, value, locationTrace);
774
+ }
775
+ }
776
+ exports.ODCheckerNullStructure = ODCheckerNullStructure;
777
+ /**## ODCheckerTypeSwitchStructure `class`
778
+ * This is an Open Discord config checker structure.
779
+ *
780
+ * This class will switch checkers based on the type of the variable in a config file, customise it in the settings!
781
+ */
782
+ class ODCheckerTypeSwitchStructure extends ODCheckerStructure {
783
+ constructor(id, options) {
784
+ super(id, options);
785
+ }
786
+ check(checker, value, locationTrace) {
787
+ const lt = checker.locationTraceDeref(locationTrace);
788
+ if (this.options.all) {
789
+ return this.options.all.check(checker, value, lt);
790
+ }
791
+ else if (this.options.string && typeof value == "string") {
792
+ return this.options.string.check(checker, value, lt);
793
+ }
794
+ else if (this.options.number && typeof value == "number") {
795
+ return this.options.number.check(checker, value, lt);
796
+ }
797
+ else if (this.options.boolean && typeof value == "boolean") {
798
+ return this.options.boolean.check(checker, value, lt);
799
+ }
800
+ else if (this.options.array && Array.isArray(value)) {
801
+ return this.options.array.check(checker, value, lt);
802
+ }
803
+ else if (this.options.null && value === null) {
804
+ return this.options.null.check(checker, value, lt);
805
+ }
806
+ else if (this.options.object && typeof value == "object") {
807
+ return this.options.object.check(checker, value, lt);
808
+ }
809
+ else if (this.options.other) {
810
+ return this.options.other.check(checker, value, lt);
811
+ }
812
+ else if (this.options.allowedTypes && this.options.allowedTypes.length > 0) {
813
+ checker.createMessage("opendiscord:switch-invalid-type", "error", `This needs to be one of the following types: ${this.options.allowedTypes.join(", ")}!`, lt, null, [this.options.allowedTypes.join(", ")], this.id, (this.options.docs ?? null));
814
+ return false;
815
+ }
816
+ else
817
+ return super.check(checker, value, locationTrace);
818
+ }
819
+ }
820
+ exports.ODCheckerTypeSwitchStructure = ODCheckerTypeSwitchStructure;
821
+ /**## ODCheckerObjectSwitchStructure `class`
822
+ * This is an Open Discord config checker structure.
823
+ *
824
+ * This class will switch object checkers based on a variable match in one of the objects, customise it in the settings!
825
+ */
826
+ class ODCheckerObjectSwitchStructure extends ODCheckerStructure {
827
+ constructor(id, options) {
828
+ super(id, options);
829
+ }
830
+ check(checker, value, locationTrace) {
831
+ const lt = checker.locationTraceDeref(locationTrace);
832
+ if (this.options.objects) {
833
+ //check type & options
834
+ if (typeof value != "object") {
835
+ checker.createMessage("opendiscord:invalid-type", "error", "This property needs to be the type: object!", lt, null, ["object"], this.id, (this.options.docs ?? null));
836
+ return false;
837
+ }
838
+ //sort objects
839
+ const sortedObjects = this.options.objects.sort((a, b) => {
840
+ if (a.priority < b.priority)
841
+ return -1;
842
+ else if (a.priority > b.priority)
843
+ return 1;
844
+ else
845
+ return 0;
846
+ });
847
+ //check objects
848
+ let localQuit = false;
849
+ let didSelectObject = false;
850
+ sortedObjects.forEach((obj) => {
851
+ if (!obj.properties.some((p) => value[p.key] !== p.value)) {
852
+ didSelectObject = true;
853
+ if (!obj.checker.check(checker, value, lt))
854
+ localQuit = true;
855
+ }
856
+ });
857
+ //do local quit or check custom function
858
+ if (!didSelectObject) {
859
+ checker.createMessage("opendiscord:object-switch-invalid-type", "error", `This object needs to be one of the following types: ${this.options.objects.map((obj) => obj.name).join(", ")}!`, lt, null, [this.options.objects.map((obj) => obj.name).join(", ")], this.id, (this.options.docs ?? null));
860
+ return false;
861
+ }
862
+ else if (localQuit) {
863
+ return false;
864
+ }
865
+ else
866
+ return super.check(checker, value, locationTrace);
867
+ }
868
+ else
869
+ return super.check(checker, value, locationTrace);
870
+ }
871
+ }
872
+ exports.ODCheckerObjectSwitchStructure = ODCheckerObjectSwitchStructure;
873
+ /**## ODCheckerEnabledObjectStructure `class`
874
+ * This is an Open Discord config checker structure.
875
+ *
876
+ * This class will enable an object checker based on a variable match in the object, customise it in the settings!
877
+ */
878
+ class ODCheckerEnabledObjectStructure extends ODCheckerStructure {
879
+ constructor(id, options) {
880
+ super(id, options);
881
+ }
882
+ check(checker, value, locationTrace) {
883
+ const lt = checker.locationTraceDeref(locationTrace);
884
+ if (typeof value != "object") {
885
+ //value isn't an object
886
+ checker.createMessage("opendiscord:invalid-type", "error", "This property needs to be the type: object!", lt, null, ["object"], this.id, (this.options.docs ?? null));
887
+ return false;
888
+ }
889
+ else if (this.options.property && typeof value[this.options.property] == "undefined") {
890
+ //property doesn't exist
891
+ checker.createMessage("opendiscord:property-missing", "error", `The property "${this.options.property}" is mising from this object!`, lt, null, [`"${this.options.property}"`], this.id, (this.options.docs ?? null));
892
+ return false;
893
+ }
894
+ else if (this.options.property && value[this.options.property] === (typeof this.options.enabledValue == "undefined" ? true : this.options.enabledValue)) {
895
+ //this object is enabled
896
+ if (this.options.checker)
897
+ return this.options.checker.check(checker, value, lt);
898
+ else
899
+ return super.check(checker, value, locationTrace);
900
+ }
901
+ else {
902
+ //this object is disabled
903
+ if (this.options.property)
904
+ checker.createMessage("opendiscord:object-disabled", "info", `This object is disabled, enable it using "${this.options.property}"!`, lt, null, [`"${this.options.property}"`], this.id, (this.options.docs ?? null));
905
+ return super.check(checker, value, locationTrace);
906
+ }
907
+ }
908
+ }
909
+ exports.ODCheckerEnabledObjectStructure = ODCheckerEnabledObjectStructure;
910
+ /**## ODCheckerCustomStructure_DiscordId `class`
911
+ * This is an Open Discord custom checker structure.
912
+ *
913
+ * This class extends a primitive config checker & adds another layer of checking in the `custom` function.
914
+ * You can compare it to a blueprint for a specific checker.
915
+ *
916
+ * **This custom checker is made for discord ids (channel, user, role, ...)**
917
+ */
918
+ class ODCheckerCustomStructure_DiscordId extends ODCheckerStringStructure {
919
+ /**The type of id (used in rendering) */
920
+ type;
921
+ /**Is this id allowed to be empty */
922
+ emptyAllowed;
923
+ /**Extra matches (value will also be valid when one of these options match) */
924
+ extraOptions;
925
+ constructor(id, type, emptyAllowed, extraOptions, options) {
926
+ //add premade custom structure checker
927
+ const newOptions = options ?? {};
928
+ newOptions.custom = (checker, value, locationTrace, locationId, locationDocs) => {
929
+ const lt = checker.locationTraceDeref(locationTrace);
930
+ if (typeof value != "string")
931
+ return false;
932
+ else if ((!emptyAllowed && value.length < 15) || value.length > 50 || !/^[0-9]*$/.test(value)) {
933
+ if (!(extraOptions.length > 0 && extraOptions.some((opt) => opt == value))) {
934
+ //value is not an id & not one of the extra options
935
+ if (extraOptions.length > 0)
936
+ checker.createMessage("opendiscord:discord-invalid-id-options", "error", `This is an invalid discord ${type} id! You can also use one of these: ${extraOptions.join(", ")}!`, lt, null, [type, extraOptions.join(", ")], this.id, (this.options.docs ?? null));
937
+ else
938
+ checker.createMessage("opendiscord:discord-invalid-id", "error", `This is an invalid discord ${type} id!`, lt, null, [type], this.id, (this.options.docs ?? null));
939
+ return false;
940
+ }
941
+ else
942
+ return true;
943
+ }
944
+ return true;
945
+ };
946
+ super(id, newOptions);
947
+ this.type = type;
948
+ this.emptyAllowed = emptyAllowed;
949
+ this.extraOptions = extraOptions;
950
+ }
951
+ }
952
+ exports.ODCheckerCustomStructure_DiscordId = ODCheckerCustomStructure_DiscordId;
953
+ /**## ODCheckerCustomStructure_DiscordIdArray `class`
954
+ * This is an Open Discord custom checker structure.
955
+ *
956
+ * This class extends a primitive config checker & adds another layer of checking in the `custom` function.
957
+ * You can compare it to a blueprint for a specific checker.
958
+ *
959
+ * **This custom checker is made for discord id arrays (channel, user, role, ...)**
960
+ */
961
+ class ODCheckerCustomStructure_DiscordIdArray extends ODCheckerArrayStructure {
962
+ /**The type of id (used in rendering) */
963
+ type;
964
+ /**Extra matches (value will also be valid when one of these options match) */
965
+ extraOptions;
966
+ constructor(id, type, extraOptions, options, idOptions) {
967
+ //add premade custom structure checker
968
+ const newOptions = options ?? {};
969
+ newOptions.propertyChecker = new ODCheckerCustomStructure_DiscordId(id, type, false, extraOptions, idOptions);
970
+ super(id, newOptions);
971
+ this.type = type;
972
+ this.extraOptions = extraOptions;
973
+ }
974
+ }
975
+ exports.ODCheckerCustomStructure_DiscordIdArray = ODCheckerCustomStructure_DiscordIdArray;
976
+ /**## ODCheckerCustomStructure_DiscordToken `class`
977
+ * This is an Open Discord custom checker structure.
978
+ *
979
+ * This class extends a primitive config checker & adds another layer of checking in the `custom` function.
980
+ * You can compare it to a blueprint for a specific checker.
981
+ *
982
+ * **This custom checker is made for a discord (auth) token**
983
+ */
984
+ class ODCheckerCustomStructure_DiscordToken extends ODCheckerStringStructure {
985
+ constructor(id, options) {
986
+ //add premade custom structure checker
987
+ const newOptions = options ?? {};
988
+ newOptions.custom = (checker, value, locationTrace, locationId, locationDocs) => {
989
+ const lt = checker.locationTraceDeref(locationTrace);
990
+ if (typeof value != "string" || !/^[A-Za-z0-9-_\.]+$/.test(value)) {
991
+ checker.createMessage("opendiscord:discord-invalid-token", "error", "This is an invalid discord token (syntactically)!", lt, null, [], this.id, (this.options.docs ?? null));
992
+ return false;
993
+ }
994
+ return true;
995
+ };
996
+ super(id, newOptions);
997
+ }
998
+ }
999
+ exports.ODCheckerCustomStructure_DiscordToken = ODCheckerCustomStructure_DiscordToken;
1000
+ /**## ODCheckerCustomStructure_DiscordToken `class`
1001
+ * This is an Open Discord custom checker structure.
1002
+ *
1003
+ * This class extends a primitive config checker & adds another layer of checking in the `custom` function.
1004
+ * You can compare it to a blueprint for a specific checker.
1005
+ *
1006
+ * **This custom checker is made for a hex color**
1007
+ */
1008
+ class ODCheckerCustomStructure_HexColor extends ODCheckerStringStructure {
1009
+ /**When enabled, you are also allowed to use `#fff` instead of `#ffffff` */
1010
+ allowShortForm;
1011
+ /**Allow this hex color to be empty. */
1012
+ emptyAllowed;
1013
+ constructor(id, allowShortForm, emptyAllowed, options) {
1014
+ //add premade custom structure checker
1015
+ const newOptions = options ?? {};
1016
+ newOptions.custom = (checker, value, locationTrace, locationId, locationDocs) => {
1017
+ const lt = checker.locationTraceDeref(locationTrace);
1018
+ if (typeof value != "string")
1019
+ return false;
1020
+ else if (emptyAllowed && value.length == 0) {
1021
+ return true;
1022
+ }
1023
+ else if ((!allowShortForm && !/^#[a-fA-F0-9]{6}$/.test(value)) || (allowShortForm && !/^#[a-fA-F0-9]{6}$/.test(value) && !/^#[a-fA-F0-9]{3}$/.test(value))) {
1024
+ checker.createMessage("opendiscord:color-invalid", "error", "This is an invalid hex color!", lt, null, [], this.id, (this.options.docs ?? null));
1025
+ return false;
1026
+ }
1027
+ else
1028
+ return true;
1029
+ };
1030
+ super(id, newOptions);
1031
+ this.allowShortForm = allowShortForm;
1032
+ this.emptyAllowed = emptyAllowed;
1033
+ }
1034
+ }
1035
+ exports.ODCheckerCustomStructure_HexColor = ODCheckerCustomStructure_HexColor;
1036
+ /**## ODCheckerCustomStructure_EmojiString `class`
1037
+ * This is an Open Discord custom checker structure.
1038
+ *
1039
+ * This class extends a primitive config checker & adds another layer of checking in the `custom` function.
1040
+ * You can compare it to a blueprint for a specific checker.
1041
+ *
1042
+ * **This custom checker is made for an emoji (string)**
1043
+ */
1044
+ class ODCheckerCustomStructure_EmojiString extends ODCheckerStringStructure {
1045
+ /**The minimum amount of emojis required (0 to allow empty) */
1046
+ minLength;
1047
+ /**The maximum amount of emojis allowed */
1048
+ maxLength;
1049
+ /**Allow custom discord emoji ids (`<:12345678910:emoji_name>`) */
1050
+ allowCustomDiscordEmoji;
1051
+ constructor(id, minLength, maxLength, allowCustomDiscordEmoji, options) {
1052
+ //add premade custom structure checker
1053
+ const newOptions = options ?? {};
1054
+ newOptions.custom = (checker, value, locationTrace, locationId, locationDocs) => {
1055
+ const lt = checker.locationTraceDeref(locationTrace);
1056
+ if (typeof value != "string")
1057
+ return false;
1058
+ const discordEmojiSplitter = /(?:<a?:[^:]*:[0-9]+>)/g;
1059
+ const splitted = value.split(discordEmojiSplitter);
1060
+ const discordEmojiAmount = splitted.length - 1;
1061
+ const unicodeEmojiAmount = [...new Intl.Segmenter().segment(splitted.join(""))].length;
1062
+ const emojiAmount = discordEmojiAmount + unicodeEmojiAmount;
1063
+ if (emojiAmount < minLength) {
1064
+ checker.createMessage("opendiscord:emoji-too-short", "error", `This string needs to have at least ${minLength} emoji's!`, lt, null, [maxLength.toString()], this.id, (this.options.docs ?? null));
1065
+ return false;
1066
+ }
1067
+ else if (emojiAmount > maxLength) {
1068
+ checker.createMessage("opendiscord:emoji-too-long", "error", `This string needs to have at most ${maxLength} emoji's!`, lt, null, [maxLength.toString()], this.id, (this.options.docs ?? null));
1069
+ return false;
1070
+ }
1071
+ else if (!allowCustomDiscordEmoji && /<a?:[^:]*:[0-9]+>/.test(value)) {
1072
+ checker.createMessage("opendiscord:emoji-custom", "error", `This emoji can't be a custom discord emoji!`, lt, null, [], this.id, (this.options.docs ?? null));
1073
+ return false;
1074
+ }
1075
+ else if (!/^(?:\p{Emoji}|\p{Emoji_Component}|(?:<a?:[^:]*:[0-9]+>))*$/u.test(value)) {
1076
+ checker.createMessage("opendiscord:emoji-invalid", "error", "This is an invalid emoji!", lt, null, [], this.id, (this.options.docs ?? null));
1077
+ return false;
1078
+ }
1079
+ return true;
1080
+ };
1081
+ super(id, newOptions);
1082
+ this.minLength = minLength;
1083
+ this.maxLength = maxLength;
1084
+ this.allowCustomDiscordEmoji = allowCustomDiscordEmoji;
1085
+ }
1086
+ }
1087
+ exports.ODCheckerCustomStructure_EmojiString = ODCheckerCustomStructure_EmojiString;
1088
+ /**## ODCheckerCustomStructure_UrlString `class`
1089
+ * This is an Open Discord custom checker structure.
1090
+ *
1091
+ * This class extends a primitive config checker & adds another layer of checking in the `custom` function.
1092
+ * You can compare it to a blueprint for a specific checker.
1093
+ *
1094
+ * **This custom checker is made for a URL (string)**
1095
+ */
1096
+ class ODCheckerCustomStructure_UrlString extends ODCheckerStringStructure {
1097
+ /**The settings for this url */
1098
+ urlSettings;
1099
+ /**Is this url allowed to be empty? */
1100
+ emptyAllowed;
1101
+ constructor(id, emptyAllowed, urlSettings, options) {
1102
+ //add premade custom structure checker
1103
+ const newOptions = options ?? {};
1104
+ newOptions.custom = (checker, value, locationTrace, locationId, locationDocs) => {
1105
+ const lt = checker.locationTraceDeref(locationTrace);
1106
+ if (typeof value != "string")
1107
+ return false;
1108
+ else if (emptyAllowed && value.length == 0) {
1109
+ return true;
1110
+ }
1111
+ else if (!this.#urlIsValid(value)) {
1112
+ checker.createMessage("opendiscord:url-invalid", "error", "This url is invalid!", lt, null, [], this.id, (this.options.docs ?? null));
1113
+ return false;
1114
+ }
1115
+ else if (typeof this.urlSettings.allowHttp != "undefined" && !this.urlSettings.allowHttp && !/^(https:\/\/)/.test(value)) {
1116
+ checker.createMessage("opendiscord:url-invalid-http", "error", "This url can only use the https:// protocol!", lt, null, [], this.id, (this.options.docs ?? null));
1117
+ return false;
1118
+ }
1119
+ else if (!/^(http(s)?:\/\/)/.test(value)) {
1120
+ checker.createMessage("opendiscord:url-invalid-protocol", "error", "This url can only use the http:// & https:// protocols!", lt, null, [], this.id, (this.options.docs ?? null));
1121
+ return false;
1122
+ }
1123
+ else if (typeof this.urlSettings.allowedHostnames != "undefined" && !this.#urlHasValidHostname(value, this.urlSettings.allowedHostnames)) {
1124
+ checker.createMessage("opendiscord:url-invalid-hostname", "error", "This url has a disallowed hostname!", lt, null, [], this.id, (this.options.docs ?? null));
1125
+ return false;
1126
+ }
1127
+ else if (typeof this.urlSettings.allowedExtensions != "undefined" && !this.#urlHasValidExtension(value, this.urlSettings.allowedExtensions)) {
1128
+ checker.createMessage("opendiscord:url-invalid-extension", "error", `This url has an invalid extension! Choose between: ${this.urlSettings.allowedExtensions.join(", ")}!"`, lt, null, [this.urlSettings.allowedExtensions.join(", ")], this.id, (this.options.docs ?? null));
1129
+ return false;
1130
+ }
1131
+ else if (typeof this.urlSettings.allowedPaths != "undefined" && !this.#urlHasValidPath(value, this.urlSettings.allowedPaths)) {
1132
+ checker.createMessage("opendiscord:url-invalid-path", "error", "This url has an invalid path!", lt, null, [], this.id, (this.options.docs ?? null));
1133
+ return false;
1134
+ }
1135
+ else if (typeof this.urlSettings.regex != "undefined" && !this.urlSettings.regex.test(value)) {
1136
+ checker.createMessage("opendiscord:url-invalid", "error", "This url is invalid!", lt, null, [], this.id, (this.options.docs ?? null));
1137
+ return false;
1138
+ }
1139
+ else
1140
+ return true;
1141
+ };
1142
+ super(id, newOptions);
1143
+ this.urlSettings = urlSettings;
1144
+ this.emptyAllowed = emptyAllowed;
1145
+ }
1146
+ /**Check for the hostname */
1147
+ #urlHasValidHostname(url, hostnames) {
1148
+ try {
1149
+ const hostname = new URL(url).hostname;
1150
+ return hostnames.some((rule) => {
1151
+ if (typeof rule == "string") {
1152
+ return rule == hostname;
1153
+ }
1154
+ else {
1155
+ return rule.test(hostname);
1156
+ }
1157
+ });
1158
+ }
1159
+ catch {
1160
+ return false;
1161
+ }
1162
+ }
1163
+ /**Check for the extension */
1164
+ #urlHasValidExtension(url, extensions) {
1165
+ try {
1166
+ const path = new URL(url).pathname;
1167
+ return extensions.some((rule) => {
1168
+ return path.endsWith(rule);
1169
+ });
1170
+ }
1171
+ catch {
1172
+ return false;
1173
+ }
1174
+ }
1175
+ /**Check for the path */
1176
+ #urlHasValidPath(url, paths) {
1177
+ try {
1178
+ const path = new URL(url).pathname;
1179
+ return paths.some((rule) => {
1180
+ if (typeof rule == "string") {
1181
+ return rule == path;
1182
+ }
1183
+ else {
1184
+ return rule.test(path);
1185
+ }
1186
+ });
1187
+ }
1188
+ catch {
1189
+ return false;
1190
+ }
1191
+ }
1192
+ /**Do general syntax check on url */
1193
+ #urlIsValid(url) {
1194
+ try {
1195
+ new URL(url);
1196
+ return true;
1197
+ }
1198
+ catch {
1199
+ return false;
1200
+ }
1201
+ }
1202
+ }
1203
+ exports.ODCheckerCustomStructure_UrlString = ODCheckerCustomStructure_UrlString;
1204
+ /**## ODCheckerCustomStructure_UniqueId `class`
1205
+ * This is an Open Discord custom checker structure.
1206
+ *
1207
+ * This class extends a primitive config checker & adds another layer of checking in the `custom` function.
1208
+ * You can compare it to a blueprint for a specific checker.
1209
+ *
1210
+ * **This custom checker is made for a unique id (per source & scope)**
1211
+ */
1212
+ class ODCheckerCustomStructure_UniqueId extends ODCheckerStringStructure {
1213
+ /**The source of this unique id (generally the plugin name or `opendiscord`) */
1214
+ source;
1215
+ /**The scope of this unique id (id needs to be unique in this scope) */
1216
+ scope;
1217
+ constructor(id, source, scope, options) {
1218
+ //add premade custom structure checker
1219
+ const newOptions = options ?? {};
1220
+ newOptions.custom = (checker, value, locationTrace, locationId, locationDocs) => {
1221
+ const lt = checker.locationTraceDeref(locationTrace);
1222
+ if (typeof value != "string")
1223
+ return false;
1224
+ const uniqueArray = (checker.storage.get(source, scope) === null) ? [] : checker.storage.get(source, scope);
1225
+ if (uniqueArray.includes(value)) {
1226
+ //unique id already exists => throw error
1227
+ checker.createMessage("opendiscord:id-not-unique", "error", "This id isn't unique, use another id instead!", lt, null, [], this.id, (this.options.docs ?? null));
1228
+ return false;
1229
+ }
1230
+ else {
1231
+ //unique id doesn't exists => add to list
1232
+ uniqueArray.push(value);
1233
+ checker.storage.set(source, scope, uniqueArray);
1234
+ return true;
1235
+ }
1236
+ };
1237
+ super(id, newOptions);
1238
+ this.source = source;
1239
+ this.scope = scope;
1240
+ }
1241
+ }
1242
+ exports.ODCheckerCustomStructure_UniqueId = ODCheckerCustomStructure_UniqueId;
1243
+ /**## ODCheckerCustomStructure_UniqueIdArray `class`
1244
+ * This is an Open Discord custom checker structure.
1245
+ *
1246
+ * This class extends a primitive config checker & adds another layer of checking in the `custom` function.
1247
+ * You can compare it to a blueprint for a specific checker.
1248
+ *
1249
+ * **This custom checker is made for a unique id array (per source & scope)**
1250
+ */
1251
+ class ODCheckerCustomStructure_UniqueIdArray extends ODCheckerArrayStructure {
1252
+ /**The source to read unique ids (generally the plugin name or `opendiscord`) */
1253
+ source;
1254
+ /**The scope to read unique ids (id needs to be unique in this scope) */
1255
+ scope;
1256
+ /**The scope to push unique ids when used in this array! */
1257
+ usedScope;
1258
+ constructor(id, source, scope, usedScope, options, idOptions) {
1259
+ //add premade custom structure checker
1260
+ const newOptions = options ?? {};
1261
+ newOptions.propertyChecker = new ODCheckerStringStructure("opendiscord:unique-id", { ...(idOptions ?? {}), minLength: 1, custom: (checker, value, locationTrace, locationId, locationDocs) => {
1262
+ if (typeof value != "string")
1263
+ return false;
1264
+ const localLt = checker.locationTraceDeref(locationTrace);
1265
+ localLt.pop();
1266
+ const uniqueArray = checker.storage.get(source, scope) ?? [];
1267
+ if (uniqueArray.includes(value)) {
1268
+ //exists
1269
+ if (usedScope) {
1270
+ const current = checker.storage.get(source, usedScope) ?? [];
1271
+ current.push(value);
1272
+ checker.storage.set(source, usedScope, current);
1273
+ }
1274
+ return true;
1275
+ }
1276
+ else {
1277
+ //doesn't exist
1278
+ checker.createMessage("opendiscord:id-non-existent", "error", `The id "${value}" doesn't exist!`, localLt, null, [`"${value}"`], locationId, locationDocs);
1279
+ return false;
1280
+ }
1281
+ } });
1282
+ super(id, newOptions);
1283
+ this.source = source;
1284
+ this.scope = scope;
1285
+ this.usedScope = usedScope ?? null;
1286
+ }
1287
+ }
1288
+ exports.ODCheckerCustomStructure_UniqueIdArray = ODCheckerCustomStructure_UniqueIdArray;
1289
+ /*TEMPLATE!!!!
1290
+ export interface ODCheckerTemplateStructureOptions extends ODCheckerStructureOptions {
1291
+
1292
+ }
1293
+ export class ODCheckerTemplateStructure extends ODCheckerStructure {
1294
+ declare options: ODCheckerTemplateStructureOptions
1295
+
1296
+ constructor(id:ODValidId, options:ODCheckerTemplateStructureOptions){
1297
+ super(id,options)
1298
+ }
1299
+
1300
+ check(checker:ODChecker, value:any, locationTrace:ODCheckerLocationTrace): boolean {
1301
+ const lt = checker.locationTraceDeref(locationTrace)
1302
+
1303
+ return super.check(checker,value,locationTrace)
1304
+ }
1305
+ }
1306
+ */
1307
+ /*CUSTOM TEMPLATE!!!!
1308
+ export class ODCheckerCustomStructure_Template extends ODCheckerTemplateStructure {
1309
+ idk: string
1310
+
1311
+ constructor(id:ODValidId, idk:string, options?:ODCheckerStringStructureOptions){
1312
+ //add premade custom structure checker
1313
+ const newOptions = options ?? {}
1314
+ newOptions.custom = (checker,value,locationTrace,locationId,locationDocs) => {
1315
+ const lt = checker.locationTraceDeref(locationTrace)
1316
+
1317
+ //do custom check & push error message. Return true if correct
1318
+ return boolean
1319
+ }
1320
+ super(id,newOptions)
1321
+ this.idk = idk
1322
+ }
1323
+ }
1324
+ */