@open-discord-bots/framework 0.2.17 → 0.3.0

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 (49) hide show
  1. package/dist/api/index.d.ts +16 -15
  2. package/dist/api/index.js +16 -15
  3. package/dist/api/main.d.ts +31 -23
  4. package/dist/api/main.js +3 -1
  5. package/dist/api/modules/action.d.ts +2 -2
  6. package/dist/api/modules/action.js +1 -5
  7. package/dist/api/modules/base.d.ts +2 -2
  8. package/dist/api/modules/builder.d.ts +2 -2
  9. package/dist/api/modules/builder.js +0 -4
  10. package/dist/api/modules/checker.d.ts +2 -2
  11. package/dist/api/modules/checker.js +2 -6
  12. package/dist/api/modules/component.d.ts +922 -0
  13. package/dist/api/modules/component.js +1344 -0
  14. package/dist/api/modules/config.d.ts +30 -1
  15. package/dist/api/modules/config.js +81 -0
  16. package/dist/api/modules/cooldown.d.ts +5 -5
  17. package/dist/api/modules/cooldown.js +1 -17
  18. package/dist/api/modules/database.d.ts +21 -13
  19. package/dist/api/modules/database.js +0 -23
  20. package/dist/api/modules/helpmenu.d.ts +9 -7
  21. package/dist/api/modules/helpmenu.js +22 -17
  22. package/dist/api/modules/language.d.ts +2 -2
  23. package/dist/api/modules/language.js +3 -7
  24. package/dist/api/modules/progressbar.d.ts +2 -1
  25. package/dist/api/modules/progressbar.js +1 -1
  26. package/dist/api/modules/responder.d.ts +2 -2
  27. package/dist/api/modules/responder.js +0 -4
  28. package/dist/api/modules/session.d.ts +1 -1
  29. package/dist/api/modules/session.js +1 -1
  30. package/dist/api/modules/startscreen.d.ts +2 -2
  31. package/dist/api/modules/startscreen.js +5 -3
  32. package/package.json +3 -2
  33. package/src/api/index.ts +16 -15
  34. package/src/api/main.ts +33 -24
  35. package/src/api/modules/action.ts +2 -4
  36. package/src/api/modules/base.ts +2 -2
  37. package/src/api/modules/builder.ts +2 -4
  38. package/src/api/modules/checker.ts +5 -6
  39. package/src/api/modules/component.ts +1822 -0
  40. package/src/api/modules/config.ts +78 -1
  41. package/src/api/modules/cooldown.ts +8 -13
  42. package/src/api/modules/database.ts +24 -32
  43. package/src/api/modules/helpmenu.ts +29 -22
  44. package/src/api/modules/language.ts +5 -7
  45. package/src/api/modules/progressbar.ts +2 -3
  46. package/src/api/modules/responder.ts +2 -4
  47. package/src/api/modules/session.ts +1 -1
  48. package/src/api/modules/startscreen.ts +6 -4
  49. package/src/api/modules/component.txt +0 -350
@@ -6,6 +6,7 @@ import nodepath from "path"
6
6
  import { ODDebugger } from "./console.js"
7
7
  import fs from "fs"
8
8
  import * as fjs from "formatted-json-stringify"
9
+ import { jsonc } from "jsonc"
9
10
 
10
11
  /**## ODConfigManagerIdConstraint `type`
11
12
  * The constraint/layout for id mappings/interfaces of the `ODConfigManager` class.
@@ -71,7 +72,7 @@ export class ODConfigManager<IdList extends ODConfigManagerIdConstraint = ODConf
71
72
  *
72
73
  * You can use this class if you want to create your own config implementation (e.g. `yml`, `xml`,...)!
73
74
  */
74
- export class ODConfig<Data extends any> extends ODManagerData {
75
+ export abstract class ODConfig<Data extends any> extends ODManagerData {
75
76
  /**The name of the file with extension. */
76
77
  file: string = ""
77
78
  /**The path to the file relative to the main directory. */
@@ -182,4 +183,80 @@ export class ODJsonConfig<Data extends any> extends ODConfig<Data> {
182
183
  throw new ODSystemError("Unable to save config \""+nodepath.join("./",this.path)+"\"!")
183
184
  }
184
185
  }
186
+ }
187
+
188
+ /**## ODJsonCommentsConfig `class`
189
+ * An Open Discord JSONC (`.jsonc`) config.
190
+ * Use this class to get & edit variables from the config files or to create your own JSON config!
191
+ * @example
192
+ * //create a config from: ./config/test.jsonc with the id "some-config"
193
+ * const config = new api.ODJsonCommentsConfig("some-config","test.jsonc")
194
+ *
195
+ * //create a config with custom dir: ./plugins/testplugin/test.jsonc
196
+ * const config = new api.ODJsonCommentsConfig("plugin-config","test.jsonc","./plugins/testplugin/")
197
+ */
198
+ export class ODJsonCommentsConfig<Data extends any> extends ODConfig<Data> {
199
+ formatter: fjs.custom.BaseFormatter
200
+
201
+ constructor(id:ODValidId, file:string, customPath?:string, formatter?:fjs.custom.BaseFormatter){
202
+ super(id,{})
203
+ this.file = (file.endsWith(".jsonc")) ? file : file+".jsonc"
204
+ this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./config/",this.file)
205
+ this.formatter = formatter ?? new fjs.DefaultFormatter(null,true," ")
206
+ }
207
+
208
+ /**Init the config. */
209
+ init(): ODPromiseVoid {
210
+ if (!fs.existsSync(this.path)) throw new ODSystemError("Unable to parse JSONC config \""+nodepath.join("./",this.path)+"\", the file doesn't exist!")
211
+ try{
212
+ this.data = jsonc.parse(fs.readFileSync(this.path).toString())
213
+ super.init()
214
+ }catch(err){
215
+ process.emit("uncaughtException",err)
216
+ throw new ODSystemError("Unable to parse JSONC config \""+nodepath.join("./",this.path)+"\"!")
217
+ }
218
+ }
219
+ /**Reload the config. Be aware that this doesn't update the config data everywhere in the bot! */
220
+ reload(){
221
+ if (!this.initiated) throw new ODSystemError("Unable to reload JSONC config \""+nodepath.join("./",this.path)+"\", the file hasn't been initiated yet!")
222
+ if (!fs.existsSync(this.path)) throw new ODSystemError("Unable to JSONC reload config \""+nodepath.join("./",this.path)+"\", the file doesn't exist!")
223
+ try{
224
+ this.data = jsonc.parse(fs.readFileSync(this.path).toString())
225
+ super.reload()
226
+ this.reloadListeners.forEach((cb) => {
227
+ try{
228
+ cb()
229
+ }catch(err){
230
+ process.emit("uncaughtException",err)
231
+ }
232
+ })
233
+ }catch(err){
234
+ process.emit("uncaughtException",err)
235
+ throw new ODSystemError("Unable to reload JSONC config \""+nodepath.join("./",this.path)+"\"!")
236
+ }
237
+ }
238
+ /**Save the edited config to the filesystem. This is used by the Interactive Setup CLI. It's not recommended to use this while the bot is running. */
239
+ save(): ODPromiseVoid {
240
+ if (!this.initiated) throw new ODSystemError("Unable to save JSONC config \""+nodepath.join("./",this.path)+"\", the file hasn't been initiated yet!")
241
+ try{
242
+ const contents = this.formatter.stringify(this.data as ODValidJsonType)
243
+ fs.writeFileSync(this.path,contents)
244
+ super.save()
245
+ }catch(err){
246
+ process.emit("uncaughtException",err)
247
+ throw new ODSystemError("Unable to save JSONC config \""+nodepath.join("./",this.path)+"\"!")
248
+ }
249
+ }
250
+ }
251
+
252
+ /**## ODMemoryConfig `class`
253
+ * An Open Discord memory config.
254
+ * This config lives in-memory and does not have any connection to the filesystem.
255
+ *
256
+ * It is perfect for temporary configs or using the `ODChecker` without a real config file.
257
+ */
258
+ export class ODMemoryConfig<Data extends any> extends ODConfig<Data> {
259
+ constructor(id:ODValidId,data:Data){
260
+ super(id,data)
261
+ }
185
262
  }
@@ -75,7 +75,7 @@ export class ODCooldownData<Data extends object> extends ODManagerData {
75
75
  *
76
76
  * There are also premade cooldowns available in the bot!
77
77
  */
78
- export class ODCooldown<Data extends object> extends ODManagerData {
78
+ export abstract class ODCooldown<Data extends object> extends ODManagerData {
79
79
  data: ODManager<ODCooldownData<Data>> = new ODManager()
80
80
  /**Is this cooldown already initialized? */
81
81
  ready: boolean = false
@@ -85,21 +85,16 @@ export class ODCooldown<Data extends object> extends ODManagerData {
85
85
  }
86
86
 
87
87
  /**Check this id and start cooldown when it exeeds the limit! Returns `true` when on cooldown! */
88
- use(id:string): boolean {
89
- throw new ODSystemError("Tried to use an unimplemented ODCooldown!")
90
- }
88
+ abstract use(id:string): boolean
89
+
91
90
  /**Check this id without starting or updating the cooldown. Returns `true` when on cooldown! */
92
- check(id:string): boolean {
93
- throw new ODSystemError("Tried to use an unimplemented ODCooldown!")
94
- }
91
+ abstract check(id:string): boolean
92
+
95
93
  /**Remove the cooldown for an id when available.*/
96
- delete(id:string){
97
- throw new ODSystemError("Tried to use an unimplemented ODCooldown!")
98
- }
94
+ abstract delete(id:string): void
95
+
99
96
  /**Initialize the internal systems of this cooldown. */
100
- async init(){
101
- throw new ODSystemError("Tried to use an unimplemented ODCooldown!")
102
- }
97
+ abstract init(): Promise<void>|void
103
98
  }
104
99
 
105
100
  /**## ODCounterCooldown `class`
@@ -70,50 +70,42 @@ export type ODDatabaseIdConstraint = Record<string,ODValidJsonType>
70
70
  *
71
71
  * You can use this class if you want to create your own database implementation (e.g. `mongodb`, `mysql`,...)!
72
72
  */
73
- export class ODDatabase<IdList extends ODDatabaseIdConstraint = ODDatabaseIdConstraint> extends ODManagerData {
73
+ export abstract class ODDatabase<IdList extends ODDatabaseIdConstraint = ODDatabaseIdConstraint> extends ODManagerData {
74
74
  /**The name of the file with extension. */
75
75
  file: string = ""
76
76
  /**The path to the file relative to the main directory. */
77
77
  path: string = ""
78
78
 
79
79
  /**Init the database. */
80
- init(): ODPromiseVoid {
81
- //nothing
82
- }
80
+ abstract init(): ODPromiseVoid
81
+
83
82
  /**Add/Overwrite a specific category & key in the database. Returns `true` when overwritten. */
84
- set<CategoryId extends keyof ODNoGeneric<IdList>>(category:CategoryId, key:string, value:IdList[CategoryId]): ODOptionalPromise<boolean>
85
- set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean>
86
- set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> {
87
- return false
88
- }
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
+
89
87
  /**Get a specific category & key in the database */
90
- get<CategoryId extends keyof ODNoGeneric<IdList>>(category:CategoryId, key:string): ODOptionalPromise<IdList[CategoryId]|undefined>
91
- get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined>
92
- get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined> {
93
- return undefined
94
- }
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
+
95
92
  /**Delete a specific category & key in the database */
96
- delete<CategoryId extends keyof ODNoGeneric<IdList>>(category:CategoryId, key:string): ODOptionalPromise<boolean>
97
- delete(category:string, key:string): ODOptionalPromise<boolean>
98
- delete(category:string, key:string): ODOptionalPromise<boolean> {
99
- return false
100
- }
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
+
101
97
  /**Check if a specific category & key exists in the database */
102
- exists(category:keyof ODNoGeneric<IdList>, key:string): ODOptionalPromise<boolean>
103
- exists(category:string, key:string): ODOptionalPromise<boolean>
104
- exists(category:string, key:string): ODOptionalPromise<boolean> {
105
- return false
106
- }
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
+
107
102
  /**Get a specific category in the database */
108
- getCategory<CategoryId extends keyof ODNoGeneric<IdList>>(category:CategoryId): ODOptionalPromise<{key:string, value:IdList[CategoryId]}[]|undefined>
109
- getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined>
110
- getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> {
111
- return undefined
112
- }
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
+
113
107
  /**Get all values in the database */
114
- getAll(): ODOptionalPromise<ODJsonDatabaseStructure> {
115
- return []
116
- }
108
+ abstract getAll(): ODOptionalPromise<ODJsonDatabaseStructure>
117
109
  }
118
110
 
119
111
  /**## ODJsonDatabaseStructure `type`
@@ -4,27 +4,22 @@
4
4
  import { ODId, ODManager, ODManagerData, ODNoGeneric, ODSystemError, ODValidId } from "./base.js"
5
5
  import { ODDebugger } from "./console.js"
6
6
 
7
- /**## ODHelpMenuComponentRenderer `type`
8
- * This is the callback of the help menu component renderer. It also contains information about how & where it is rendered.
9
- */
10
- export type ODHelpMenuComponentRenderer = (page:number, category:number, location:number, mode:"slash"|"text") => string|Promise<string>
11
-
12
7
  /**## ODHelpMenuComponent `class`
13
8
  * This is an Open Discord help menu component.
14
9
  *
15
10
  * It can render something on the Open Discord help menu.
16
11
  */
17
- export class ODHelpMenuComponent extends ODManagerData {
12
+ export abstract class ODHelpMenuComponent extends ODManagerData {
18
13
  /**The priority of this component. The higher, the earlier it will appear in the help menu. */
19
14
  priority: number
20
- /**The render function for this component. */
21
- render: ODHelpMenuComponentRenderer
22
15
 
23
- constructor(id:ODValidId, priority:number, render:ODHelpMenuComponentRenderer){
16
+ constructor(id:ODValidId, priority:number){
24
17
  super(id)
25
18
  this.priority = priority
26
- this.render = render
27
19
  }
20
+
21
+ /**The render function for this component. */
22
+ abstract render(page:number, category:number, location:number, mode:"slash"|"text"): string|Promise<string>
28
23
  }
29
24
 
30
25
  /**## ODHelpMenuTextComponent `class`
@@ -33,10 +28,16 @@ export class ODHelpMenuComponent extends ODManagerData {
33
28
  * It can render a static piece of text on the Open Discord help menu.
34
29
  */
35
30
  export class ODHelpMenuTextComponent extends ODHelpMenuComponent {
31
+ /**The text of this help menu component. */
32
+ text: string
33
+
36
34
  constructor(id:ODValidId, priority:number, text:string){
37
- super(id,priority,() => {
38
- return text
39
- })
35
+ super(id,priority)
36
+ this.text = text
37
+ }
38
+
39
+ render(page:number,category:number,location:number,mode:"slash"|"text"){
40
+ return this.text
40
41
  }
41
42
  }
42
43
 
@@ -74,16 +75,22 @@ export interface ODHelpMenuCommandComponentSettings {
74
75
  * It contains a useful helper to render a command in the Open Discord help menu.
75
76
  */
76
77
  export class ODHelpMenuCommandComponent extends ODHelpMenuComponent {
78
+ /**The settings for this help menu component. */
79
+ settings:ODHelpMenuCommandComponentSettings
80
+
77
81
  constructor(id:ODValidId, priority:number, settings:ODHelpMenuCommandComponentSettings){
78
- super(id,priority,(page,category,location,mode) => {
79
- if (mode == "slash" && settings.slashName){
80
- return `\`${settings.slashName}${(settings.slashOptions) ? this.#renderOptions(settings.slashOptions) : ""}\` ➜ ${settings.slashDescription ?? ""}`
81
-
82
- }else if (mode == "text" && settings.textName){
83
- return `\`${settings.textName}${(settings.textOptions) ? this.#renderOptions(settings.textOptions) : ""}\` ${settings.textDescription ?? ""}`
84
-
85
- }else return ""
86
- })
82
+ super(id,priority)
83
+ this.settings = settings
84
+ }
85
+
86
+ render(page:number,category:number,location:number,mode:"slash"|"text"){
87
+ if (mode == "slash" && this.settings.slashName){
88
+ return `\`${this.settings.slashName}${(this.settings.slashOptions) ? this.#renderOptions(this.settings.slashOptions) : ""}\` ➜ ${this.settings.slashDescription ?? ""}`
89
+
90
+ }else if (mode == "text" && this.settings.textName){
91
+ return `\`${this.settings.textName}${(this.settings.textOptions) ? this.#renderOptions(this.settings.textOptions) : ""}\` ➜ ${this.settings.textDescription ?? ""}`
92
+
93
+ }else return ""
87
94
  }
88
95
 
89
96
  /**Utility function to render all command options. */
@@ -45,9 +45,9 @@ export class ODLanguageManager<IdList extends ODLanguageManagerIdConstraint = OD
45
45
 
46
46
  constructor(debug:ODDebugger, presets:boolean){
47
47
  super(debug,"language")
48
- if (presets) this.add(new ODLanguage("english","english.json"))
49
- this.current = presets ? new ODLanguage("english","english.json") : null
50
- this.backup = presets ? new ODLanguage("english","english.json") : null
48
+ if (presets) this.add(new ODJsonLanguage("english","english.json"))
49
+ this.current = presets ? new ODJsonLanguage("english","english.json") : null
50
+ this.backup = presets ? new ODJsonLanguage("english","english.json") : null
51
51
  this.#debug = debug
52
52
  }
53
53
 
@@ -185,7 +185,7 @@ export class ODLanguageManager<IdList extends ODLanguageManagerIdConstraint = OD
185
185
  *
186
186
  * JSON languages should be created using the `ODJsonLanguage` class instead!
187
187
  */
188
- export class ODLanguage extends ODManagerData {
188
+ export abstract class ODLanguage extends ODManagerData {
189
189
  /**The name of the file with extension. */
190
190
  file: string = ""
191
191
  /**The path to the file relative to the main directory. */
@@ -201,9 +201,7 @@ export class ODLanguage extends ODManagerData {
201
201
  }
202
202
 
203
203
  /**Init the language. */
204
- init(): ODPromiseVoid {
205
- //nothing
206
- }
204
+ abstract init(): ODPromiseVoid
207
205
  }
208
206
 
209
207
  /**## ODJsonLanguage `class`
@@ -119,14 +119,13 @@ export class ODProgressBarRenderer<Settings extends {}> extends ODManagerData {
119
119
  return "<PROGRESS-BAR-ERROR>"
120
120
  }
121
121
  }
122
-
122
+ /**Create a clone of this progress bar renderer, but with additional settings. */
123
123
  withAdditionalSettings(settings:Partial<Settings>): ODProgressBarRenderer<Settings> {
124
124
  const newSettings: Settings = {...this.settings}
125
125
  for (const key of Object.keys(settings) as (keyof Partial<Settings>)[]){
126
126
  if (typeof settings[key] != "undefined") newSettings[key] = settings[key]
127
127
  }
128
128
 
129
- const idk = Object.keys(settings)
130
129
  return new ODProgressBarRenderer(this.id,this.#render,newSettings)
131
130
  }
132
131
  }
@@ -139,7 +138,7 @@ export class ODProgressBarRenderer<Settings extends {}> extends ODManagerData {
139
138
  *
140
139
  * Use other classes as existing templates or create your own progress bar from scratch using this class.
141
140
  */
142
- export class ODProgressBar extends ODManagerData {
141
+ export abstract class ODProgressBar extends ODManagerData {
143
142
  /**The renderer of this progress bar. */
144
143
  renderer: ODProgressBarRenderer<{}>
145
144
  /**Is this progress bar currently active? */
@@ -15,7 +15,7 @@ import { ODDropdownData, ODMessageBuildResult, ODMessageBuildSentResult, ODModal
15
15
  *
16
16
  * This class can't be used stand-alone & needs to be extended from!
17
17
  */
18
- export class ODResponderImplementation<Instance,Origin extends string,Params,WorkerIds extends string = string> extends ODManagerData {
18
+ export abstract class ODResponderImplementation<Instance,Origin extends string,Params,WorkerIds extends string = string> extends ODManagerData {
19
19
  /**The manager that has all workers of this implementation */
20
20
  workers: ODWorkerManager<Instance,Origin,Params,WorkerIds>
21
21
  /**The `commandName` or `customId` needs to match this string or regex for this responder to be executed. */
@@ -28,9 +28,7 @@ export class ODResponderImplementation<Instance,Origin extends string,Params,Wor
28
28
  if (callback) this.workers.add(new ODWorker(callbackId ? callbackId : id,priority ?? 0,callback))
29
29
  }
30
30
  /**Execute all workers & return the result. */
31
- async respond(instance:Instance, origin:Origin, params:Params): Promise<void> {
32
- throw new ODSystemError("Tried to build an unimplemented ODResponderImplementation")
33
- }
31
+ abstract respond(instance:Instance, origin:Origin, params:Params): Promise<void>
34
32
  }
35
33
 
36
34
  /**## ODResponderTimeoutErrorCallback `type`
@@ -67,7 +67,7 @@ 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 100% unique id's for usage in the bot. An id can also store additional data which isn't saved to the filesystem.
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 {
@@ -90,20 +90,22 @@ export class ODStartScreenManager<IdList extends ODStartScreenManagerIdConstrain
90
90
  *
91
91
  * It's recommended to use pre-built components except if you really need a custom one.
92
92
  */
93
- export class ODStartScreenComponent extends ODManagerData {
93
+ export abstract class ODStartScreenComponent extends ODManagerData {
94
94
  /**The priority of this component. */
95
95
  priority: number
96
96
  /**An optional render function which will be inserted before the default renderer. */
97
- renderBefore: ODStartScreenComponentRenderCallback|null = null
97
+ renderBefore: ODStartScreenComponentRenderCallback|null
98
98
  /**The render function which will render the contents of this component. */
99
99
  render: ODStartScreenComponentRenderCallback
100
100
  /**An optional render function which will be inserted behind the default renderer. */
101
- renderAfter: ODStartScreenComponentRenderCallback|null = null
101
+ renderAfter: ODStartScreenComponentRenderCallback|null
102
102
 
103
- constructor(id:ODValidId, priority:number, render:ODStartScreenComponentRenderCallback){
103
+ constructor(id:ODValidId, priority:number, render:ODStartScreenComponentRenderCallback,renderBefore?:ODStartScreenComponentRenderCallback,renderAfter?:ODStartScreenComponentRenderCallback){
104
104
  super(id)
105
105
  this.priority = priority
106
106
  this.render = render
107
+ this.renderBefore = renderBefore ?? null
108
+ this.renderAfter = renderAfter ?? null
107
109
  }
108
110
 
109
111
  /**Render this component and combine it with the `renderBefore` & `renderAfter` contents. */