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