@open-discord-bots/framework 0.3.13 → 0.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/api/main.js +1 -1
  2. package/dist/api/modules/responder.js +50 -26
  3. package/dist/api/modules/verifybar.d.ts +1 -1
  4. package/dist/api/modules/verifybar.js +1 -1
  5. package/package.json +1 -1
  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
@@ -1,363 +0,0 @@
1
- ///////////////////////////////////////
2
- //PERMISSION MODULE
3
- ///////////////////////////////////////
4
- import { ODId, ODValidId, ODManager, ODSystemError, ODManagerData, ODNoGeneric } from "./base.js"
5
- import * as discord from "discord.js"
6
- import { ODDebugger } from "./console.js"
7
- import { ODClientManager } from "./client.js"
8
-
9
- /**## ODPermissionType `type`
10
- * All available permission types/levels. Can be used in the `ODPermission` class.
11
- */
12
- export type ODPermissionType = "member"|"support"|"moderator"|"admin"|"owner"|"developer"
13
-
14
- /**## ODPermissionScope `type`
15
- * The scope in which a certain permission is active.
16
- */
17
- export type ODPermissionScope = "global-user"|"channel-user"|"global-role"|"channel-role"
18
-
19
- /**## ODPermissionResult `interface`
20
- * The result returned by `ODPermissionManager.getPermissions()`.
21
- */
22
- export interface ODPermissionResult {
23
- /**The permission type. */
24
- type:ODPermissionType
25
- /**The permission scope. */
26
- scope:ODPermissionScope|"default"
27
- /**The highest level available for this scope. */
28
- level:ODPermissionLevel,
29
- /**The permission which returned this level. */
30
- source:ODPermission|null
31
- }
32
-
33
- /**## ODPermissionLevel `enum`
34
- * All available permission types/levels. But as `enum` instead of `type`. Used to calculate the level.
35
- */
36
- export enum ODPermissionLevel {
37
- /**A normal member. (Default for everyone) */
38
- member,
39
- /**Support team. Higher than a normal member. (Used for ticket-admins) */
40
- support,
41
- /**Moderator. Higher than the support team. (Unused) */
42
- moderator,
43
- /**Admin. Higher than a moderator. (Used for global-admins) */
44
- admin,
45
- /**Server owner. (Able to use all commands including `/stats reset`) */
46
- owner,
47
- /**Bot owner or all users from dev team. (Able to use all commands including `/stats reset`) */
48
- developer
49
- }
50
-
51
- /**## ODPermission `class`
52
- * This is an Open Discord permission.
53
- *
54
- * It defines a single permission level for a specific scope (global/channel & user/role)
55
- * These permissions only apply to commands & interactions.
56
- * They are not related to channel permissions in the ticket system.
57
- *
58
- * Register this class to an `ODPermissionManager` to use it!
59
- */
60
- export class ODPermission extends ODManagerData {
61
- /**The scope of this permission. */
62
- readonly scope: ODPermissionScope
63
- /**The type/level of this permission. */
64
- readonly permission: ODPermissionType
65
- /**The user/role of this permission. */
66
- readonly value: discord.Role|discord.User
67
- /**The channel that this permission applies to. (`null` when global) */
68
- readonly channel: discord.Channel|null
69
-
70
- constructor(id:ODValidId, scope:"global-user", permission:ODPermissionType, value:discord.User)
71
- constructor(id:ODValidId, scope:"global-role", permission:ODPermissionType, value:discord.Role)
72
- constructor(id:ODValidId, scope:"channel-user", permission:ODPermissionType, value:discord.User, channel:discord.Channel)
73
- constructor(id:ODValidId, scope:"channel-role", permission:ODPermissionType, value:discord.Role, channel:discord.Channel)
74
- constructor(id:ODValidId, scope:ODPermissionScope, permission:ODPermissionType, value:discord.Role|discord.User, channel?:discord.Channel){
75
- super(id)
76
- this.scope = scope
77
- this.permission = permission
78
- this.value = value
79
- this.channel = channel ?? null
80
- }
81
- }
82
-
83
- /**## ODPermissionSettings `interface`
84
- * Optional settings for the `getPermissions()` method in the `ODPermissionManager`.
85
- */
86
- export interface ODPermissionSettings {
87
- /**Include permissions from the global user scope. */
88
- allowGlobalUserScope?:boolean,
89
- /**Include permissions from the global role scope. */
90
- allowGlobalRoleScope?:boolean,
91
- /**Include permissions from the channel user scope. */
92
- allowChannelUserScope?:boolean,
93
- /**Include permissions from the channel role scope. */
94
- allowChannelRoleScope?:boolean,
95
- /**Only include permissions of which the id matches this regex. */
96
- idRegex?:RegExp
97
- }
98
-
99
- /**## ODPermissionCalculationCallback `type`
100
- * The callback of the permission calculation. (Used in `ODPermissionManager`)
101
- */
102
- export type ODPermissionCalculationCallback = (user:discord.User, channel?:discord.Channel|null, guild?:discord.Guild|null, settings?:ODPermissionSettings|null) => Promise<ODPermissionResult>
103
-
104
- /**## ODPermissionCommandResult `type`
105
- * The result of calculating permissions for a command.
106
- */
107
- export type ODPermissionCommandResult = {
108
- /**Returns `true` when the user has valid permissions. */
109
- hasPerms:false,
110
- reason:"no-perms"|"disabled"|"not-in-server"
111
- }|{
112
- /**Returns `true` when the user has valid permissions. */
113
- hasPerms:true,
114
- /**Is the user a server admin or a normal member? This does not decide if the user has permissions or not. */
115
- isAdmin:boolean
116
- }
117
-
118
- /**## ODPermissionManagerIdConstraint `type`
119
- * The constraint/layout for id mappings/interfaces of the `ODPermissionManager` class.
120
- */
121
- export type ODPermissionManagerIdConstraint = Record<string,ODPermission>
122
-
123
- /**## ODPermissionManager `class`
124
- * This is an Open Discord permission manager.
125
- *
126
- * It manages all permissions in the bot!
127
- * Use the `getPermissions()` and `hasPermissions()` methods to get user perms.
128
- *
129
- * Add new permissions using the `ODPermission` class in your plugin!
130
- */
131
- export class ODPermissionManager<IdList extends ODPermissionManagerIdConstraint = ODPermissionManagerIdConstraint> extends ODManager<ODPermission> {
132
- /**The function for calculating permissions in this manager. */
133
- private calculation: ODPermissionCalculationCallback|null
134
- /**An alias to the Open Discord client manager. */
135
- private client: ODClientManager
136
- /**The result which is returned when no other permissions match. (`member` by default) */
137
- defaultResult: ODPermissionResult = {
138
- level:ODPermissionLevel["member"],
139
- scope:"default",
140
- type:"member",
141
- source:null
142
- }
143
-
144
- constructor(debug:ODDebugger, client:ODClientManager, useDefaultCalculation?:boolean){
145
- super(debug,"permission")
146
- this.calculation = useDefaultCalculation ? this.defaultCalculation : null
147
- this.client = client
148
- }
149
-
150
- /**Edit the permission calculation function in this manager. */
151
- setCalculation(calculation:ODPermissionCalculationCallback){
152
- this.calculation = calculation
153
- }
154
- /**Edit the result which is returned when no other permissions match. (`member` by default) */
155
- setDefaultResult(result:ODPermissionResult){
156
- this.defaultResult = result
157
- }
158
- /**Get an `ODPermissionResult` based on a few context factors. Use `hasPermissions()` to simplify the result. */
159
- getPermissions(user:discord.User, channel?:discord.Channel|null, guild?:discord.Guild|null, settings?:ODPermissionSettings|null): Promise<ODPermissionResult> {
160
- try{
161
- if (!this.calculation) throw new ODSystemError("ODPermissionManager:getPermissions() => missing perms calculation")
162
- return this.calculation(user,channel,guild,settings)
163
- }catch(err){
164
- process.emit("uncaughtException",err)
165
- throw new ODSystemError("ODPermissionManager:getPermissions() => failed perms calculation")
166
- }
167
- }
168
- /**Simplifies the `ODPermissionResult` returned from `getPermissions()` and returns a boolean to check if the user matches the required permissions. */
169
- hasPermissions(minimum:ODPermissionType, data:ODPermissionResult){
170
- if (minimum == "member") return true
171
- else if (minimum == "support") return (data.level >= ODPermissionLevel["support"])
172
- else if (minimum == "moderator") return (data.level >= ODPermissionLevel["moderator"])
173
- else if (minimum == "admin") return (data.level >= ODPermissionLevel["admin"])
174
- else if (minimum == "owner") return (data.level >= ODPermissionLevel["owner"])
175
- else if (minimum == "developer") return (data.level >= ODPermissionLevel["developer"])
176
- else throw new ODSystemError("Invalid minimum permission type at ODPermissionManager.hasPermissions()")
177
- }
178
- /**Check for permissions. (default calculation) */
179
- private async defaultCalculation(user:discord.User,channel?:discord.Channel|null,guild?:discord.Guild|null, settings?:ODPermissionSettings|null): Promise<ODPermissionResult> {
180
- const globalCalc = await this.defaultGlobalCalculation(user,channel,guild,settings)
181
- const channelCalc = await this.defaultChannelCalculation(user,channel,guild,settings)
182
-
183
- if (globalCalc.level > channelCalc.level) return globalCalc
184
- else return channelCalc
185
- }
186
- /**Check for global permissions. Result will be compared with the channel perms in `#defaultCalculation()`. */
187
- private async defaultGlobalCalculation(user:discord.User,channel?:discord.Channel|null,guild?:discord.Guild|null, settings?:ODPermissionSettings|null): Promise<ODPermissionResult> {
188
- const idRegex = (settings && typeof settings.idRegex != "undefined") ? settings.idRegex : null
189
- const allowGlobalUserScope = (settings && typeof settings.allowGlobalUserScope != "undefined") ? settings.allowGlobalUserScope : true
190
- const allowGlobalRoleScope = (settings && typeof settings.allowGlobalRoleScope != "undefined") ? settings.allowGlobalRoleScope : true
191
-
192
- //check for global user permissions
193
- if (allowGlobalUserScope){
194
- const users = this.getFiltered((permission) => (!idRegex || (idRegex && idRegex.test(permission.id.value))) && permission.scope == "global-user" && (permission.value instanceof discord.User) && permission.value.id == user.id)
195
-
196
- if (users.length > 0){
197
- //sort all permisions from highest to lowest
198
- users.sort((a,b) => {
199
- const levelA = ODPermissionLevel[a.permission]
200
- const levelB = ODPermissionLevel[b.permission]
201
-
202
- if (levelB > levelA) return 1
203
- else if (levelA > levelB) return -1
204
- else return 0
205
- })
206
-
207
- return {
208
- type:users[0].permission,
209
- scope:"global-user",
210
- level:ODPermissionLevel[users[0].permission],
211
- source:users[0] ?? null
212
- }
213
- }
214
- }
215
-
216
- //check for global role permissions
217
- if (allowGlobalRoleScope){
218
- if (guild){
219
- const member = await this.client.fetchGuildMember(guild,user.id)
220
- if (member){
221
- const memberRoles = member.roles.cache.map((role) => role.id)
222
- const roles = this.getFiltered((permission) => (!idRegex || (idRegex && idRegex.test(permission.id.value))) && permission.scope == "global-role" && (permission.value instanceof discord.Role) && memberRoles.includes(permission.value.id) && permission.value.guild.id == guild.id)
223
-
224
- if (roles.length > 0){
225
- //sort all permisions from highest to lowest
226
- roles.sort((a,b) => {
227
- const levelA = ODPermissionLevel[a.permission]
228
- const levelB = ODPermissionLevel[b.permission]
229
-
230
- if (levelB > levelA) return 1
231
- else if (levelA > levelB) return -1
232
- else return 0
233
- })
234
-
235
- return {
236
- type:roles[0].permission,
237
- scope:"global-role",
238
- level:ODPermissionLevel[roles[0].permission],
239
- source:roles[0] ?? null
240
- }
241
- }
242
- }
243
- }
244
- }
245
-
246
- //spread result to prevent accidental referencing
247
- return {...this.defaultResult}
248
- }
249
- /**Check for channel permissions. Result will be compared with the global perms in `#defaultCalculation()`. */
250
- private async defaultChannelCalculation(user:discord.User,channel?:discord.Channel|null,guild?:discord.Guild|null, settings?:ODPermissionSettings|null): Promise<ODPermissionResult> {
251
- const idRegex = (settings && typeof settings.idRegex != "undefined") ? settings.idRegex : null
252
- const allowChannelUserScope = (settings && typeof settings.allowChannelUserScope != "undefined") ? settings.allowChannelUserScope : true
253
- const allowChannelRoleScope = (settings && typeof settings.allowChannelRoleScope != "undefined") ? settings.allowChannelRoleScope : true
254
-
255
- if (guild && channel && !channel.isDMBased()){
256
- //check for channel user permissions
257
- if (allowChannelUserScope){
258
- const users = this.getFiltered((permission) => (!idRegex || (idRegex && idRegex.test(permission.id.value))) && permission.scope == "channel-user" && permission.channel && (permission.channel.id == channel.id) && (permission.value instanceof discord.User) && permission.value.id == user.id)
259
-
260
- if (users.length > 0){
261
- //sort all permisions from highest to lowest
262
- users.sort((a,b) => {
263
- const levelA = ODPermissionLevel[a.permission]
264
- const levelB = ODPermissionLevel[b.permission]
265
-
266
- if (levelB > levelA) return 1
267
- else if (levelA > levelB) return -1
268
- else return 0
269
- })
270
-
271
- return {
272
- type:users[0].permission,
273
- scope:"channel-user",
274
- level:ODPermissionLevel[users[0].permission],
275
- source:users[0] ?? null
276
- }
277
- }
278
- }
279
-
280
- //check for channel role permissions
281
- if (allowChannelRoleScope){
282
- const member = await this.client.fetchGuildMember(guild,user.id)
283
- if (member){
284
- const memberRoles = member.roles.cache.map((role) => role.id)
285
- const roles = this.getFiltered((permission) => (!idRegex || (idRegex && idRegex.test(permission.id.value))) && permission.scope == "channel-role" && permission.channel && (permission.channel.id == channel.id) && (permission.value instanceof discord.Role) && memberRoles.includes(permission.value.id) && permission.value.guild.id == guild.id)
286
-
287
- if (roles.length > 0){
288
- //sort all permisions from highest to lowest
289
- roles.sort((a,b) => {
290
- const levelA = ODPermissionLevel[a.permission]
291
- const levelB = ODPermissionLevel[b.permission]
292
-
293
- if (levelB > levelA) return 1
294
- else if (levelA > levelB) return -1
295
- else return 0
296
- })
297
-
298
- return {
299
- type:roles[0].permission,
300
- scope:"channel-role",
301
- level:ODPermissionLevel[roles[0].permission],
302
- source:roles[0] ?? null
303
- }
304
- }
305
- }
306
- }
307
- }
308
-
309
- //spread result to prevent accidental modification because of referencing
310
- return {...this.defaultResult}
311
- }
312
-
313
- /**Check the permissions for a certain command of the bot. Permission mode: `none`, `everyone`, `admin` or any valid discord role ID. */
314
- async checkCommandPerms(permissionMode:string,requiredLevel:ODPermissionType,user:discord.User,member?:discord.GuildMember|null,channel?:discord.Channel|null,guild?:discord.Guild|null,settings?:ODPermissionSettings): Promise<ODPermissionCommandResult> {
315
- if (permissionMode === "none"){
316
- return {hasPerms:false,reason:"disabled"}
317
-
318
- }else if (permissionMode === "everyone"){
319
- const isAdmin = this.hasPermissions(requiredLevel,await this.getPermissions(user,channel,guild,settings))
320
- return {hasPerms:true,isAdmin}
321
-
322
- }else if (permissionMode === "admin"){
323
- const isAdmin = this.hasPermissions(requiredLevel,await this.getPermissions(user,channel,guild,settings))
324
- if (!isAdmin) return {hasPerms:false,reason:"no-perms"}
325
- else return {hasPerms:true,isAdmin}
326
- }else{
327
- if (!guild || !member){
328
- this.debug?.debug("ODPermissionManager.checkCommandPerms(): Permission Error, Not in server! (#1)")
329
- return {hasPerms:false,reason:"not-in-server"}
330
- }
331
- const role = await this.client.fetchGuildRole(guild,permissionMode)
332
- if (!role){
333
- this.debug?.debug("ODPermissionManager.checkCommandPerms(): Permission Error, Not in server! (#2)")
334
- return {hasPerms:false,reason:"not-in-server"}
335
- }
336
- if (!role.members.has(member.id)) return {hasPerms:false,reason:"no-perms"}
337
-
338
- const isAdmin = this.hasPermissions(requiredLevel,await this.getPermissions(user,channel,guild,settings))
339
- return {hasPerms:true,isAdmin}
340
- }
341
- }
342
-
343
- get<PermissionId extends keyof ODNoGeneric<IdList>>(id:PermissionId): IdList[PermissionId]
344
- get(id:ODValidId): ODPermission|null
345
-
346
- get(id:ODValidId): ODPermission|null {
347
- return super.get(id)
348
- }
349
-
350
- remove<PermissionId extends keyof ODNoGeneric<IdList>>(id:PermissionId): IdList[PermissionId]
351
- remove(id:ODValidId): ODPermission|null
352
-
353
- remove(id:ODValidId): ODPermission|null {
354
- return super.remove(id)
355
- }
356
-
357
- exists(id:keyof ODNoGeneric<IdList>): boolean
358
- exists(id:ODValidId): boolean
359
-
360
- exists(id:ODValidId): boolean {
361
- return super.exists(id)
362
- }
363
- }
@@ -1,294 +0,0 @@
1
- ///////////////////////////////////////
2
- //PLUGIN MODULE
3
- ///////////////////////////////////////
4
- import { ODId, ODManager, ODManagerData, ODNoGeneric, ODValidId, ODVersion } from "./base.js"
5
- import { ODDebugger } from "./console.js"
6
- import nodepath from "path"
7
-
8
- /**## ODUnknownCrashedPlugin `interface`
9
- * Basic details for a plugin that crashed while loading the `plugin.json` file.
10
- */
11
- export interface ODUnknownCrashedPlugin {
12
- /**The name of the plugin. (path when plugin crashed before `name` was loaded) */
13
- name:string,
14
- /**The description of the plugin. (when found before crashing) */
15
- description:string
16
- }
17
-
18
- /**## ODPluginManagerIdConstraint `type`
19
- * The constraint/layout for id mappings/interfaces of the `ODPluginManager` class.
20
- */
21
- export type ODPluginManagerIdConstraint = Record<string,ODPlugin>
22
-
23
- /**## ODPluginManager `class`
24
- * This is an Open Discord plugin manager.
25
- *
26
- * It manages all active plugins in the bot!
27
- * It also contains all "plugin classes" which are managers registered by plugins.
28
- * These are accessible via the `opendiscord.plugins.classes` global.
29
- *
30
- * Use `isPluginLoaded()` to check if a plugin has been loaded.
31
- */
32
- export class ODPluginManager<IdList extends ODPluginManagerIdConstraint = ODPluginManagerIdConstraint,PluginClassIdList extends ODPluginClassManagerIdConstraint = ODPluginClassManagerIdConstraint> extends ODManager<ODPlugin> {
33
- /**A manager for all custom managers registered by plugins. */
34
- classes: ODPluginClassManager<PluginClassIdList>
35
- /**A list of basic details from all plugins that crashed while loading the `plugin.json` file. */
36
- unknownCrashedPlugins: ODUnknownCrashedPlugin[] = []
37
-
38
- constructor(debug:ODDebugger){
39
- super(debug,"plugin")
40
- this.classes = new ODPluginClassManager(debug)
41
- }
42
-
43
- /**Check if a plugin has been loaded successfully and is available for usage.*/
44
- isPluginLoaded(id:ODValidId): boolean {
45
- const newId = new ODId(id)
46
- const plugin = this.get(newId)
47
- return (plugin !== null && plugin.executed)
48
- }
49
-
50
- get<PluginId extends keyof ODNoGeneric<IdList>>(id:PluginId): IdList[PluginId]
51
- get(id:ODValidId): ODPlugin|null
52
-
53
- get(id:ODValidId): ODPlugin|null {
54
- return super.get(id)
55
- }
56
-
57
- remove<PluginId extends keyof ODNoGeneric<IdList>>(id:PluginId): IdList[PluginId]
58
- remove(id:ODValidId): ODPlugin|null
59
-
60
- remove(id:ODValidId): ODPlugin|null {
61
- return super.remove(id)
62
- }
63
-
64
- exists(id:keyof ODNoGeneric<IdList>): boolean
65
- exists(id:ODValidId): boolean
66
-
67
- exists(id:ODValidId): boolean {
68
- return super.exists(id)
69
- }
70
- }
71
-
72
- /**## ODPluginData `interface`
73
- * Parsed data from the `plugin.json` file in a plugin.
74
- */
75
- export interface ODPluginData {
76
- /**The name of this plugin (shown on startup) */
77
- name:string,
78
- /**The id of this plugin. (Must be identical to directory name) */
79
- id:string,
80
- /**The version of this plugin. */
81
- version:string,
82
- /**The location of the start file of the plugin relative to the rootDir of the plugin */
83
- startFile:string,
84
- /**A list of compatible versions. (e.g. `["OTv4.0.x", "OMv1.x.x"]`) (optional, will be required in future version)
85
- * - `OT` --> Open Ticket support
86
- * - `OM` --> Open Moderation support
87
- */
88
- supportedVersions?:string[],
89
-
90
- /**Is this plugin enabled? */
91
- enabled:boolean,
92
- /**The priority of this plugin. Higher priority will load before lower priority. */
93
- priority:number,
94
- /**A list of events to register to the `opendiscord.events` global before loading any plugins. This way, plugins with a higher priority are able to use events from this plugin as well! */
95
- events:string[]
96
-
97
- /**Npm dependencies which are required for this plugin to work. */
98
- npmDependencies:string[],
99
- /**Plugins which are required for this plugin to work. */
100
- requiredPlugins:string[],
101
- /**Plugins which are incompatible with this plugin. */
102
- incompatiblePlugins:string[],
103
-
104
- /**Additional details about this plugin. */
105
- details:ODPluginDetails
106
- }
107
-
108
- /**## ODPluginDetails `interface`
109
- * Additional details in the `plugin.json` file from a plugin.
110
- */
111
- export interface ODPluginDetails {
112
- /**The main author of the plugin. Additional contributors can be specified in `contributors`. */
113
- author:string,
114
- /**A list of plugin contributors. (optional, will be required in future version) */
115
- contributors?:string[],
116
- /**A short description of this plugin. */
117
- shortDescription:string,
118
- /**A large description of this plugin. */
119
- longDescription:string,
120
- /**A URL to a cover image of this plugin. (currently unused) */
121
- imageUrl:string,
122
- /**A URL to the website/project page of this plugin. (currently unused) */
123
- projectUrl:string,
124
- /**A list of tags/categories that this plugin affects. */
125
- tags:string[]
126
- }
127
-
128
- /**## ODPlugin `class`
129
- * This is an Open Discord plugin.
130
- *
131
- * It represents a single plugin in the `./plugins/` directory.
132
- * All plugins are accessible via the `opendiscord.plugins` global.
133
- *
134
- * Don't re-execute plugins which are already enabled! It might break the bot or plugin.
135
- */
136
- export class ODPlugin extends ODManagerData {
137
- /**The name of the directory of this plugin. (same as id) */
138
- dir: string
139
- /**All plugin data found in the `plugin.json` file. */
140
- data: ODPluginData
141
- /**The name of this plugin. */
142
- name: string
143
- /**The priority of this plugin. */
144
- priority: number
145
- /**The version of this plugin. */
146
- version: ODVersion
147
- /**The additional details of this plugin. */
148
- details: ODPluginDetails
149
-
150
- /**Is this plugin enabled? */
151
- enabled: boolean
152
- /**Did this plugin execute successfully?. */
153
- executed: boolean
154
- /**Did this plugin crash? (A reason is available in the `crashReason`) */
155
- crashed: boolean
156
- /**The reason which caused this plugin to crash. */
157
- crashReason: null|"incompatible.plugin"|"missing.plugin"|"missing.dependency"|"incompatible.version"|"executed" = null
158
-
159
- constructor(dir:string, jsondata:ODPluginData){
160
- super(jsondata.id)
161
- this.dir = dir
162
- this.data = jsondata
163
- this.name = jsondata.name
164
- this.priority = jsondata.priority
165
- this.version = ODVersion.fromString("plugin",jsondata.version)
166
- this.details = jsondata.details
167
-
168
- this.enabled = jsondata.enabled
169
- this.executed = false
170
- this.crashed = false
171
- }
172
-
173
- /**Get the startfile location relative to the `./plugins/` directory. (`./dist/plugins/`) when compiled) */
174
- getStartFile(){
175
- const newFile = this.data.startFile.replace(/\.ts$/,".js")
176
- return nodepath.join(this.dir,newFile)
177
- }
178
- /**Execute this plugin. Returns `false` on crash. */
179
- async execute(debug:ODDebugger,force?:boolean): Promise<boolean> {
180
- if ((this.enabled && !this.crashed) || force){
181
- try{
182
- //import relative plugin directory path (works on windows & unix based systems)
183
- const pluginPath = nodepath.join(process.cwd(),"./dist/plugins/",this.getStartFile()).replaceAll("\\","/")
184
- await import(pluginPath)
185
- debug.console.log("Plugin \""+this.id.value+"\" loaded successfully!","plugin")
186
- this.executed = true
187
- return true
188
- }catch(error:any){
189
- this.crashed = true
190
- this.crashReason = "executed"
191
-
192
- debug.console.log(error.message+", canceling plugin execution...","plugin",[
193
- {key:"path",value:"./plugins/"+this.dir}
194
- ])
195
- debug.console.log("You can see more about this error in the ./debug.txt file!","info")
196
- debug.console.debugfile.writeText(error.stack)
197
-
198
- return false
199
- }
200
- }else return true
201
- }
202
-
203
- /**Check if a npm dependency exists. */
204
- checkDependency(id:string){
205
- try{
206
- import.meta.resolve(id)
207
- return true
208
- }catch{
209
- return false
210
- }
211
- }
212
-
213
- /**Get a list of all missing npm dependencies that are required for this plugin. */
214
- dependenciesInstalled(){
215
- const missing: string[] = []
216
- this.data.npmDependencies.forEach((d) => {
217
- if (!this.checkDependency(d)){
218
- missing.push(d)
219
- }
220
- })
221
-
222
- return missing
223
- }
224
- /**Get a list of all missing plugins that are required for this plugin. */
225
- pluginsInstalled(manager:ODPluginManager){
226
- const missing: string[] = []
227
- this.data.requiredPlugins.forEach((p) => {
228
- const plugin = manager.get(p)
229
- if (!plugin || !plugin.enabled){
230
- missing.push(p)
231
- }
232
- })
233
-
234
- return missing
235
- }
236
- /**Get a list of all enabled incompatible plugins that interfere with this plugin. */
237
- pluginsIncompatible(manager:ODPluginManager){
238
- const incompatible: string[] = []
239
- this.data.incompatiblePlugins.forEach((p) => {
240
- const plugin = manager.get(p)
241
- if (plugin && plugin.enabled){
242
- incompatible.push(p)
243
- }
244
- })
245
-
246
- return incompatible
247
- }
248
- /**Get a list of all authors & contributors of this plugin. */
249
- getAuthors(): string[] {
250
- return [this.details.author,...(this.details.contributors ?? [])]
251
- }
252
- }
253
-
254
- /**## ODPluginClassManagerIdConstraint `type`
255
- * The constraint/layout for id mappings/interfaces of the `ODPluginClassManager` class.
256
- */
257
- export type ODPluginClassManagerIdConstraint = Record<string,ODManagerData>
258
-
259
- /**## ODPluginClassManager `class`
260
- * This is an Open Discord plugin class manager.
261
- *
262
- * It manages all managers registered by plugins!
263
- * Plugins are able to register their own managers, handlers, functions, classes, ... here.
264
- * By doing this, other plugins are also able to make use of it.
265
- * This can be useful for plugins that want to extend other plugins.
266
- *
267
- * Use `isPluginLoaded()` to check if a plugin has been loaded before trying to access the manager.
268
- */
269
- export class ODPluginClassManager<IdList extends ODPluginClassManagerIdConstraint = ODPluginClassManagerIdConstraint> extends ODManager<ODManagerData> {
270
- constructor(debug:ODDebugger){
271
- super(debug,"plugin class")
272
- }
273
-
274
- get<PluginClassId extends keyof ODNoGeneric<IdList>>(id:PluginClassId): IdList[PluginClassId]
275
- get(id:ODValidId): ODManagerData|null
276
-
277
- get(id:ODValidId): ODManagerData|null {
278
- return super.get(id)
279
- }
280
-
281
- remove<PluginClassId extends keyof ODNoGeneric<IdList>>(id:PluginClassId): IdList[PluginClassId]
282
- remove(id:ODValidId): ODManagerData|null
283
-
284
- remove(id:ODValidId): ODManagerData|null {
285
- return super.remove(id)
286
- }
287
-
288
- exists(id:keyof ODNoGeneric<IdList>): boolean
289
- exists(id:ODValidId): boolean
290
-
291
- exists(id:ODValidId): boolean {
292
- return super.exists(id)
293
- }
294
- }