@open-discord-bots/framework 0.2.17 → 0.3.1
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/index.d.ts +16 -15
- package/dist/api/index.js +16 -15
- package/dist/api/main.d.ts +31 -23
- package/dist/api/main.js +3 -1
- package/dist/api/modules/action.d.ts +2 -2
- package/dist/api/modules/action.js +1 -5
- package/dist/api/modules/base.d.ts +29 -11
- package/dist/api/modules/base.js +78 -80
- package/dist/api/modules/builder.d.ts +2 -11
- package/dist/api/modules/builder.js +0 -4
- package/dist/api/modules/checker.d.ts +28 -7
- package/dist/api/modules/checker.js +33 -37
- package/dist/api/modules/client.d.ts +66 -14
- package/dist/api/modules/client.js +146 -132
- package/dist/api/modules/component.d.ts +928 -0
- package/dist/api/modules/component.js +1346 -0
- package/dist/api/modules/config.d.ts +30 -2
- package/dist/api/modules/config.js +90 -7
- package/dist/api/modules/console.d.ts +16 -4
- package/dist/api/modules/console.js +25 -25
- package/dist/api/modules/cooldown.d.ts +5 -5
- package/dist/api/modules/cooldown.js +1 -17
- package/dist/api/modules/database.d.ts +21 -13
- package/dist/api/modules/database.js +0 -23
- package/dist/api/modules/event.d.ts +4 -2
- package/dist/api/modules/event.js +8 -10
- package/dist/api/modules/fuse.d.ts +1 -1
- package/dist/api/modules/helpmenu.d.ts +11 -9
- package/dist/api/modules/helpmenu.js +24 -22
- package/dist/api/modules/language.d.ts +4 -3
- package/dist/api/modules/language.js +9 -16
- package/dist/api/modules/permission.d.ts +10 -1
- package/dist/api/modules/permission.js +17 -20
- package/dist/api/modules/plugin.d.ts +2 -1
- package/dist/api/modules/plugin.js +2 -2
- package/dist/api/modules/post.d.ts +12 -4
- package/dist/api/modules/post.js +36 -10
- package/dist/api/modules/progressbar.d.ts +18 -6
- package/dist/api/modules/progressbar.js +35 -35
- package/dist/api/modules/responder.d.ts +97 -28
- package/dist/api/modules/responder.js +213 -176
- package/dist/api/modules/session.d.ts +11 -2
- package/dist/api/modules/session.js +16 -16
- package/dist/api/modules/startscreen.d.ts +2 -3
- package/dist/api/modules/startscreen.js +8 -9
- package/dist/api/modules/statistic.d.ts +2 -1
- package/dist/api/modules/statistic.js +4 -7
- package/dist/api/modules/worker.d.ts +2 -1
- package/dist/api/modules/worker.js +3 -3
- package/package.json +3 -2
- package/src/api/index.ts +16 -15
- package/src/api/main.ts +33 -24
- package/src/api/modules/action.ts +2 -4
- package/src/api/modules/base.ts +77 -79
- package/src/api/modules/builder.ts +2 -14
- package/src/api/modules/checker.ts +36 -37
- package/src/api/modules/client.ts +144 -136
- package/src/api/modules/component.ts +1826 -0
- package/src/api/modules/config.ts +86 -7
- package/src/api/modules/console.ts +25 -25
- package/src/api/modules/cooldown.ts +8 -13
- package/src/api/modules/database.ts +24 -32
- package/src/api/modules/event.ts +6 -10
- package/src/api/modules/fuse.ts +1 -1
- package/src/api/modules/helpmenu.ts +31 -27
- package/src/api/modules/language.ts +11 -16
- package/src/api/modules/permission.ts +17 -20
- package/src/api/modules/plugin.ts +2 -2
- package/src/api/modules/post.ts +31 -10
- package/src/api/modules/progressbar.ts +36 -37
- package/src/api/modules/responder.ts +234 -185
- package/src/api/modules/session.ts +15 -15
- package/src/api/modules/startscreen.ts +9 -10
- package/src/api/modules/statistic.ts +4 -7
- package/src/api/modules/worker.ts +3 -3
- package/src/api/modules/component.txt +0 -350
|
@@ -67,28 +67,28 @@ export type ODSessionTimeoutCallback = (id:string, timeout:"default"|"custom", d
|
|
|
67
67
|
/**## ODSession `class`
|
|
68
68
|
* This is an Open Discord session.
|
|
69
69
|
*
|
|
70
|
-
* It can be used to create
|
|
70
|
+
* It can be used to create unique user sessions with an ID. Each session can store additional data which isn't saved to the filesystem.
|
|
71
71
|
* You can almost compare it to the PHP session system.
|
|
72
72
|
*/
|
|
73
73
|
export class ODSession extends ODManagerData {
|
|
74
74
|
/**The history of previously generated instance ids. Used to reduce the risk of generating the same id twice. */
|
|
75
|
-
|
|
75
|
+
protected idHistory: string[] = []
|
|
76
76
|
/**The max length of the instance id history. */
|
|
77
|
-
|
|
77
|
+
protected maxIdHistoryLength: number = 500
|
|
78
78
|
/**An array of all the currently active session instances. */
|
|
79
79
|
sessions: ODSessionInstance[] = []
|
|
80
80
|
/**The default amount of minutes before a session automatically stops. */
|
|
81
81
|
timeoutMinutes: number = 30
|
|
82
82
|
/**The id of the auto-timeout session checker interval */
|
|
83
|
-
|
|
83
|
+
protected intervalId: NodeJS.Timeout
|
|
84
84
|
/**Listeners for when a session times-out. */
|
|
85
|
-
|
|
85
|
+
protected timeoutListeners: ODSessionTimeoutCallback[] = []
|
|
86
86
|
|
|
87
87
|
constructor(id:ODValidId, intervalSeconds?:number){
|
|
88
88
|
super(id)
|
|
89
89
|
|
|
90
90
|
//create the auto-timeout session checker
|
|
91
|
-
this
|
|
91
|
+
this.intervalId = setInterval(() => {
|
|
92
92
|
const deletableSessions: {instance:ODSessionInstance,reason:"default"|"custom"}[] = []
|
|
93
93
|
|
|
94
94
|
//collect all deletable sessions
|
|
@@ -108,31 +108,31 @@ export class ODSession extends ODManagerData {
|
|
|
108
108
|
this.sessions.splice(index,1)
|
|
109
109
|
|
|
110
110
|
//emit timeout listeners
|
|
111
|
-
this
|
|
111
|
+
this.timeoutListeners.forEach((cb) => cb(session.instance.id,session.reason,session.instance.data,new Date(session.instance.creation)))
|
|
112
112
|
})
|
|
113
113
|
|
|
114
114
|
},((intervalSeconds) ? (intervalSeconds * 1000) : 60000))
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
/**Create a unique hex id of 8 characters and add it to the instance id history */
|
|
118
|
-
|
|
118
|
+
protected createUniqueId(): string {
|
|
119
119
|
const hex = crypto.randomBytes(4).toString("hex")
|
|
120
|
-
if (this
|
|
121
|
-
return this
|
|
120
|
+
if (this.idHistory.includes(hex)){
|
|
121
|
+
return this.createUniqueId()
|
|
122
122
|
}else{
|
|
123
|
-
this
|
|
124
|
-
if (this
|
|
123
|
+
this.idHistory.push(hex)
|
|
124
|
+
if (this.idHistory.length > this.maxIdHistoryLength) this.idHistory.shift()
|
|
125
125
|
return hex
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
/**Stop the global interval that automatically deletes timed-out sessions. (This action can't be reverted!) */
|
|
129
129
|
stopAutoTimeout(){
|
|
130
|
-
clearInterval(this
|
|
130
|
+
clearInterval(this.intervalId)
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
/**Start a session instance with data. Returns the unique id required to access the session. */
|
|
134
134
|
start(data?:any): string {
|
|
135
|
-
const id = this
|
|
135
|
+
const id = this.createUniqueId()
|
|
136
136
|
this.sessions.push({
|
|
137
137
|
id,data,
|
|
138
138
|
creation:new Date().getTime(),
|
|
@@ -176,6 +176,6 @@ export class ODSession extends ODManagerData {
|
|
|
176
176
|
}
|
|
177
177
|
/**Listen for a session timeout (default or custom) */
|
|
178
178
|
onTimeout(callback:ODSessionTimeoutCallback){
|
|
179
|
-
this
|
|
179
|
+
this.timeoutListeners.push(callback)
|
|
180
180
|
}
|
|
181
181
|
}
|
|
@@ -24,14 +24,11 @@ export type ODStartScreenManagerIdConstraint = Record<string,ODStartScreenCompon
|
|
|
24
24
|
* The startscreen is the part you see when the bot has started up successfully. (e.g. the Open Discord logo, logs, livestatus, flags, ...)
|
|
25
25
|
*/
|
|
26
26
|
export class ODStartScreenManager<IdList extends ODStartScreenManagerIdConstraint = ODStartScreenManagerIdConstraint,LiveStatus extends ODLiveStatusManager = ODLiveStatusManager> extends ODManager<ODStartScreenComponent> {
|
|
27
|
-
/**Alias to the Open Discord debugger. */
|
|
28
|
-
#debug: ODDebugger
|
|
29
27
|
/**Alias to the livestatus manager. */
|
|
30
28
|
livestatus: LiveStatus
|
|
31
29
|
|
|
32
30
|
constructor(debug:ODDebugger,livestatus:LiveStatus){
|
|
33
31
|
super(debug,"startscreen component")
|
|
34
|
-
this.#debug = debug
|
|
35
32
|
this.livestatus = livestatus
|
|
36
33
|
}
|
|
37
34
|
|
|
@@ -51,10 +48,10 @@ export class ODStartScreenManager<IdList extends ODStartScreenManagerIdConstrain
|
|
|
51
48
|
try {
|
|
52
49
|
const renderedText = await component.renderAll(location)
|
|
53
50
|
console.log(renderedText)
|
|
54
|
-
this
|
|
51
|
+
this.debug?.console.debugfile.writeText("[STARTSCREEN] Component: \""+component.id+"\"\n"+ansis.strip(renderedText))
|
|
55
52
|
}catch(e){
|
|
56
|
-
this
|
|
57
|
-
this
|
|
53
|
+
this.debug?.console.log("Unable to render \""+component.id+"\" startscreen component!","error")
|
|
54
|
+
this.debug?.console.debugfile.writeErrorMessage(new ODError(e,"uncaughtException"))
|
|
58
55
|
}
|
|
59
56
|
location++
|
|
60
57
|
}
|
|
@@ -90,20 +87,22 @@ export class ODStartScreenManager<IdList extends ODStartScreenManagerIdConstrain
|
|
|
90
87
|
*
|
|
91
88
|
* It's recommended to use pre-built components except if you really need a custom one.
|
|
92
89
|
*/
|
|
93
|
-
export class ODStartScreenComponent extends ODManagerData {
|
|
90
|
+
export abstract class ODStartScreenComponent extends ODManagerData {
|
|
94
91
|
/**The priority of this component. */
|
|
95
92
|
priority: number
|
|
96
93
|
/**An optional render function which will be inserted before the default renderer. */
|
|
97
|
-
renderBefore: ODStartScreenComponentRenderCallback|null
|
|
94
|
+
renderBefore: ODStartScreenComponentRenderCallback|null
|
|
98
95
|
/**The render function which will render the contents of this component. */
|
|
99
96
|
render: ODStartScreenComponentRenderCallback
|
|
100
97
|
/**An optional render function which will be inserted behind the default renderer. */
|
|
101
|
-
renderAfter: ODStartScreenComponentRenderCallback|null
|
|
98
|
+
renderAfter: ODStartScreenComponentRenderCallback|null
|
|
102
99
|
|
|
103
|
-
constructor(id:ODValidId, priority:number, render:ODStartScreenComponentRenderCallback){
|
|
100
|
+
constructor(id:ODValidId, priority:number, render:ODStartScreenComponentRenderCallback,renderBefore?:ODStartScreenComponentRenderCallback,renderAfter?:ODStartScreenComponentRenderCallback){
|
|
104
101
|
super(id)
|
|
105
102
|
this.priority = priority
|
|
106
103
|
this.render = render
|
|
104
|
+
this.renderBefore = renderBefore ?? null
|
|
105
|
+
this.renderAfter = renderAfter ?? null
|
|
107
106
|
}
|
|
108
107
|
|
|
109
108
|
/**Render this component and combine it with the `renderBefore` & `renderAfter` contents. */
|
|
@@ -37,16 +37,13 @@ export type ODStatisticManagerIdConstraint = Record<string,ODStatisticScope>
|
|
|
37
37
|
* Statistic can be accessed in the individual scopes.
|
|
38
38
|
*/
|
|
39
39
|
export class ODStatisticManager<IdList extends ODStatisticManagerIdConstraint = ODStatisticManagerIdConstraint> extends ODManager<ODStatisticScope> {
|
|
40
|
-
/**Alias to Open Discord debugger. */
|
|
41
|
-
#debug: ODDebugger
|
|
42
40
|
/**Alias to Open Discord statistics database. */
|
|
43
41
|
database: ODDatabase<ODDatabaseIdConstraint>|null = null
|
|
44
42
|
/**All the listeners for the init event. */
|
|
45
|
-
|
|
43
|
+
protected initListeners: ODStatisticManagerInitCallback[] = []
|
|
46
44
|
|
|
47
45
|
constructor(debug:ODDebugger){
|
|
48
46
|
super(debug,"statistic scope")
|
|
49
|
-
this.#debug = debug
|
|
50
47
|
}
|
|
51
48
|
|
|
52
49
|
/**Select the database to use to read/write all statistics from/to. */
|
|
@@ -54,7 +51,7 @@ export class ODStatisticManager<IdList extends ODStatisticManagerIdConstraint =
|
|
|
54
51
|
this.database = database
|
|
55
52
|
}
|
|
56
53
|
add(data:ODStatisticScope, overwrite?:boolean): boolean {
|
|
57
|
-
data.useDebug(this
|
|
54
|
+
data.useDebug(this.debug,"stat")
|
|
58
55
|
if (this.database) data.useDatabase(this.database)
|
|
59
56
|
return super.add(data,overwrite)
|
|
60
57
|
}
|
|
@@ -76,7 +73,7 @@ export class ODStatisticManager<IdList extends ODStatisticManagerIdConstraint =
|
|
|
76
73
|
})
|
|
77
74
|
|
|
78
75
|
//do additional deletion
|
|
79
|
-
for (const cb of this
|
|
76
|
+
for (const cb of this.initListeners){
|
|
80
77
|
await cb(data,deletableStats)
|
|
81
78
|
}
|
|
82
79
|
|
|
@@ -96,7 +93,7 @@ export class ODStatisticManager<IdList extends ODStatisticManagerIdConstraint =
|
|
|
96
93
|
}
|
|
97
94
|
/**Run a function when the statistics are initialized. This can be used to clear statistics from users that left the server or tickets which don't exist anymore. */
|
|
98
95
|
onInit(callback:ODStatisticManagerInitCallback){
|
|
99
|
-
this
|
|
96
|
+
this.initListeners.push(callback)
|
|
100
97
|
}
|
|
101
98
|
|
|
102
99
|
get<ScopeId extends keyof ODNoGeneric<IdList>>(id:ScopeId): IdList[ScopeId]
|
|
@@ -40,13 +40,13 @@ export class ODWorker<Instance, Origin extends string, Params> extends ODManager
|
|
|
40
40
|
*/
|
|
41
41
|
export class ODWorkerManager<Instance, Origin extends string, Params,WorkerIds extends string = string> extends ODManager<ODWorker<Instance,Origin,Params>> {
|
|
42
42
|
/**The order of execution for workers inside this manager. */
|
|
43
|
-
|
|
43
|
+
protected priorityOrder: "ascending"|"descending"
|
|
44
44
|
/**The backup worker will be executed when one of the workers fails or cancels execution. */
|
|
45
45
|
backupWorker: ODWorker<{reason:"error"|"cancel"},Origin,Params>|null = null
|
|
46
46
|
|
|
47
47
|
constructor(priorityOrder:"ascending"|"descending"){
|
|
48
48
|
super()
|
|
49
|
-
this
|
|
49
|
+
this.priorityOrder = priorityOrder
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
/**Get all workers in sorted order. */
|
|
@@ -61,7 +61,7 @@ export class ODWorkerManager<Instance, Origin extends string, Params,WorkerIds e
|
|
|
61
61
|
/**Execute all workers on an instance using the given origin & parameters. */
|
|
62
62
|
async executeWorkers(instance:Instance, origin:Origin, params:Params){
|
|
63
63
|
const derefParams = {...params}
|
|
64
|
-
const workers = this.getSortedWorkers(this
|
|
64
|
+
const workers = this.getSortedWorkers(this.priorityOrder)
|
|
65
65
|
let didCancel = false
|
|
66
66
|
let didCrash = false
|
|
67
67
|
|
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
///////////////////////////////////////
|
|
2
|
-
//COMPONENTS MODULE
|
|
3
|
-
///////////////////////////////////////
|
|
4
|
-
import { ODId, ODValidId, ODSystemError, ODManagerData, ODNoGeneric, ODManager } from "./base.js"
|
|
5
|
-
import * as discord from "discord.js"
|
|
6
|
-
import { ODWorkerManager, ODWorkerCallback, ODWorker } from "./worker.js"
|
|
7
|
-
import { ODDebugger } from "./console.js"
|
|
8
|
-
|
|
9
|
-
/**## ODComponentFactoryInstance `class`
|
|
10
|
-
* An Open Discord component factory instance.
|
|
11
|
-
*
|
|
12
|
-
* It will contain the final root component which is returned by an `ODComponentFactory`.
|
|
13
|
-
* This component can be used in another `ODComponentFactory` or rendered to a message/modal.
|
|
14
|
-
*/
|
|
15
|
-
export class ODComponentFactoryInstance<Component extends ODComponent<object,any>> {
|
|
16
|
-
/**The root component of this factory. */
|
|
17
|
-
#rootComponent: Component|null = null
|
|
18
|
-
|
|
19
|
-
/**The root component of this factory. */
|
|
20
|
-
getComponent(){
|
|
21
|
-
return this.#rootComponent
|
|
22
|
-
}
|
|
23
|
-
/**Set the root component of this factory. */
|
|
24
|
-
setComponent(c:Component|null){
|
|
25
|
-
this.#rootComponent = c
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**## ODComponentFactory `class`
|
|
30
|
-
* An Open Discord component factory.
|
|
31
|
-
*
|
|
32
|
-
* It is a collection of functions/workers/hooks which will build a Discord message/modal component from scratch.
|
|
33
|
-
* Plugins can intercept and modify these workers to replace default behaviour or layout.
|
|
34
|
-
*/
|
|
35
|
-
export class ODComponentFactory<Component extends ODComponent<object,any>,Origin extends string,Params,WorkerIds extends string = string> extends ODManagerData {
|
|
36
|
-
/**A collection of all workers for this component factory. */
|
|
37
|
-
workers: ODWorkerManager<ODComponentFactoryInstance<Component>,Origin,Params,WorkerIds>
|
|
38
|
-
|
|
39
|
-
constructor(id:ODValidId, callback?:ODWorkerCallback<ODComponentFactoryInstance<Component>,Origin,Params>, priority?:number, callbackId?:ODValidId){
|
|
40
|
-
super(id)
|
|
41
|
-
this.workers = new ODWorkerManager("ascending")
|
|
42
|
-
if (callback) this.workers.add(new ODWorker(callbackId ? callbackId : id,priority ?? 0,callback))
|
|
43
|
-
}
|
|
44
|
-
/**Run all workers and return the resulting component. */
|
|
45
|
-
async build(origin:Origin, params:Params): Promise<ODComponentInferBuildResult<Component>> {
|
|
46
|
-
const instance = new ODComponentFactoryInstance<Component>()
|
|
47
|
-
await this.workers.executeWorkers(instance,origin,params)
|
|
48
|
-
const rootComponent = instance.getComponent()
|
|
49
|
-
if (!rootComponent) throw new ODSystemError("ODComponentFactory.build() --> Failed to build component! (id: "+this.id.value+")")
|
|
50
|
-
return rootComponent.build()
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**## ODComponentManagerIdConstraint `type`
|
|
55
|
-
* The constraint/layout for id mappings/interfaces of the `ODComponentManager` class.
|
|
56
|
-
*/
|
|
57
|
-
export type ODComponentManagerIdConstraint = Record<string,{origin:string,params:object,workers:string}>
|
|
58
|
-
|
|
59
|
-
/**## ODBaseComponentManager `class`
|
|
60
|
-
* A generic Open Discord component manager.
|
|
61
|
-
*
|
|
62
|
-
* It contains a collection of all Open Discord component factories. You can:
|
|
63
|
-
* - Add your own message/modal component factories
|
|
64
|
-
* - Modify existing message/modal component factories
|
|
65
|
-
*
|
|
66
|
-
* Messages created using this system are not compatible with `ODBuilder` messages!
|
|
67
|
-
*/
|
|
68
|
-
export class ODBaseComponentManager<IdList extends ODComponentManagerIdConstraint = ODComponentManagerIdConstraint,Component extends ODComponent<object,any> = ODComponent<object,any>> extends ODManager<ODComponentFactory<Component,string,{},string>> {
|
|
69
|
-
get<FactoryId extends keyof ODNoGeneric<IdList>>(id:FactoryId): ODComponentFactory<Component,IdList[FactoryId]["origin"],IdList[FactoryId]["params"],IdList[FactoryId]["workers"]>
|
|
70
|
-
get(id:ODValidId): ODComponentFactory<Component,string,{},string>|null
|
|
71
|
-
|
|
72
|
-
get(id:ODValidId): ODComponentFactory<Component,string,{},string>|null {
|
|
73
|
-
return super.get(id)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
remove<FactoryId extends keyof ODNoGeneric<IdList>>(id:FactoryId): ODComponentFactory<Component,IdList[FactoryId]["origin"],IdList[FactoryId]["params"],IdList[FactoryId]["workers"]>
|
|
77
|
-
remove(id:ODValidId): ODComponentFactory<Component,string,{},string>|null
|
|
78
|
-
|
|
79
|
-
remove(id:ODValidId): ODComponentFactory<Component,string,{},string>|null {
|
|
80
|
-
return super.remove(id)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
exists(id:keyof ODNoGeneric<IdList>): boolean
|
|
84
|
-
exists(id:ODValidId): boolean
|
|
85
|
-
|
|
86
|
-
exists(id:ODValidId): boolean {
|
|
87
|
-
return super.exists(id)
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**## ODSharedComponentManager `class
|
|
92
|
-
* A special class with types for shared message/modal `ODComponent`'s.
|
|
93
|
-
* Create button, dropdown or any other layout component template to use them in messages & modals.
|
|
94
|
-
*/
|
|
95
|
-
export class ODSharedComponentManager<IdList extends ODComponentManagerIdConstraint = ODComponentManagerIdConstraint> extends ODBaseComponentManager<IdList,ODComponent<object,any>> {
|
|
96
|
-
constructor(debug:ODDebugger){
|
|
97
|
-
super(debug,"shared component")
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**## ODMessageComponentManager `class
|
|
102
|
-
* A special class with types for `ODMessageComponent`'s.
|
|
103
|
-
* Create message templates to use as replies and make use of shared components.
|
|
104
|
-
*/
|
|
105
|
-
export class ODMessageComponentManager<IdList extends ODComponentManagerIdConstraint = ODComponentManagerIdConstraint> extends ODBaseComponentManager<IdList,TODO> {
|
|
106
|
-
constructor(debug:ODDebugger){
|
|
107
|
-
super(debug,"message component")
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**## ODModalComponentManager `class
|
|
112
|
-
* A special class with types for `ODModalComponent`'s.
|
|
113
|
-
* Create modal templates to use as forms and make use of shared components.
|
|
114
|
-
*/
|
|
115
|
-
export class ODModalComponentManager<IdList extends ODComponentManagerIdConstraint = ODComponentManagerIdConstraint> extends ODBaseComponentManager<IdList,TODO> {
|
|
116
|
-
constructor(debug:ODDebugger){
|
|
117
|
-
super(debug,"modal component")
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**## ODComponentManager `class`
|
|
122
|
-
* An Open Discord component manager.
|
|
123
|
-
*
|
|
124
|
-
* Create message & modal templates, re-use components and design all visual elements of the bot.
|
|
125
|
-
*
|
|
126
|
-
* Using the Open Discord component system has many advantages compared to vanilla `discord.js`:
|
|
127
|
-
* - Plugins can extend, edit & replace messages & components
|
|
128
|
-
* - Includes automatic error handling
|
|
129
|
-
* - Independent workers/hooks (with priority)
|
|
130
|
-
* - Fail-safe design using try-catch
|
|
131
|
-
* - Automatic switch between components v2 and legacy components depending on message requirements
|
|
132
|
-
* - Get to know the origin of the request (e.g. button, dropdown, modal, ...)
|
|
133
|
-
* - And so much more!
|
|
134
|
-
*/
|
|
135
|
-
export class ODComponentManager<
|
|
136
|
-
SharedIdList extends ODComponentManagerIdConstraint = ODComponentManagerIdConstraint,
|
|
137
|
-
MessageIdList extends ODComponentManagerIdConstraint = ODComponentManagerIdConstraint,
|
|
138
|
-
ModalIdList extends ODComponentManagerIdConstraint = ODComponentManagerIdConstraint
|
|
139
|
-
> {
|
|
140
|
-
/**The manager for all shared components. */
|
|
141
|
-
shared: ODSharedComponentManager<SharedIdList>
|
|
142
|
-
/**The manager for all messages components. */
|
|
143
|
-
messages: ODMessageComponentManager<MessageIdList>
|
|
144
|
-
/**The manager for all modals components. */
|
|
145
|
-
modals: ODModalComponentManager<ModalIdList>
|
|
146
|
-
|
|
147
|
-
constructor(debug:ODDebugger){
|
|
148
|
-
this.shared = new ODSharedComponentManager(debug)
|
|
149
|
-
this.messages = new ODMessageComponentManager(debug)
|
|
150
|
-
this.modals = new ODModalComponentManager(debug)
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
///////////////////////////////////////
|
|
155
|
-
// GENERIC COMPONENT DEFINITIONS //
|
|
156
|
-
///////////////////////////////////////
|
|
157
|
-
|
|
158
|
-
/**## ODComponentBuilderFunc `type`
|
|
159
|
-
* The builder function of a component.
|
|
160
|
-
*/
|
|
161
|
-
export type ODComponentBuilderFunc<BuildResult> = () => Promise<BuildResult|null>|BuildResult|null
|
|
162
|
-
|
|
163
|
-
/**## ODComponentInferBuildResult `type`
|
|
164
|
-
* Infer the build result of a certain component.
|
|
165
|
-
*/
|
|
166
|
-
export type ODComponentInferBuildResult<Component> = Component extends ODComponent<object,infer BuildResult> ? BuildResult : never
|
|
167
|
-
|
|
168
|
-
/**## ODComponent `class`
|
|
169
|
-
* An Open Discord message/modal component.
|
|
170
|
-
*
|
|
171
|
-
* This class itself doesn't do anything, but is a blueprint for other
|
|
172
|
-
* `ODComponent` classes which represent the new Discord message/modal components.
|
|
173
|
-
*/
|
|
174
|
-
export class ODComponent<Data extends object,BuildResult> {
|
|
175
|
-
/**The id of this message/modal component. */
|
|
176
|
-
id: ODId
|
|
177
|
-
/** */
|
|
178
|
-
/**The data or configuration of this message/modal component. */
|
|
179
|
-
readonly data: Data
|
|
180
|
-
/**Build this component. Returns `null` when invalid. */
|
|
181
|
-
readonly build: ODComponentBuilderFunc<BuildResult>
|
|
182
|
-
|
|
183
|
-
constructor(id:ODValidId,data:Data,build:ODComponentBuilderFunc<BuildResult>){
|
|
184
|
-
this.id = new ODId(id)
|
|
185
|
-
this.data = data
|
|
186
|
-
this.build = build
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**## ODGroupComponent `class`
|
|
191
|
-
* An Open Discord message/modal component with children.
|
|
192
|
-
*
|
|
193
|
-
* This class itself doesn't do anything, but is a blueprint for other
|
|
194
|
-
* `ODGroupComponent` classes which represent the new Discord message/modal components.
|
|
195
|
-
*/
|
|
196
|
-
export class ODGroupComponent<Data extends object,ChildComponent extends ODComponent<object,any>,BuildResult> extends ODComponent<Data,BuildResult> {
|
|
197
|
-
/**The collection of child components. */
|
|
198
|
-
readonly children: ChildComponent[] = []
|
|
199
|
-
|
|
200
|
-
/**Add a new component to this group. There are multiple modes available:
|
|
201
|
-
* - `start`: insert at the start of the list.
|
|
202
|
-
* - `end`: insert at the end of the list.
|
|
203
|
-
* - `before`: insert before an existing component `referenceId` (`start` if `referenceId` is invalid)
|
|
204
|
-
* - `after`: insert after an existing component `referenceId` (`end` if `referenceId` is invalid)
|
|
205
|
-
* - `index`: insert at a certain index `referenceIndex` (`end` if `referenceIndex` is invalid)
|
|
206
|
-
*/
|
|
207
|
-
addComponent(c:ChildComponent,mode:"start"|"end"): void
|
|
208
|
-
addComponent(c:ChildComponent,mode:"before"|"after",referenceId:ODValidId): void
|
|
209
|
-
addComponent(c:ChildComponent,mode:"index",referenceIndex:number): void
|
|
210
|
-
addComponent(c:ChildComponent,mode:"start"|"end"|"before"|"after"|"index" = "start",reference?:ODValidId|number){
|
|
211
|
-
if (mode == "start") this.children.unshift(c)
|
|
212
|
-
else if (mode == "end") this.children.push(c)
|
|
213
|
-
else if (mode == "before"){
|
|
214
|
-
if (!reference || !this.children.find((c) => c.id.value === new ODId(reference).value)) this.children.unshift(c)
|
|
215
|
-
else{
|
|
216
|
-
const referenceIndex = this.children.findIndex((c) => c.id.value === new ODId(reference).value)
|
|
217
|
-
this.children.splice(referenceIndex,0,c) //insert at position 'referenceIndex' (before)
|
|
218
|
-
}
|
|
219
|
-
}else if (mode == "after"){
|
|
220
|
-
if (!reference || !this.children.find((c) => c.id.value === new ODId(reference).value)) this.children.push(c)
|
|
221
|
-
else{
|
|
222
|
-
const referenceIndex = this.children.findIndex((c) => c.id.value === new ODId(reference).value)
|
|
223
|
-
this.children.splice(referenceIndex+1,0,c) //insert at position 'referenceIndex+1' (after)
|
|
224
|
-
}
|
|
225
|
-
}else if (mode == "index"){
|
|
226
|
-
if (!reference || typeof reference !== "number") this.children.push(c)
|
|
227
|
-
else{
|
|
228
|
-
this.children.splice(reference,0,c) //insert at position 'reference'
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
/**Get a component with a certain ID in this group. Returns `null` if non-existent. */
|
|
233
|
-
getComponent(id:ODValidId){
|
|
234
|
-
const component = this.children.find((c) => c.id.value === new ODId(id).value)
|
|
235
|
-
return component ?? null
|
|
236
|
-
}
|
|
237
|
-
/**Get the position of a component with a certain ID in this group. Returns `-1` if non-existent. */
|
|
238
|
-
getComponentPosition(id:ODValidId){
|
|
239
|
-
return this.children.findIndex((c) => c.id.value === new ODId(id).value)
|
|
240
|
-
}
|
|
241
|
-
/**Returns if a component with a certain ID exists in this group. */
|
|
242
|
-
existsComponent(id:ODValidId){
|
|
243
|
-
const component = this.children.find((c) => c.id.value === new ODId(id).value)
|
|
244
|
-
return component ? true : false
|
|
245
|
-
}
|
|
246
|
-
/**Remove a component with a certain ID from this group. Returns the removed component or `null if non-existent. */
|
|
247
|
-
removeComponent(id:ODValidId){
|
|
248
|
-
const index = this.children.findIndex((c) => c.id.value === new ODId(id).value)
|
|
249
|
-
if (index < 0) return null
|
|
250
|
-
else return this.children.splice(index,1)[0]
|
|
251
|
-
}
|
|
252
|
-
/**Moves an existing component to a new location in this group. There are multiple modes available:
|
|
253
|
-
* - `start`: move to the start of the list.
|
|
254
|
-
* - `end`: move to the end of the list.
|
|
255
|
-
* - `before`: move before an existing component `referenceId` (`start` if `referenceId` is invalid)
|
|
256
|
-
* - `after`: move after an existing component `referenceId` (`end` if `referenceId` is invalid)
|
|
257
|
-
* - `index`: move to a certain index `referenceIndex` (`end` if `referenceIndex` is invalid)
|
|
258
|
-
*/
|
|
259
|
-
moveComponent(id:ODValidId,mode:"start"|"end"): void
|
|
260
|
-
moveComponent(id:ODValidId,mode:"before"|"after",referenceId:ODValidId): void
|
|
261
|
-
moveComponent(id:ODValidId,mode:"index",referenceIndex:number): void
|
|
262
|
-
moveComponent(id:ODValidId,mode:"start"|"end"|"before"|"after"|"index" = "start",reference?:ODValidId|number){
|
|
263
|
-
const component = this.removeComponent(id)
|
|
264
|
-
if (component){
|
|
265
|
-
if (mode == "start" || mode == "end") this.addComponent(component,mode)
|
|
266
|
-
if ((mode == "before" || mode == "after") && reference) this.addComponent(component,mode,reference)
|
|
267
|
-
if (mode == "index" && typeof reference == "number") this.addComponent(component,mode,reference)
|
|
268
|
-
return
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**## ODParentComponent `class`
|
|
274
|
-
* An Open Discord message/modal component with a single child.
|
|
275
|
-
*
|
|
276
|
-
* This class itself doesn't do anything, but is a blueprint for other
|
|
277
|
-
* `ODParentComponent` classes which represent the new Discord message/modal components.
|
|
278
|
-
*/
|
|
279
|
-
export class ODParentComponent<Data extends object,ChildComponent extends ODComponent<object,any>,BuildResult> extends ODComponent<Data,BuildResult> {
|
|
280
|
-
/**The child component of this parent. */
|
|
281
|
-
#child: ChildComponent|null = null
|
|
282
|
-
|
|
283
|
-
/**The child component of this parent. */
|
|
284
|
-
get child(){
|
|
285
|
-
return this.#child
|
|
286
|
-
}
|
|
287
|
-
/**Set the child component of this parent. */
|
|
288
|
-
setComponent(c:ChildComponent|null){
|
|
289
|
-
this.#child = c
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
//////////////////////////////////////
|
|
294
|
-
// GLOBAL COMPONENT DEFINITIONS //
|
|
295
|
-
//////////////////////////////////////
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
//////////////////////////////////////
|
|
300
|
-
// LAYOUT COMPONENT DEFINITIONS //
|
|
301
|
-
//////////////////////////////////////
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
///////////////////////////////////////
|
|
306
|
-
// CONTENT COMPONENT DEFINITIONS //
|
|
307
|
-
///////////////////////////////////////
|
|
308
|
-
|
|
309
|
-
/**## ODTextComponentData `type`
|
|
310
|
-
* The configurable settings/options for the `ODTextComponent`.
|
|
311
|
-
*/
|
|
312
|
-
export interface ODTextComponentData {
|
|
313
|
-
/**The text to display. */
|
|
314
|
-
content:string
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/**## ODTextComponent `class`
|
|
318
|
-
* A text component which renders markdown text in a message.
|
|
319
|
-
*/
|
|
320
|
-
export class ODTextComponent extends ODComponent<ODTextComponentData,discord.TextDisplayBuilder> {
|
|
321
|
-
constructor(id:ODValidId,data:Partial<ODTextComponentData>){
|
|
322
|
-
const initData: ODTextComponentData = {content:"",...data}
|
|
323
|
-
super(id,initData,() => {
|
|
324
|
-
if (this.data.content.length < 1) return null
|
|
325
|
-
return new discord.TextDisplayBuilder({
|
|
326
|
-
content:this.data.content
|
|
327
|
-
})
|
|
328
|
-
})
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**Set the text to display. */
|
|
332
|
-
setContent(value:string){
|
|
333
|
-
this.data.content = value
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/* TODO
|
|
338
|
-
* 🔴 ODFileComponent
|
|
339
|
-
* 🔴 ODGalleryComponent
|
|
340
|
-
* 🔴 ODThumbnailComponent
|
|
341
|
-
* 🔴 ODContentComponent (simple msg)
|
|
342
|
-
* 🔴 ODPollComponent (simple msg)
|
|
343
|
-
* 🔴 ODEmbedComponent (simple msg)
|
|
344
|
-
* 🔴 ODStickerComponent (simple msg)
|
|
345
|
-
*/
|
|
346
|
-
|
|
347
|
-
///////////////////////////////////////////
|
|
348
|
-
// INTERACTIVE COMPONENT DEFINITIONS //
|
|
349
|
-
///////////////////////////////////////////
|
|
350
|
-
|