diff --git a/src/core/api/modules/language.ts b/src/core/api/modules/language.ts index 4cac88b..c9f683b 100644 --- a/src/core/api/modules/language.ts +++ b/src/core/api/modules/language.ts @@ -143,6 +143,14 @@ export class ODLanguageManager extends ODManager { } } +/**## ODLanguage `class` + * This is an open ticket language file. + * + * It contains metadata and all translation strings available in this language. + * Register this class to an `ODLanguageManager` to use it! + * + * JSON languages should be created using the `ODJsonLanguage` class instead! + */ export class ODLanguage extends ODManagerData { /**The name of the file with extension. */ file: string = "" @@ -164,6 +172,14 @@ export class ODLanguage extends ODManagerData { } } +/**## ODJsonLanguage `class` + * This is an open ticket JSON language file. + * + * It contains metadata and all translation strings from a certain JSON file (in `./languages/`). + * Register this class to an `ODLanguageManager` to use it! + * + * Use the `ODLanguage` class to use translations from non-JSON files! + */ export class ODJsonLanguage extends ODLanguage { constructor(id:ODValidId, file:string, customPath?:string){ super(id,{}) diff --git a/src/core/api/modules/permission.ts b/src/core/api/modules/permission.ts index 5602d29..ee2b03e 100644 --- a/src/core/api/modules/permission.ts +++ b/src/core/api/modules/permission.ts @@ -5,28 +5,65 @@ import { ODId, ODValidId, ODManager, ODSystemError, ODManagerData } from "./base import * as discord from "discord.js" import { ODDebugger } from "./console" +/**## ODPermissionType `type` + * All available permission types/levels. Can be used in the `ODPermission` class. + */ export type ODPermissionType = "member"|"support"|"moderator"|"admin"|"owner"|"developer" + +/**## ODPermissionScope `type` + * The scope in which a certain permission is active. + */ export type ODPermissionScope = "global-user"|"channel-user"|"global-role"|"channel-role" + +/**## ODPermissionResult `interface` + * The result returned by `ODPermissionManager.getPermissions()`. + */ export interface ODPermissionResult { + /**The permission type. */ type:ODPermissionType + /**The permission scope. */ scope:ODPermissionScope|"default" + /**The highest level available for this scope. */ level:ODPermissionLevel, + /**The permission which returned this level. */ source:ODPermission|null } +/**## ODPermissionLevel `enum` + * All available permission types/levels. But as `enum` instead of `type`. Used to calculate the level. + */ export enum ODPermissionLevel { + /**A normal member. (Default for everyone) */ member, + /**Support team. Higher than a normal member. (Used for ticket-admins) */ support, + /**Moderator. Higher than the support team. (Unused) */ moderator, + /**Admin. Higher than a moderator. (Used for global-admins) */ admin, + /**Server owner. (Able to use all commands including `/stats reset`) */ owner, + /**Bot owner or all users from dev team. (Able to use all commands including `/stats reset`) */ developer } +/**## ODPermission `class` + * This is an open ticket permission. + * + * It defines a single permission level for a specific scope (global/channel & user/role) + * These permissions only apply to commands & interactions. + * They are not related to channel permissions in the ticket system. + * + * Register this class to an `ODPermissionManager` to use it! + */ export class ODPermission extends ODManagerData { + /**The scope of this permission. */ readonly scope: ODPermissionScope + /**The type/level of this permission. */ readonly permission: ODPermissionType + /**The user/role of this permission. */ readonly value: discord.Role|discord.User + /**The channel that this permission applies to. (`null` when global) */ readonly channel: discord.Channel|null constructor(id:ODValidId, scope:"global-user", permission:ODPermissionType, value:discord.User) @@ -42,18 +79,39 @@ export class ODPermission extends ODManagerData { } } +/**## ODPermissionSettings `interface` + * Optional settings for the `getPermissions()` method in the `ODPermissionManager`. + */ export interface ODPermissionSettings { + /**Include permissions from the global user scope. */ allowGlobalUserScope?:boolean, + /**Include permissions from the global role scope. */ allowGlobalRoleScope?:boolean, + /**Include permissions from the channel user scope. */ allowChannelUserScope?:boolean, + /**Include permissions from the channel role scope. */ allowChannelRoleScope?:boolean, + /**Only include permissions of which the id matches this regex. */ idRegex?:RegExp } +/**## ODPermissionCalculationCallback `type` + * The callback of the permission calculation. (Used in `ODPermissionManager`) + */ export type ODPermissionCalculationCallback = (user:discord.User, channel?:discord.Channel|null, guild?:discord.Guild|null, settings?:ODPermissionSettings|null) => Promise +/**## ODPermissionManager `class` + * This is an open ticket permission manager. + * + * It manages all permissions in the bot! + * Use the `getPermissions()` and `hasPermissions()` methods to get user perms. + * + * Add new permissions using the `ODPermission` class in your plugin! + */ export class ODPermissionManager extends ODManager { + /**The function for calculating permissions in this manager. */ #calculation: ODPermissionCalculationCallback|null + /**The result which is returned when no other permissions match. (`member` by default) */ defaultResult: ODPermissionResult = { level:ODPermissionLevel["member"], scope:"default", @@ -66,12 +124,15 @@ export class ODPermissionManager extends ODManager { this.#calculation = useDefaultCalculation ? this.#defaultCalculation : null } + /**Edit the permission calculation function in this manager. */ setCalculation(calculation:ODPermissionCalculationCallback){ this.#calculation = calculation } + /**Edit the result which is returned when no other permissions match. (`member` by default) */ setDefaultResult(result:ODPermissionResult){ this.defaultResult = result } + /**Get an `ODPermissionResult` based on a few context factors. Use `hasPermissions()` to simplify the result. */ getPermissions(user:discord.User, channel?:discord.Channel|null, guild?:discord.Guild|null, settings?:ODPermissionSettings|null): Promise { try{ if (!this.#calculation) throw new ODSystemError("ODPermissionManager:getPermissions() => missing perms calculation") @@ -81,6 +142,7 @@ export class ODPermissionManager extends ODManager { throw new ODSystemError("ODPermissionManager:getPermissions() => failed perms calculation") } } + /**Simplifies the `ODPermissionResult` returned from `getPermissions()` and returns a boolean to check if the user matches the required permissions. */ hasPermissions(minimum:ODPermissionType, data:ODPermissionResult){ if (minimum == "member") return true else if (minimum == "support") return (data.level >= ODPermissionLevel["support"]) @@ -90,6 +152,7 @@ export class ODPermissionManager extends ODManager { else if (minimum == "developer") return (data.level >= ODPermissionLevel["developer"]) else throw new ODSystemError("Invalid minimum permission type at ODPermissionManager.hasPermissions()") } + /**Check for permissions. (default calculation) */ async #defaultCalculation(user:discord.User,channel?:discord.Channel|null,guild?:discord.Guild|null, settings?:ODPermissionSettings|null): Promise { const globalCalc = await this.#defaultGlobalCalculation(user,channel,guild,settings) const channelCalc = await this.#defaultChannelCalculation(user,channel,guild,settings) @@ -97,7 +160,7 @@ export class ODPermissionManager extends ODManager { if (globalCalc.level > channelCalc.level) return globalCalc else return channelCalc } - /**Check for global permissions. Then this result can be compared with the channel one. */ + /**Check for global permissions. Result will be compared with the channel perms in `#defaultCalculation()`. */ async #defaultGlobalCalculation(user:discord.User,channel?:discord.Channel|null,guild?:discord.Guild|null, settings?:ODPermissionSettings|null): Promise { const idRegex = (settings && typeof settings.idRegex != "undefined") ? settings.idRegex : null const allowGlobalUserScope = (settings && typeof settings.allowGlobalUserScope != "undefined") ? settings.allowGlobalUserScope : true @@ -160,7 +223,7 @@ export class ODPermissionManager extends ODManager { //spread result to prevent accidental referencing return {...this.defaultResult} } - /**Check for channel permissions. Then this result can be compared with the global one. */ + /**Check for channel permissions. Result will be compared with the global perms in `#defaultCalculation()`. */ async #defaultChannelCalculation(user:discord.User,channel?:discord.Channel|null,guild?:discord.Guild|null, settings?:ODPermissionSettings|null): Promise { const idRegex = (settings && typeof settings.idRegex != "undefined") ? settings.idRegex : null const allowChannelUserScope = (settings && typeof settings.allowChannelUserScope != "undefined") ? settings.allowChannelUserScope : true @@ -220,7 +283,7 @@ export class ODPermissionManager extends ODManager { } } - //spread result to prevent accidental referencing + //spread result to prevent accidental modification because of referencing return {...this.defaultResult} } } \ No newline at end of file