@open-discord-bots/framework 0.3.14 → 0.3.16

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 (44) hide show
  1. package/README.md +5 -1
  2. package/dist/api/main.js +1 -1
  3. package/dist/api/modules/responder.js +50 -26
  4. package/package.json +1 -1
  5. package/.gitattributes +0 -2
  6. package/src/api/index.ts +0 -31
  7. package/src/api/main.ts +0 -203
  8. package/src/api/modules/action.ts +0 -89
  9. package/src/api/modules/base.ts +0 -845
  10. package/src/api/modules/builder.ts +0 -1755
  11. package/src/api/modules/checker.ts +0 -1826
  12. package/src/api/modules/client.ts +0 -2345
  13. package/src/api/modules/code.ts +0 -84
  14. package/src/api/modules/component.ts +0 -2000
  15. package/src/api/modules/config.ts +0 -264
  16. package/src/api/modules/console.ts +0 -697
  17. package/src/api/modules/cooldown.ts +0 -369
  18. package/src/api/modules/database.ts +0 -321
  19. package/src/api/modules/event.ts +0 -123
  20. package/src/api/modules/flag.ts +0 -99
  21. package/src/api/modules/fuse.ts +0 -365
  22. package/src/api/modules/helpmenu.ts +0 -273
  23. package/src/api/modules/language.ts +0 -230
  24. package/src/api/modules/permission.ts +0 -363
  25. package/src/api/modules/plugin.ts +0 -294
  26. package/src/api/modules/post.ts +0 -137
  27. package/src/api/modules/progressbar.ts +0 -370
  28. package/src/api/modules/responder.ts +0 -1625
  29. package/src/api/modules/session.ts +0 -181
  30. package/src/api/modules/startscreen.ts +0 -345
  31. package/src/api/modules/state.ts +0 -298
  32. package/src/api/modules/statistic.ts +0 -380
  33. package/src/api/modules/verifybar.ts +0 -68
  34. package/src/api/modules/worker.ts +0 -119
  35. package/src/cli/editConfig.ts +0 -930
  36. package/src/cli/index.ts +0 -152
  37. package/src/index.ts +0 -8
  38. package/src/startup/compilation.ts +0 -204
  39. package/src/startup/dump.ts +0 -46
  40. package/src/startup/errorHandling.ts +0 -42
  41. package/src/startup/pluginLauncher.ts +0 -265
  42. package/src/utilities/index.ts +0 -229
  43. package/tools/cleanup.js +0 -2
  44. package/tsconfig.json +0 -15
@@ -1,845 +0,0 @@
1
- ///////////////////////////////////////
2
- //BASE MODULE
3
- ///////////////////////////////////////
4
- import * as fs from "fs"
5
- import { ODDebugger } from "./console.js"
6
- import type { ODMain } from "../main.js"
7
-
8
- /**## ODPromiseVoid `type`
9
- * This is a simple type to represent a callback return value that could be a promise or not.
10
- */
11
- export type ODPromiseVoid = void|Promise<void>
12
-
13
- /**## ODOptionalPromise `type`
14
- * This is a simple type to represent a type as normal value or a promise value.
15
- */
16
- export type ODOptionalPromise<T> = T|Promise<T>
17
-
18
- /**## ODValidButtonColor `type`
19
- * This is a collection of all the possible button colors.
20
- */
21
- export type ODValidButtonColor = "gray"|"red"|"green"|"blue"
22
-
23
- /**## ODProjectType `type`
24
- * Valid project types for using Open Discord.
25
- */
26
- export type ODProjectType = "openticket"|"openmoderation"
27
-
28
- /**## ODValidId `type`
29
- * A valid Open Discord identifier. It can be an `ODId` or `string`!
30
- *
31
- * You will see this type in many functions from Open Discord.
32
- */
33
- export type ODValidId = string|number|symbol|ODId
34
-
35
- /**## ODValidJsonType `type`
36
- * A collection of all types that can be stored in a JSON file!
37
- *
38
- * list: `string`, `number`, `boolean`, `array`, `object`, `null`
39
- */
40
- export type ODValidJsonType = string|number|boolean|{[key:string]:ODValidJsonType}|ODValidJsonType[]|null|object
41
-
42
- /**## ODInterfaceWithPartialProperty `type`
43
- * A utility type to create an interface where some properties are optional!
44
- */
45
- export type ODInterfaceWithPartialProperty<Interface,Key extends keyof Interface> = Omit<Interface,Key> & Partial<Pick<Interface,Key>>
46
-
47
- /**## ODDiscordIdType `type`
48
- * A list of all available discord ID types. Used in the config checker.
49
- */
50
- export type ODDiscordIdType = "role"|"server"|"channel"|"category"|"user"|"member"|"interaction"|"message"
51
-
52
- /**## ODNoGeneric `type`
53
- * A utility type to remove generic index signatures from interfaces. This is required for providing autocomplete in all `IdList`'s of the `ODManagers`.
54
- */
55
- export type ODNoGeneric<T extends Record<string|number|symbol,any>> = {
56
- [K in keyof T as string extends K ? never : number extends K ? never : symbol extends K ? never : K]: T[K]
57
- }
58
-
59
- /**## ODId `class`
60
- * This is an Open Discord identifier.
61
- *
62
- * It can only contain the following characters: `a-z`, `A-Z`, `0-9`, `:`, `-` & `_`
63
- *
64
- * You can use this class to assign a unique id when creating configs, databases, languages & more!
65
- */
66
- export class ODId {
67
- /**The raw value of this `ODId` as a `string`. */
68
- private rawValue: string
69
- /**The change listener for the parent `ODManager` of this `ODId`. */
70
- private changeListener: ((oldId:string,newId:string) => void)|null = null
71
-
72
- constructor(id:ODValidId){
73
- if (typeof id != "string" && !(id instanceof ODId)) throw new ODSystemError("Invalid constructor parameter => id:ODValidId")
74
-
75
- if (typeof id == "string"){
76
- //id is string
77
- const result: string[] = []
78
- const charregex = /[a-zA-Z0-9éèçàêâôûî\:\-\_]/
79
-
80
- id.split("").forEach((char) => {
81
- if (charregex.test(char)){
82
- result.push(char)
83
- }
84
- })
85
-
86
- if (result.length > 0) this.rawValue = result.join("")
87
- else throw new ODSystemError("invalid ID at 'new ODID(id: "+id+")'")
88
- }else{
89
- //id is ODId
90
- this.rawValue = id.rawValue
91
- }
92
- }
93
-
94
- /**The full value of this `ODId` as a `string`. */
95
- set value(id:string){
96
- this._change(this.rawValue,id)
97
- this.rawValue = id
98
- }
99
- get value(){
100
- return this.rawValue
101
- }
102
- /**Returns a string representation of this id. (same as `this.value`) */
103
- toString(){
104
- return this.rawValue
105
- }
106
- /**The namespace of the id before `:`. (e.g. `opendiscord` for `opendiscord:autoclose-enabled`) */
107
- getNamespace(){
108
- const splitted = this.rawValue.split(":")
109
- if (splitted.length > 1) return splitted[0]
110
- else return ""
111
- }
112
- /**The identifier of the id after `:`. (e.g. `autoclose-enabled` for `opendiscord:autoclose-enabled`) */
113
- getIdentifier(){
114
- const splitted = this.rawValue.split(":")
115
- if (splitted.length > 1){
116
- splitted.shift()
117
- return splitted.join(":")
118
- }else return this.rawValue
119
- }
120
- /**Trigger an `onChange()` event in the parent `ODManager` of this class. */
121
- protected _change(oldId:string,newId:string){
122
- if (this.changeListener){
123
- try{
124
- this.changeListener(oldId,newId)
125
- }catch(err){
126
- process.emit("uncaughtException",err)
127
- throw new ODSystemError("Failed to execute _change() callback!")
128
- }
129
- }
130
- }
131
- /****(❌ SYSTEM ONLY!!)** Set the callback executed when a value inside this class changes. */
132
- changed(callback:((oldId:string,newId:string) => void)|null){
133
- this.changeListener = callback
134
- }
135
- }
136
-
137
- /**## ODManagerChangeHelper `class`
138
- * This is an Open Discord manager change helper.
139
- *
140
- * It is used to let the "onChange" event in the `ODManager` class work.
141
- * You can use this class when extending your own `ODManager`
142
- */
143
- export abstract class ODManagerChangeHelper {
144
- private changeListener: (() => void)|null = null
145
-
146
- /**Trigger an `onChange()` event in the parent `ODManager` of this class. */
147
- protected _change(){
148
- if (this.changeListener){
149
- try{
150
- this.changeListener()
151
- }catch(err){
152
- process.emit("uncaughtException",err)
153
- throw new ODSystemError("Failed to execute _change() callback!")
154
- }
155
- }
156
- }
157
- /****(❌ SYSTEM ONLY!!)** Set the callback executed when a value inside this class changes. */
158
- changed(callback:(() => void)|null){
159
- this.changeListener = callback
160
- }
161
- }
162
-
163
- /**## ODManagerData `class`
164
- * This is Open Discord manager data.
165
- *
166
- * It provides a template for all classes that are used in the `ODManager`.
167
- *
168
- * There is an `id:ODId` property & also some events used in the manager.
169
- */
170
- export abstract class ODManagerData extends ODManagerChangeHelper {
171
- /**The id of this data. */
172
- id: ODId
173
-
174
- constructor(id:ODValidId){
175
- if (typeof id != "string" && !(id instanceof ODId)) throw new ODSystemError("Invalid constructor parameter => id:ODValidId")
176
- super()
177
- this.id = new ODId(id)
178
- }
179
- }
180
-
181
- /**## ODManagerCallback `type`
182
- * This is a callback for the `onChange` and `onRemove` events in the `ODManager`
183
- */
184
- export type ODManagerCallback<DataType extends ODManagerData> = (data:DataType) => void
185
- /**## ODManagerAddCallback `type`
186
- * This is a callback for the `onAdd` event in the `ODManager`
187
- */
188
- export type ODManagerAddCallback<DataType extends ODManagerData> = (data:DataType, overwritten:boolean) => void
189
-
190
- /**## ODManager `class`
191
- * This is an Open Discord manager.
192
- *
193
- * It can be used to store & manage classes based on their `ODId`.
194
- * It is somewhat the same as the default JS `Map()`.
195
- * You can extend this class when creating your own classes & managers.
196
- *
197
- * This class has many useful functions based on `ODId` (add, get, remove, getAll, getFiltered, exists, loopAll, ...)
198
- */
199
- export class ODManager<DataType extends ODManagerData> extends ODManagerChangeHelper {
200
- /**Alias to Open Discord debugger. */
201
- protected debug?: ODDebugger
202
- /**The message to send when debugging this manager. */
203
- protected debugname?: string
204
- /**The map storing all data classes in this manager. */
205
- private data: Map<string,DataType> = new Map()
206
- /**An array storing all listeners when data is added. */
207
- private addListeners: ODManagerAddCallback<DataType>[] = []
208
- /**An array storing all listeners when data has changed. */
209
- private changeListeners: ODManagerCallback<DataType>[] = []
210
- /**An array storing all listeners when data is removed. */
211
- private removeListeners: ODManagerCallback<DataType>[] = []
212
-
213
- constructor(debug?:ODDebugger, debugname?:string){
214
- super()
215
- this.debug = debug
216
- this.debugname = debugname
217
- }
218
-
219
- /**Add data to the manager. The `ODId` in the data class will be used as identifier! You can optionally select to overwrite existing data!*/
220
- add(data:DataType|DataType[], overwrite?:boolean): boolean {
221
- //repeat same command when data is an array
222
- if (Array.isArray(data)){
223
- data.forEach((arrayData) => {
224
- this.add(arrayData,overwrite)
225
- })
226
- return false
227
- }
228
-
229
- //add listener for data id change => transfer data within manager
230
- data.id.changed((oldId,newId) => {
231
- this.data.delete(oldId)
232
- this.data.set(newId,data)
233
- })
234
-
235
- //add data
236
- let didOverwrite: boolean
237
- if (this.data.has(data.id.value)){
238
- if (!overwrite) throw new ODSystemError("Id '"+data.id.value+"' already exists in "+this.debugname+" manager. Use 'overwrite:true' to allow overwriting!")
239
- this.data.set(data.id.value,data)
240
- didOverwrite = true
241
- if (this.debug) this.debug.debug("Added new "+this.debugname+" to manager",[{key:"id",value:data.id.value},{key:"overwrite",value:"true"}])
242
-
243
- }else{
244
- this.data.set(data.id.value,data)
245
- didOverwrite = false
246
- if (this.debug) this.debug.debug("Added new "+this.debugname+" to manager",[{key:"id",value:data.id.value},{key:"overwrite",value:"false"}])
247
-
248
- }
249
-
250
- //emit change listeners
251
- data.changed(() => {
252
- //notify change in upper-manager (because data in this manager changed)
253
- this._change()
254
- this.changeListeners.forEach((cb) => {
255
- try{
256
- cb(data)
257
- }catch(err){
258
- throw new ODSystemError("Failed to run manager onChange() listener.\n"+err)
259
- }
260
- })
261
- })
262
-
263
- //emit add listeners
264
- this.addListeners.forEach((cb) => {
265
- try{
266
- cb(data,didOverwrite)
267
- }catch(err){
268
- throw new ODSystemError("Failed to run manager onAdd() listener.\n"+err)
269
- }
270
- })
271
-
272
- //notify change in upper-manager (because data added)
273
- this._change()
274
-
275
- return didOverwrite
276
- }
277
- /**Get data that matches the `ODId`. Returns the found data.*/
278
- get(id:ODValidId): DataType|null {
279
- const newId = new ODId(id)
280
- const data = this.data.get(newId.value)
281
- if (data) return data
282
- else return null
283
- }
284
- /**Remove data that matches the `ODId`. Returns the removed data. */
285
- remove(id:ODValidId): DataType|null {
286
- const newId = new ODId(id)
287
- const data = this.data.get(newId.value)
288
-
289
- if (!data){
290
- if (this.debug) this.debug.debug("Removed "+this.debugname+" from manager",[{key:"id",value:newId.value},{key:"found",value:"false"}])
291
- return null
292
- }else{
293
- this.data.delete(newId.value)
294
- if (this.debug) this.debug.debug("Removed "+this.debugname+" from manager",[{key:"id",value:newId.value},{key:"found",value:"true"}])
295
- }
296
-
297
- //remove all listeners
298
- data.id.changed(null)
299
- data.changed(null)
300
-
301
- //emit remove listeners
302
- this.removeListeners.forEach((cb) => {
303
- try{
304
- cb(data)
305
- }catch(err){
306
- throw new ODSystemError("Failed to run manager onRemove() listener.\n"+err)
307
- }
308
- })
309
-
310
- //notify change in upper-manager (because data removed)
311
- this._change()
312
-
313
- return data
314
- }
315
- /**Check if data that matches the `ODId` exists. Returns a boolean. */
316
- exists(id:ODValidId): boolean {
317
- const newId = new ODId(id)
318
- if (this.data.has(newId.value)) return true
319
- else return false
320
- }
321
- /**Get all data inside this manager*/
322
- getAll(): DataType[] {
323
- return Array.from(this.data.values())
324
- }
325
- /**Get all data that matches inside the filter function*/
326
- getFiltered(predicate:(value:DataType, index:number, array:DataType[]) => unknown): DataType[] {
327
- return Array.from(this.data.values()).filter(predicate)
328
- }
329
- /**Get all data where the `ODId` matches the provided RegExp. */
330
- getRegex(regex:RegExp): DataType[] {
331
- return Array.from(this.data.values()).filter((data) => regex.test(data.id.value))
332
- }
333
- /**Get the length/size/amount of the data inside this manager. */
334
- getLength(){
335
- return this.data.size
336
- }
337
- /**Get a list of all the ids inside this manager*/
338
- getIds(): ODId[] {
339
- const ids = Array.from(this.data.keys())
340
- return ids.map((id) => new ODId(id))
341
- }
342
- /**Run an iterator over all data in this manager. This method also supports async-await behaviour!*/
343
- async loopAll(cb:(data:DataType,id:ODId) => ODPromiseVoid): Promise<void> {
344
- for (const data of this.getAll()){
345
- await cb(data,data.id)
346
- }
347
- }
348
- /**Use the Open Discord debugger in this manager for logs*/
349
- useDebug(debug?:ODDebugger, debugname?:string){
350
- this.debug = debug
351
- this.debugname = debugname
352
- }
353
- /**Listen for when data is added to this manager. */
354
- onAdd(callback:ODManagerAddCallback<DataType>){
355
- this.addListeners.push(callback)
356
- }
357
- /**Listen for when data is changed in this manager. */
358
- onChange(callback:ODManagerCallback<DataType>){
359
- this.changeListeners.push(callback)
360
- }
361
- /**Listen for when data is removed from this manager. */
362
- onRemove(callback:ODManagerCallback<DataType>){
363
- this.removeListeners.push(callback)
364
- }
365
- }
366
-
367
- /**## ODManagerWithSafety `class`
368
- * This is an Open Discord safe manager.
369
- *
370
- * It functions exactly the same as a normal `ODManager`, but it has 1 function extra!
371
- * The `getSafe()` function will always return data, because when it doesn't find an id, it returns pre-configured backup data.
372
- */
373
- export class ODManagerWithSafety<DataType extends ODManagerData> extends ODManager<DataType> {
374
- /**The function that creates backup data returned in `getSafe()` when an id is missing in this manager. */
375
- protected backupGenerator: () => DataType
376
-
377
- constructor(backupGenerator:() => DataType, debug?:ODDebugger, debugname?:string){
378
- super(debug,debugname)
379
- this.backupGenerator = backupGenerator
380
- }
381
-
382
- /**Get data that matches the `ODId`. Returns the backup data when not found.
383
- *
384
- * ### ⚠️ This should only be used when the data doesn't need to be written/edited
385
- */
386
- getSafe(id:ODValidId): DataType {
387
- const newId = new ODId(id)
388
- const data = super.get(id)
389
- if (!data){
390
- process.emit("uncaughtException",new ODSystemError("ODManagerWithSafety:getSafe(\""+newId.value+"\") => Unknown Id => Used backup data ("+this.debugname+" manager)"))
391
- return this.backupGenerator()
392
- }
393
- else return data
394
- }
395
- }
396
-
397
- /**## ODVersionManagerIdConstraint `type`
398
- * The constraint/layout for id mappings/interfaces of the `ODVersionManager` class.
399
- */
400
- export type ODVersionManagerIdConstraint = Record<string,ODVersion>
401
-
402
- /**## ODVersionManager `class`
403
- * A Open Discord version manager.
404
- *
405
- * It is used to manage different `ODVersion`'s from the bot. You will use it to check which version of the bot is used.
406
- */
407
- export class ODVersionManager<IdList extends ODVersionManagerIdConstraint = ODVersionManagerIdConstraint> extends ODManager<ODVersion> {
408
- constructor(){
409
- super()
410
- }
411
-
412
- get<VersionId extends keyof ODNoGeneric<IdList>>(id:VersionId): IdList[VersionId]
413
- get(id:ODValidId): ODVersion|null
414
-
415
- get(id:ODValidId): ODVersion|null {
416
- return super.get(id)
417
- }
418
-
419
- remove<VersionId extends keyof ODNoGeneric<IdList>>(id:VersionId): IdList[VersionId]
420
- remove(id:ODValidId): ODVersion|null
421
-
422
- remove(id:ODValidId): ODVersion|null {
423
- return super.remove(id)
424
- }
425
-
426
- exists(id:keyof ODNoGeneric<IdList>): boolean
427
- exists(id:ODValidId): boolean
428
-
429
- exists(id:ODValidId): boolean {
430
- return super.exists(id)
431
- }
432
- }
433
-
434
- /**## ODVersion `class`
435
- * This is an Open Discord version.
436
- *
437
- * It has many features like comparing versions & checking if they are compatible.
438
- *
439
- * You can use it in your own plugin, but most of the time you will use it to check the Open Discord version!
440
- */
441
- export class ODVersion extends ODManagerData {
442
- /**The first number of the version (example: `v1.2.3` => `1`) */
443
- primary: number
444
- /**The second number of the version (example: `v1.2.3` => `2`) */
445
- secondary: number
446
- /**The third number of the version (example: `v1.2.3` => `3`) */
447
- tertiary: number
448
-
449
- constructor(id:ODValidId, primary:number, secondary:number, tertiary:number){
450
- super(id)
451
- if (typeof primary != "number") throw new ODSystemError("Invalid constructor parameter => primary:number")
452
- if (typeof secondary != "number") throw new ODSystemError("Invalid constructor parameter => secondary:number")
453
- if (typeof tertiary != "number") throw new ODSystemError("Invalid constructor parameter => tertiary:number")
454
-
455
- this.primary = primary
456
- this.secondary = secondary
457
- this.tertiary = tertiary
458
- }
459
-
460
- /**Get the version from a string (also possible with `v` prefix)
461
- * @example const version = api.ODVersion.fromString("id","v1.2.3") //creates version 1.2.3
462
- */
463
- static fromString(id:ODValidId, version:string){
464
- if (typeof id != "string" && !(id instanceof ODId)) throw new ODSystemError("Invalid function parameter => id:ODValidId")
465
- if (typeof version != "string") throw new ODSystemError("Invalid function parameter => version:string")
466
-
467
- const versionCheck = (version.startsWith("v")) ? version.substring(1) : version
468
- const splittedVersion = versionCheck.split(".")
469
-
470
- return new this(id,Number(splittedVersion[0]),Number(splittedVersion[1]),Number(splittedVersion[2]))
471
- }
472
- /**Get the version as a string (`noprefix:true` => with `v` prefix)
473
- * @example
474
- * new api.ODVersion(1,0,0).toString(false) //returns "v1.0.0"
475
- * new api.ODVersion(1,0,0).toString(true) //returns "1.0.0"
476
- */
477
- toString(noprefix?:boolean){
478
- const prefix = noprefix ? "" : "v"
479
- return prefix+[this.primary,this.secondary,this.tertiary].join(".")
480
- }
481
- /**Compare this version with another version and returns the result: `higher`, `lower` or `equal`
482
- * @example
483
- * new api.ODVersion(1,0,0).compare(new api.ODVersion(1,2,0)) //returns "lower"
484
- * new api.ODVersion(1,3,0).compare(new api.ODVersion(1,2,0)) //returns "higher"
485
- * new api.ODVersion(1,2,0).compare(new api.ODVersion(1,2,0)) //returns "equal"
486
- */
487
- compare(comparator:ODVersion): "higher"|"lower"|"equal" {
488
- if (!(comparator instanceof ODVersion)) throw new ODSystemError("Invalid function parameter => comparator:ODVersion")
489
-
490
- if (this.primary < comparator.primary) return "lower"
491
- else if (this.primary > comparator.primary) return "higher"
492
- else {
493
- if (this.secondary < comparator.secondary) return "lower"
494
- else if (this.secondary > comparator.secondary) return "higher"
495
- else {
496
- if (this.tertiary < comparator.tertiary) return "lower"
497
- else if (this.tertiary > comparator.tertiary) return "higher"
498
- else return "equal"
499
- }
500
- }
501
- }
502
- /**Check if this version is included in the list
503
- * @example
504
- * const list = [
505
- * new api.ODVersion(1,0,0),
506
- * new api.ODVersion(1,0,1),
507
- * new api.ODVersion(1,0,2)
508
- * ]
509
- * new api.ODVersion(1,0,0).compatible(list) //returns true
510
- * new api.ODVersion(1,0,1).compatible(list) //returns true
511
- * new api.ODVersion(1,0,3).compatible(list) //returns false
512
- */
513
- compatible(list:ODVersion[]): boolean {
514
- if (!Array.isArray(list)) throw new ODSystemError("Invalid function parameter => list:ODVersion[]")
515
- if (!list.every((v) => (v instanceof ODVersion))) throw new ODSystemError("Invalid function parameter => list:ODVersion[]")
516
-
517
- return list.some((v) => {
518
- return (v.toString() === this.toString())
519
- })
520
- }
521
- /**Check if this version is higher or equal to the provided `requirement`. */
522
- min(requirement:string|ODVersion){
523
- if (typeof requirement == "string") requirement = ODVersion.fromString("temp",requirement)
524
-
525
- //skip when primary version is higher or lower than current one.
526
- if (this.primary < requirement.primary) return false
527
- else if (this.primary > requirement.primary) return true
528
-
529
- //skip when secondary version is higher or lower than current one.
530
- if (this.secondary < requirement.secondary) return false
531
- else if (this.secondary > requirement.secondary) return true
532
-
533
- //skip when tertiary version is higher or lower than current one.
534
- if (this.tertiary < requirement.tertiary) return false
535
- else if (this.tertiary > requirement.tertiary) return true
536
-
537
- return true
538
- }
539
- /**Check if this version is lower or equal to the provided `requirement`. */
540
- max(requirement:string|ODVersion){
541
- if (typeof requirement == "string") requirement = ODVersion.fromString("temp",requirement)
542
-
543
- //skip when primary version is higher or lower than current one.
544
- if (this.primary < requirement.primary) return true
545
- else if (this.primary > requirement.primary) return false
546
-
547
- //skip when secondary version is higher or lower than current one.
548
- if (this.secondary < requirement.secondary) return true
549
- else if (this.secondary > requirement.secondary) return false
550
-
551
- //skip when tertiary version is higher or lower than current one.
552
- if (this.tertiary < requirement.tertiary) return true
553
- else if (this.tertiary > requirement.tertiary) return false
554
-
555
- return true
556
- }
557
- /**Check if this version is matches the major version (`vX.X`) of the provided `requirement`. */
558
- major(requirement:string|ODVersion){
559
- if (typeof requirement == "string") requirement = ODVersion.fromString("temp",requirement)
560
- return (this.primary == requirement.primary && this.secondary == requirement.secondary)
561
- }
562
- /**Check if this version is matches the minor version (`vX.X.X`) of the provided `requirement`. */
563
- minor(requirement:string|ODVersion){
564
- if (typeof requirement == "string") requirement = ODVersion.fromString("temp",requirement)
565
- return (this.primary == requirement.primary && this.secondary == requirement.secondary && this.tertiary == requirement.tertiary)
566
- }
567
- }
568
-
569
- /**## ODVersionMigration `class`
570
- * This class is used to manage data migration between Open Ticket versions.
571
- *
572
- * It shouldn't be used by plugins because this is an internal API feature!
573
- */
574
- export class ODVersionMigration {
575
- /**The version to migrate data to */
576
- version: ODVersion
577
- /**The migration function */
578
- private migrateFunc: () => void|Promise<void>
579
- /**The migration function */
580
- private migrateAfterInitFunc: () => void|Promise<void>
581
-
582
- constructor(version:ODVersion,migrateFunc:() => void|Promise<void>,migrateAfterInitFunc:() => void|Promise<void>){
583
- this.version = version
584
- this.migrateFunc = migrateFunc
585
- this.migrateAfterInitFunc = migrateAfterInitFunc
586
- }
587
- /**Run this version migration as a plugin. Returns `false` when something goes wrong. */
588
- async migrate(): Promise<boolean> {
589
- try{
590
- await this.migrateFunc()
591
- return true
592
- }catch(err){
593
- process.emit("uncaughtException",err)
594
- return false
595
- }
596
- }
597
- /**Run this version migration as a plugin (after other plugins have loaded). Returns `false` when something goes wrong. */
598
- async migrateAfterInit(): Promise<boolean> {
599
- try{
600
- await this.migrateAfterInitFunc()
601
- return true
602
- }catch(err){
603
- process.emit("uncaughtException",err)
604
- return false
605
- }
606
- }
607
- }
608
-
609
- /**## ODHTTPGetRequest `class`
610
- * This is a class that can help you with creating simple HTTP GET requests.
611
- *
612
- * It works using the native node.js fetch() method. You can configure all options in the constructor!
613
- * @example
614
- * const request = new api.ODHTTPGetRequest("https://www.example.com/abc.txt",false,{})
615
- *
616
- * const result = await request.run()
617
- * result.body //the response body (string)
618
- * result.status //the response code (number)
619
- * result.response //the full response (object)
620
- */
621
- export class ODHTTPGetRequest {
622
- /**The url used in the request */
623
- url: string
624
- /**The request config for additional options */
625
- config: RequestInit
626
- /**Throw on error OR return http code 500 */
627
- throwOnError: boolean
628
-
629
- constructor(main:ODMain,url:string,throwOnError:boolean,config?:RequestInit){
630
- if (typeof url != "string") throw new ODSystemError("Invalid constructor parameter => url:string")
631
- if (typeof throwOnError != "boolean") throw new ODSystemError("Invalid constructor parameter => throwOnError:boolean")
632
- if (typeof config != "undefined" && typeof config != "object") throw new ODSystemError("Invalid constructor parameter => config?:RequestInit")
633
-
634
- this.url = url
635
- this.throwOnError = throwOnError
636
- const newConfig = config ?? {}
637
- newConfig.method = "GET"
638
- const userAgent = ((main.project == "openticket") ? "OpenDiscordBots-OpenTicket" : "OpenDiscordBots-OpenModeration") +"/"+(main.versions.get("opendiscord:version")?.toString(true) ?? "<OD:UNKNOWN_VERSION>")
639
- if (newConfig.headers) Object.assign(newConfig.headers,{"User-Agent":userAgent})
640
- else newConfig.headers = {"User-Agent":userAgent}
641
- this.config = newConfig
642
- }
643
-
644
- /**Execute the GET request.*/
645
- run(): Promise<{status:number, body:string, response?:Response}> {
646
- return new Promise(async (resolve,reject) => {
647
- try{
648
- const response = await fetch(this.url,this.config)
649
- resolve({
650
- status:response.status,
651
- body:(await response.text()),
652
- response:response
653
- })
654
- }catch(err){
655
- if (this.throwOnError) return reject("[OPENTICKET ERROR]: ODHTTPGetRequest => Unknown fetch() error: "+err)
656
- else return resolve({
657
- status:500,
658
- body:"Open Discord Error: Unknown fetch() error: "+err,
659
- })
660
- }
661
- })
662
- }
663
- }
664
-
665
- /**## ODHTTPPostRequest `class`
666
- * This is a class that can help you with creating simple HTTP POST requests.
667
- *
668
- * It works using the native node.js fetch() method. You can configure all options in the constructor!
669
- * @example
670
- * const request = new api.ODHTTPPostRequest("https://www.example.com/abc.txt",false,{})
671
- *
672
- * const result = await request.run()
673
- * result.body //the response body (string)
674
- * result.status //the response code (number)
675
- * result.response //the full response (object)
676
- */
677
- export class ODHTTPPostRequest {
678
- /**The url used in the request */
679
- url: string
680
- /**The request config for additional options */
681
- config: RequestInit
682
- /**Throw on error OR return http code 500 */
683
- throwOnError: boolean
684
-
685
- constructor(main:ODMain,url:string,throwOnError:boolean,config?:RequestInit){
686
- if (typeof url != "string") throw new ODSystemError("Invalid constructor parameter => url:string")
687
- if (typeof throwOnError != "boolean") throw new ODSystemError("Invalid constructor parameter => throwOnError:boolean")
688
- if (typeof config != "undefined" && typeof config != "object") throw new ODSystemError("Invalid constructor parameter => config?:RequestInit")
689
-
690
- this.url = url
691
- this.throwOnError = throwOnError
692
- const newConfig = config ?? {}
693
- newConfig.method = "POST"
694
- const userAgent = ((main.project == "openticket") ? "OpenDiscordBots-OpenTicket" : "OpenDiscordBots-OpenModeration") +"/"+(main.versions.get("opendiscord:version")?.toString(true) ?? "<OD:UNKNOWN_VERSION>")
695
- if (newConfig.headers) Object.assign(newConfig.headers,{"User-Agent":userAgent})
696
- else newConfig.headers = {"User-Agent":userAgent}
697
- this.config = newConfig
698
- }
699
-
700
- /**Execute the POST request.*/
701
- run(): Promise<{status:number, body:string, response?:Response}> {
702
- return new Promise(async (resolve,reject) => {
703
- try{
704
- const response = await fetch(this.url,this.config)
705
- resolve({
706
- status:response.status,
707
- body:(await response.text()),
708
- response:response
709
- })
710
- }catch(err){
711
- if (this.throwOnError) return reject("[OPENTICKET ERROR]: ODHTTPPostRequest => Unknown fetch() error: "+err)
712
- else return resolve({
713
- status:500,
714
- body:"Open Discord Error: Unknown fetch() error!",
715
- })
716
- }
717
- })
718
- }
719
- }
720
-
721
- /**## ODEnvHelper `class`
722
- * This is a utility class that helps you with reading the ENV.
723
- *
724
- * It has support for the built-in `process.env` & `.env` file
725
- * @example
726
- * const envHelper = new api.ODEnvHelper()
727
- *
728
- * const variableA = envHelper.getVariable("value-a")
729
- * const variableB = envHelper.getVariable("value-b","dotenv") //only get from .env
730
- * const variableA = envHelper.getVariable("value-c","env") //only get from process.env
731
- */
732
- export class ODEnvHelper {
733
- /**All variables found in the `.env` file */
734
- dotenv: Record<string,any>
735
- /**All variables found in `process.env` */
736
- env: Record<string,any>
737
-
738
- constructor(customEnvPath?:string){
739
- if (typeof customEnvPath != "undefined" && typeof customEnvPath != "string") throw new ODSystemError("Invalid constructor parameter => customEnvPath?:string")
740
-
741
- const path = customEnvPath ? customEnvPath : ".env"
742
- this.dotenv = fs.existsSync(path) ? this.readDotEnv(fs.readFileSync(path)) : {}
743
- this.env = process.env
744
- }
745
-
746
- /**Get a variable from the env */
747
- getVariable(name:string,source?:"dotenv"|"env"): any|undefined {
748
- if (typeof name != "string") throw new ODSystemError("Invalid function parameter => name:string")
749
- if ((typeof source != "undefined" && typeof source != "string") || (source && !["env","dotenv"].includes(source))) throw new ODSystemError("Invalid function parameter => source:'dotenv'|'env'")
750
-
751
- if (source == "dotenv"){
752
- return this.dotenv[name]
753
- }else if (source == "env"){
754
- return this.env[name]
755
- }else{
756
- //when no source specified => .env has priority over process.env
757
- if (this.dotenv[name]) return this.dotenv[name]
758
- else return this.env[name]
759
- }
760
- }
761
-
762
- //THIS CODE IS COPIED FROM THE DODENV-LIB
763
- //Repo: https://github.com/motdotla/dotenv
764
- //Source: https://github.com/motdotla/dotenv/blob/master/lib/main.js#L12
765
- //All rights go to the original authors of the dotenv library.
766
- protected readDotEnv(src:Buffer){
767
- const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg
768
- const obj: Record<string,any> = {}
769
-
770
- // Convert buffer to string
771
- let lines = src.toString()
772
-
773
- // Convert line breaks to same format
774
- lines = lines.replace(/\r\n?/mg, '\n')
775
-
776
- let match
777
- while ((match = LINE.exec(lines)) != null) {
778
- const key = match[1]
779
-
780
- // Default undefined or null to empty string
781
- let value = (match[2] || '')
782
-
783
- // Remove whitespace
784
- value = value.trim()
785
-
786
- // Check if double quoted
787
- const maybeQuote = value[0]
788
-
789
- // Remove surrounding quotes
790
- value = value.replace(/^(['"`])([\s\S]*)\1$/mg, '$2')
791
-
792
- // Expand newlines if double quoted
793
- if (maybeQuote === '"') {
794
- value = value.replace(/\\n/g, '\n')
795
- value = value.replace(/\\r/g, '\r')
796
- }
797
-
798
- // Add to object
799
- obj[key] = value
800
- }
801
- return obj
802
- }
803
- }
804
-
805
- /**## ODSystemError `class`
806
- * A wrapper for the node.js `Error` class that makes the error look better in the console!
807
- *
808
- * This wrapper is made for Open Discord system errors! **It can only be used by Open Discord itself!**
809
- */
810
- export class ODSystemError extends Error {
811
- /**This variable gets detected by the error handling system to know how to render it */
812
- _ODErrorType = "system"
813
-
814
- /**Create an `ODSystemError` directly from an `Error` class */
815
- static fromError(err:Error){
816
- const modifiedErr: ODSystemError = Object.assign(err,{
817
- _ODErrorType:"system"
818
- })
819
- return modifiedErr as ODSystemError
820
- }
821
- }
822
-
823
- /**## ODPluginError `class`
824
- * A wrapper for the node.js `Error` class that makes the error look better in the console!
825
- *
826
- * This wrapper is made for Open Discord plugin errors! **It can only be used by plugins!**
827
- */
828
- export class ODPluginError extends Error {
829
- /**This variable gets detected by the error handling system to know how to render it */
830
- _ODErrorType = "plugin"
831
-
832
- /**Create an `ODPluginError` directly from an `Error` class */
833
- static fromError(err:Error){
834
- const modifiedErr: ODPluginError = Object.assign(err,{
835
- _ODErrorType:"plugin"
836
- })
837
- return modifiedErr as ODPluginError
838
- }
839
- }
840
-
841
- /**Oh, what could this be `¯\_(ツ)_/¯` */
842
- export interface ODEasterEggs {
843
- creator:string,
844
- translators:string[]
845
- }