@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,348 @@
1
+ ///////////////////////////////////////
2
+ //COOLDOWN MODULE
3
+ ///////////////////////////////////////
4
+ import { ODId, ODValidId, ODManager, ODSystemError, ODManagerData } from "./base"
5
+ import { ODDebugger } from "./console"
6
+
7
+ /**## ODCooldownManager `class`
8
+ * This is an Open Discord cooldown manager.
9
+ *
10
+ * It is responsible for managing all cooldowns in Open Discord. An example of this is the ticket creation cooldown.
11
+ *
12
+ * There are many types of cooldowns available, but you can also create your own!
13
+ */
14
+ export class ODCooldownManager extends ODManager<ODCooldown<object>> {
15
+ constructor(debug:ODDebugger){
16
+ super(debug,"cooldown")
17
+ }
18
+ /**Initiate all cooldowns in this manager. */
19
+ async init(){
20
+ for (const cooldown of this.getAll()){
21
+ await cooldown.init()
22
+ }
23
+ }
24
+ }
25
+
26
+ /**## ODCooldownData `class`
27
+ * This is Open Discord cooldown data.
28
+ *
29
+ * It contains the instance of an active cooldown (e.g. for a user). It is handled by the cooldown itself.
30
+ */
31
+ export class ODCooldownData<Data extends object> extends ODManagerData {
32
+ /**Is this cooldown active? */
33
+ active: boolean
34
+ /**Additional data of this cooldown instance. (different for each cooldown type) */
35
+ data: Data
36
+
37
+ constructor(id:ODValidId,active:boolean,data:Data){
38
+ super(id)
39
+ this.active = active
40
+ this.data = data
41
+ }
42
+ }
43
+
44
+ /**## ODCooldown `class`
45
+ * This is an Open Discord cooldown.
46
+ *
47
+ * It doesn't do anything on it's own, but it provides the methods that are used to interact with a cooldown.
48
+ * This class can be extended from to create a working cooldown.
49
+ *
50
+ * There are also premade cooldowns available in the bot!
51
+ */
52
+ export class ODCooldown<Data extends object> extends ODManagerData {
53
+ data: ODManager<ODCooldownData<Data>> = new ODManager()
54
+ /**Is this cooldown already initialized? */
55
+ ready: boolean = false
56
+
57
+ constructor(id:ODValidId){
58
+ super(id)
59
+ }
60
+
61
+ /**Check this id and start cooldown when it exeeds the limit! Returns `true` when on cooldown! */
62
+ use(id:string): boolean {
63
+ throw new ODSystemError("Tried to use an unimplemented ODCooldown!")
64
+ }
65
+ /**Check this id without starting or updating the cooldown. Returns `true` when on cooldown! */
66
+ check(id:string): boolean {
67
+ throw new ODSystemError("Tried to use an unimplemented ODCooldown!")
68
+ }
69
+ /**Remove the cooldown for an id when available.*/
70
+ delete(id:string){
71
+ throw new ODSystemError("Tried to use an unimplemented ODCooldown!")
72
+ }
73
+ /**Initialize the internal systems of this cooldown. */
74
+ async init(){
75
+ throw new ODSystemError("Tried to use an unimplemented ODCooldown!")
76
+ }
77
+ }
78
+
79
+ /**## ODCounterCooldown `class`
80
+ * This is an Open Discord counter cooldown.
81
+ *
82
+ * It is is a cooldown based on a counter. When the number exceeds the limit, the cooldown is activated.
83
+ * The number will automatically be decreased with a set amount & interval.
84
+ */
85
+ export class ODCounterCooldown extends ODCooldown<{value:number}> {
86
+ /**The cooldown will activate when exceeding this limit. */
87
+ activeLimit: number
88
+ /**The cooldown will deactivate when below this limit. */
89
+ cancelLimit: number
90
+ /**The amount to increase the counter with everytime the cooldown is triggered/updated. */
91
+ increment: number
92
+ /**The amount to decrease the counter over time. */
93
+ decrement: number
94
+ /**The interval between decrements in milliseconds. */
95
+ invervalMs: number
96
+
97
+ constructor(id:ODValidId, activeLimit:number, cancelLimit:number, increment:number, decrement:number, intervalMs:number){
98
+ super(id)
99
+ this.activeLimit = activeLimit
100
+ this.cancelLimit = cancelLimit
101
+ this.increment = increment
102
+ this.decrement = decrement
103
+ this.invervalMs = intervalMs
104
+ }
105
+
106
+ use(id:string): boolean {
107
+ const cooldown = this.data.get(id)
108
+ if (cooldown){
109
+ //cooldown for this id already exists
110
+ if (cooldown.active){
111
+ return true
112
+
113
+ }else if (cooldown.data.value < this.activeLimit){
114
+ cooldown.data.value = cooldown.data.value + this.increment
115
+ return false
116
+
117
+ }else{
118
+ cooldown.active = true
119
+ return false
120
+ }
121
+ }else{
122
+ //cooldown for this id doesn't exist
123
+ this.data.add(new ODCooldownData(id,(this.increment >= this.activeLimit),{
124
+ value:this.increment
125
+ }))
126
+ return false
127
+ }
128
+ }
129
+ check(id:string): boolean {
130
+ const cooldown = this.data.get(id)
131
+ if (cooldown){
132
+ //cooldown for this id already exists
133
+ return cooldown.active
134
+ }else return false
135
+ }
136
+ delete(id:string): void {
137
+ this.data.remove(id)
138
+ }
139
+ async init(){
140
+ if (this.ready) return
141
+ setInterval(async () => {
142
+ await this.data.loopAll((cooldown) => {
143
+ cooldown.data.value = cooldown.data.value - this.decrement
144
+ if (cooldown.data.value <= this.cancelLimit){
145
+ cooldown.active = false
146
+ }
147
+ if (cooldown.data.value <= 0){
148
+ this.data.remove(cooldown.id)
149
+ }
150
+ })
151
+ },this.invervalMs)
152
+ this.ready = true
153
+ }
154
+ }
155
+
156
+ /**## ODIncrementalCounterCooldown `class`
157
+ * This is an Open Discord incremental counter cooldown.
158
+ *
159
+ * It is is a cooldown based on an incremental counter. It is exactly the same as the normal counter,
160
+ * with the only difference being that it still increments when the limit is already exeeded.
161
+ */
162
+ export class ODIncrementalCounterCooldown extends ODCooldown<{value:number}> {
163
+ /**The cooldown will activate when exceeding this limit. */
164
+ activeLimit: number
165
+ /**The cooldown will deactivate when below this limit. */
166
+ cancelLimit: number
167
+ /**The amount to increase the counter with everytime the cooldown is triggered/updated. */
168
+ increment: number
169
+ /**The amount to decrease the counter over time. */
170
+ decrement: number
171
+ /**The interval between decrements in milliseconds. */
172
+ invervalMs: number
173
+
174
+ constructor(id:ODValidId, activeLimit:number, cancelLimit:number, increment:number, decrement:number, intervalMs:number){
175
+ super(id)
176
+ this.activeLimit = activeLimit
177
+ this.cancelLimit = cancelLimit
178
+ this.increment = increment
179
+ this.decrement = decrement
180
+ this.invervalMs = intervalMs
181
+ }
182
+
183
+ use(id:string): boolean {
184
+ const cooldown = this.data.get(id)
185
+ if (cooldown){
186
+ //cooldown for this id already exists
187
+ if (cooldown.active){
188
+ cooldown.data.value = cooldown.data.value + this.increment
189
+ return true
190
+
191
+ }else if (cooldown.data.value < this.activeLimit){
192
+ cooldown.data.value = cooldown.data.value + this.increment
193
+ return false
194
+
195
+ }else{
196
+ cooldown.active = true
197
+ return false
198
+ }
199
+ }else{
200
+ //cooldown for this id doesn't exist
201
+ this.data.add(new ODCooldownData(id,(this.increment >= this.activeLimit),{
202
+ value:this.increment
203
+ }))
204
+ return false
205
+ }
206
+ }
207
+ check(id:string): boolean {
208
+ const cooldown = this.data.get(id)
209
+ if (cooldown){
210
+ //cooldown for this id already exists
211
+ return cooldown.active
212
+ }else return false
213
+ }
214
+ delete(id:string): void {
215
+ this.data.remove(id)
216
+ }
217
+ async init(){
218
+ if (this.ready) return
219
+ setInterval(async () => {
220
+ await this.data.loopAll((cooldown) => {
221
+ cooldown.data.value = cooldown.data.value - this.decrement
222
+ if (cooldown.data.value <= this.cancelLimit){
223
+ cooldown.active = false
224
+ }
225
+ if (cooldown.data.value <= 0){
226
+ this.data.remove(cooldown.id)
227
+ }
228
+ })
229
+ },this.invervalMs)
230
+ this.ready = true
231
+ }
232
+ }
233
+
234
+ /**## ODTimeoutCooldown `class`
235
+ * This is an Open Discord timeout cooldown.
236
+ *
237
+ * It is a cooldown based on a timer. When triggered/updated, the cooldown is activated for the set amount of time.
238
+ * After the timer has timed out, the cooldown will be deleted.
239
+ */
240
+ export class ODTimeoutCooldown extends ODCooldown<{date:number}> {
241
+ /**The amount of milliseconds before the cooldown times-out */
242
+ timeoutMs: number
243
+
244
+ constructor(id:ODValidId, timeoutMs:number){
245
+ super(id)
246
+ this.timeoutMs = timeoutMs
247
+ }
248
+
249
+ use(id:string): boolean {
250
+ const cooldown = this.data.get(id)
251
+ if (cooldown){
252
+ //cooldown for this id already exists
253
+ if ((new Date().getTime() - cooldown.data.date) > this.timeoutMs){
254
+ this.data.remove(id)
255
+ return false
256
+ }else{
257
+ return true
258
+ }
259
+ }else{
260
+ //cooldown for this id doesn't exist
261
+ this.data.add(new ODCooldownData(id,true,{
262
+ date:new Date().getTime()
263
+ }))
264
+ return false
265
+ }
266
+ }
267
+ check(id:string): boolean {
268
+ const cooldown = this.data.get(id)
269
+ if (cooldown){
270
+ //cooldown for this id already exists
271
+ return true
272
+ }else return false
273
+ }
274
+ delete(id:string): void {
275
+ this.data.remove(id)
276
+ }
277
+ /**Get the remaining amount of milliseconds before the timeout stops. */
278
+ remaining(id:string): number|null {
279
+ const cooldown = this.data.get(id)
280
+ if (!cooldown) return null
281
+ const rawResult = this.timeoutMs - (new Date().getTime() - cooldown.data.date)
282
+ return (rawResult > 0) ? rawResult : 0
283
+ }
284
+ async init(){
285
+ if (this.ready) return
286
+ this.ready = true
287
+ }
288
+ }
289
+
290
+ /**## ODIncrementalTimeoutCooldown `class`
291
+ * This is an Open Discord incremental timeout cooldown.
292
+ *
293
+ * It is is a cooldown based on an incremental timer. It is exactly the same as the normal timer,
294
+ * with the only difference being that it adds additional time when triggered/updated while the cooldown is already active.
295
+ */
296
+ export class ODIncrementalTimeoutCooldown extends ODCooldown<{date:number}> {
297
+ /**The amount of milliseconds before the cooldown times-out */
298
+ timeoutMs: number
299
+ /**The amount of milliseconds to add when triggered/updated while the cooldown is already active. */
300
+ incrementMs: number
301
+
302
+ constructor(id:ODValidId, timeoutMs:number, incrementMs:number){
303
+ super(id)
304
+ this.timeoutMs = timeoutMs
305
+ this.incrementMs = incrementMs
306
+ }
307
+
308
+ use(id:string): boolean {
309
+ const cooldown = this.data.get(id)
310
+ if (cooldown){
311
+ //cooldown for this id already exists
312
+ if ((new Date().getTime() - cooldown.data.date) > this.timeoutMs){
313
+ this.data.remove(id)
314
+ return false
315
+ }else{
316
+ cooldown.data.date = cooldown.data.date + this.incrementMs
317
+ return true
318
+ }
319
+ }else{
320
+ //cooldown for this id doesn't exist
321
+ this.data.add(new ODCooldownData(id,true,{
322
+ date:new Date().getTime()
323
+ }))
324
+ return false
325
+ }
326
+ }
327
+ check(id:string): boolean {
328
+ const cooldown = this.data.get(id)
329
+ if (cooldown){
330
+ //cooldown for this id already exists
331
+ return true
332
+ }else return false
333
+ }
334
+ delete(id:string): void {
335
+ this.data.remove(id)
336
+ }
337
+ /**Get the remaining amount of milliseconds before the timeout stops. */
338
+ remaining(id:string): number|null {
339
+ const cooldown = this.data.get(id)
340
+ if (!cooldown) return null
341
+ const rawResult = this.timeoutMs - (new Date().getTime() - cooldown.data.date)
342
+ return (rawResult > 0) ? rawResult : 0
343
+ }
344
+ async init(){
345
+ if (this.ready) return
346
+ this.ready = true
347
+ }
348
+ }
@@ -0,0 +1,278 @@
1
+ ///////////////////////////////////////
2
+ //DATABASE MODULE
3
+ ///////////////////////////////////////
4
+ import { ODId, ODManager, ODManagerData, ODOptionalPromise, ODPromiseVoid, ODSystemError, ODValidId, ODValidJsonType } from "./base"
5
+ import fs from "fs"
6
+ import nodepath from "path"
7
+ import { ODDebugger } from "./console"
8
+ import * as fjs from "formatted-json-stringify"
9
+
10
+ /**## ODDatabaseManager `class`
11
+ * This is an Open Discord database manager.
12
+ *
13
+ * It manages all databases in the bot and allows to permanently store data from the bot!
14
+ *
15
+ * You can use this class to get/add a database (`ODDatabase`) in your plugin!
16
+ */
17
+ export class ODDatabaseManager extends ODManager<ODDatabase> {
18
+ constructor(debug:ODDebugger){
19
+ super(debug,"database")
20
+ }
21
+
22
+ /**Init all database files. */
23
+ async init(){
24
+ for (const database of this.getAll()){
25
+ try{
26
+ await database.init()
27
+ }catch(err){
28
+ process.emit("uncaughtException",new ODSystemError(err))
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+ /**## ODDatabase `class`
35
+ * This is an Open Discord database template.
36
+ * This class doesn't do anything at all, it just gives a template & basic methods for a database. Use `ODJsonDatabase` instead!
37
+ *
38
+ * You can use this class if you want to create your own database implementation (e.g. `mongodb`, `mysql`,...)!
39
+ */
40
+ export class ODDatabase extends ODManagerData {
41
+ /**The name of the file with extension. */
42
+ file: string = ""
43
+ /**The path to the file relative to the main directory. */
44
+ path: string = ""
45
+
46
+ /**Init the database. */
47
+ init(): ODPromiseVoid {
48
+ //nothing
49
+ }
50
+ /**Add/Overwrite a specific category & key in the database. Returns `true` when overwritten. */
51
+ set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> {
52
+ return false
53
+ }
54
+ /**Get a specific category & key in the database */
55
+ get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined> {
56
+ return undefined
57
+ }
58
+ /**Delete a specific category & key in the database */
59
+ delete(category:string, key:string): ODOptionalPromise<boolean> {
60
+ return false
61
+ }
62
+ /**Check if a specific category & key exists in the database */
63
+ exists(category:string, key:string): ODOptionalPromise<boolean> {
64
+ return false
65
+ }
66
+ /**Get a specific category in the database */
67
+ getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> {
68
+ return undefined
69
+ }
70
+ /**Get all values in the database */
71
+ getAll(): ODOptionalPromise<ODJsonDatabaseStructure> {
72
+ return []
73
+ }
74
+ }
75
+
76
+ /**## ODJsonDatabaseStructure `type`
77
+ * This is the structure of how a JSON database file!
78
+ */
79
+ export type ODJsonDatabaseStructure = {category:string, key:string, value:ODValidJsonType}[]
80
+
81
+ /**## ODJsonDatabase `class`
82
+ * This is an Open Discord JSON database.
83
+ * It stores data in a `json` file as a large `Array` using the `category`, `key`, `value` strategy.
84
+ * You can store the following types: `string`, `number`, `boolean`, `array`, `object` & `null`!
85
+ *
86
+ * You can use this class if you want to add your own database or to use an existing one!
87
+ */
88
+ export class ODJsonDatabase extends ODDatabase {
89
+ constructor(id:ODValidId, file:string, customPath?:string){
90
+ super(id)
91
+ this.file = (file.endsWith(".json")) ? file : file+".json"
92
+ this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./database/",this.file)
93
+ }
94
+
95
+ /**Init the database. */
96
+ init(): ODPromiseVoid {
97
+ this.#system.getData()
98
+ }
99
+ /**Set/overwrite the value of `category` & `key`. Returns `true` when overwritten!
100
+ * @example
101
+ * const didOverwrite = database.setData("category","key","value") //value can be any of the valid types
102
+ * //You need an ODJsonDatabase class named "database" for this example to work!
103
+ */
104
+ set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> {
105
+ const currentList = this.#system.getData()
106
+ const currentData = currentList.find((d) => (d.category === category) && (d.key === key))
107
+
108
+ //overwrite when already present
109
+ if (currentData){
110
+ currentList[currentList.indexOf(currentData)].value = value
111
+ }else{
112
+ currentList.push({category,key,value})
113
+ }
114
+
115
+ this.#system.setData(currentList)
116
+ return currentData ? true : false
117
+ }
118
+ /**Get the value of `category` & `key`. Returns `undefined` when non-existent!
119
+ * @example
120
+ * const data = database.getData("category","key") //data will be the value
121
+ * //You need an ODJsonDatabase class named "database" for this example to work!
122
+ */
123
+ get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined> {
124
+ const currentList = this.#system.getData()
125
+ const tempresult = currentList.find((d) => (d.category === category) && (d.key === key))
126
+ return tempresult ? tempresult.value : undefined
127
+ }
128
+ /**Remove the value of `category` & `key`. Returns `undefined` when non-existent!
129
+ * @example
130
+ * const didExist = database.deleteData("category","key") //delete this value
131
+ * //You need an ODJsonDatabase class named "database" for this example to work!
132
+ */
133
+ delete(category:string, key:string): ODOptionalPromise<boolean> {
134
+ const currentList = this.#system.getData()
135
+ const currentData = currentList.find((d) => (d.category === category) && (d.key === key))
136
+ if (currentData) currentList.splice(currentList.indexOf(currentData),1)
137
+
138
+ this.#system.setData(currentList)
139
+ return currentData ? true : false
140
+ }
141
+ /**Check if a value of `category` & `key` exists. Returns `false` when non-existent! */
142
+ exists(category:string, key:string): ODOptionalPromise<boolean> {
143
+ const currentList = this.#system.getData()
144
+ const tempresult = currentList.find((d) => (d.category === category) && (d.key === key))
145
+ return tempresult ? true : false
146
+ }
147
+ /**Get all values in `category`. Returns `undefined` when non-existent! */
148
+ getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> {
149
+ const currentList = this.#system.getData()
150
+ const tempresult = currentList.filter((d) => (d.category === category))
151
+ return tempresult ? tempresult.map((data) => {return {key:data.key,value:data.value}}) : undefined
152
+ }
153
+ /**Get all values in `category`. */
154
+ getAll(): ODOptionalPromise<ODJsonDatabaseStructure> {
155
+ return this.#system.getData()
156
+ }
157
+
158
+ #system = {
159
+ /**Read parsed data from the json file */
160
+ getData: (): ODJsonDatabaseStructure => {
161
+ if (fs.existsSync(this.path)){
162
+ try{
163
+ return JSON.parse(fs.readFileSync(this.path).toString())
164
+ }catch(err){
165
+ process.emit("uncaughtException",err)
166
+ throw new ODSystemError("Unable to read database "+this.path+"! getData() read error. (see error above)")
167
+ }
168
+ }else{
169
+ fs.writeFileSync(this.path,"[]")
170
+ return []
171
+ }
172
+ },
173
+ /**Write parsed data to the json file */
174
+ setData: (data:ODJsonDatabaseStructure) => {
175
+ fs.writeFileSync(this.path,JSON.stringify(data,null,"\t"))
176
+ }
177
+ }
178
+ }
179
+
180
+
181
+ /**## ODFormattedJsonDatabase `class`
182
+ * This is an Open Discord Formatted JSON database.
183
+ * It stores data in a `json` file as a large `Array` using the `category`, `key`, `value` strategy.
184
+ * You can store the following types: `string`, `number`, `boolean`, `array`, `object` & `null`!
185
+ *
186
+ * This one is exactly the same as `ODJsonDatabase`, but it has a formatter from the `formatted-json-stringify` package.
187
+ * This can help you organise it a little bit better!
188
+ */
189
+ export class ODFormattedJsonDatabase extends ODDatabase {
190
+ /**The formatter to use on the database array */
191
+ formatter: fjs.ArrayFormatter
192
+
193
+ constructor(id:ODValidId, file:string, formatter:fjs.ArrayFormatter, customPath?:string){
194
+ super(id)
195
+ this.file = (file.endsWith(".json")) ? file : file+".json"
196
+ this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./database/",this.file)
197
+ this.formatter = formatter
198
+ }
199
+
200
+ /**Init the database. */
201
+ init(): ODPromiseVoid {
202
+ this.#system.getData()
203
+ }
204
+ /**Set/overwrite the value of `category` & `key`. Returns `true` when overwritten!
205
+ * @example
206
+ * const didOverwrite = database.setData("category","key","value") //value can be any of the valid types
207
+ * //You need an ODFormattedJsonDatabase class named "database" for this example to work!
208
+ */
209
+ set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> {
210
+ const currentList = this.#system.getData()
211
+ const currentData = currentList.find((d) => (d.category === category) && (d.key === key))
212
+
213
+ //overwrite when already present
214
+ if (currentData){
215
+ currentList[currentList.indexOf(currentData)].value = value
216
+ }else{
217
+ currentList.push({category,key,value})
218
+ }
219
+
220
+ this.#system.setData(currentList)
221
+ return currentData ? true : false
222
+ }
223
+ /**Get the value of `category` & `key`. Returns `undefined` when non-existent!
224
+ * @example
225
+ * const data = database.getData("category","key") //data will be the value
226
+ * //You need an ODFormattedJsonDatabase class named "database" for this example to work!
227
+ */
228
+ get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined> {
229
+ const currentList = this.#system.getData()
230
+ const tempresult = currentList.find((d) => (d.category === category) && (d.key === key))
231
+ return tempresult ? tempresult.value : undefined
232
+ }
233
+ /**Remove the value of `category` & `key`. Returns `undefined` when non-existent!
234
+ * @example
235
+ * const didExist = database.deleteData("category","key") //delete this value
236
+ * //You need an ODFormattedJsonDatabase class named "database" for this example to work!
237
+ */
238
+ delete(category:string, key:string): ODOptionalPromise<boolean> {
239
+ const currentList = this.#system.getData()
240
+ const currentData = currentList.find((d) => (d.category === category) && (d.key === key))
241
+ if (currentData) currentList.splice(currentList.indexOf(currentData),1)
242
+
243
+ this.#system.setData(currentList)
244
+ return currentData ? true : false
245
+ }
246
+ /**Check if a value of `category` & `key` exists. Returns `false` when non-existent! */
247
+ exists(category:string, key:string): ODOptionalPromise<boolean> {
248
+ const currentList = this.#system.getData()
249
+ const tempresult = currentList.find((d) => (d.category === category) && (d.key === key))
250
+ return tempresult ? true : false
251
+ }
252
+ /**Get all values in `category`. Returns `undefined` when non-existent! */
253
+ getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> {
254
+ const currentList = this.#system.getData()
255
+ const tempresult = currentList.filter((d) => (d.category === category))
256
+ return tempresult ? tempresult.map((data) => {return {key:data.key,value:data.value}}) : undefined
257
+ }
258
+ /**Get all values in `category`. */
259
+ getAll(): ODOptionalPromise<ODJsonDatabaseStructure> {
260
+ return this.#system.getData()
261
+ }
262
+
263
+ #system = {
264
+ /**Read parsed data from the json file */
265
+ getData: (): ODJsonDatabaseStructure => {
266
+ if (fs.existsSync(this.path)){
267
+ return JSON.parse(fs.readFileSync(this.path).toString())
268
+ }else{
269
+ fs.writeFileSync(this.path,"[]")
270
+ return []
271
+ }
272
+ },
273
+ /**Write parsed data to the json file */
274
+ setData: (data:ODJsonDatabaseStructure) => {
275
+ fs.writeFileSync(this.path,this.formatter.stringify(data))
276
+ }
277
+ }
278
+ }