Solved merge conflicts

This commit is contained in:
JasperAtSchool
2026-05-20 10:42:17 +02:00
247 changed files with 10788 additions and 25817 deletions
+43
View File
@@ -0,0 +1,43 @@
//EXPORT FRAMEWORK
export * from "@open-discord-bots/framework/api"
//EXPORT OPEN TICKET MAPPINGS
export * from "./mappings/action.js"
export * from "./mappings/base.js"
export * from "./mappings/builder.js"
export * from "./mappings/checker.js"
export * from "./mappings/client.js"
export * from "./mappings/code.js"
export * from "./mappings/component.js"
export * from "./mappings/config.js"
export * from "./mappings/console.js"
export * from "./mappings/cooldown.js"
export * from "./mappings/database.js"
export * from "./mappings/event.js"
export * from "./mappings/flag.js"
export * from "./mappings/fuse.js"
export * from "./mappings/helpmenu.js"
export * from "./mappings/language.js"
export * from "./mappings/permission.js"
export * from "./mappings/plugin.js"
export * from "./mappings/post.js"
export * from "./mappings/progressbar.js"
export * from "./mappings/responder.js"
export * from "./mappings/session.js"
export * from "./mappings/startscreen.js"
export * from "./mappings/state.js"
export * from "./mappings/statistic.js"
export * from "./mappings/verifybar.js"
//EXPORT OPENTICKET MODULES
export * from "./api/blacklist.js"
export * from "./api/option.js"
export * from "./api/panel.js"
export * from "./api/priority.js"
export * from "./api/question.js"
export * from "./api/role.js"
export * from "./api/ticket.js"
export * from "./api/transcript.js"
//EXPORT MAIN MODULE
export { ODOpenTicketMain } from "./main.js"
-64
View File
@@ -1,64 +0,0 @@
//MAIN MODULE
export * from "./main"
//BASE MODULES
export * from "./modules/base"
export * from "./modules/event"
export * from "./modules/config"
export * from "./modules/database"
export * from "./modules/language"
export * from "./modules/flag"
export * from "./modules/console"
export * from "./modules/defaults"
export * from "./modules/plugin"
export * from "./modules/checker"
export * from "./modules/client"
export * from "./modules/worker"
export * from "./modules/builder"
export * from "./modules/responder"
export * from "./modules/action"
export * from "./modules/permission"
export * from "./modules/helpmenu"
export * from "./modules/session"
export * from "./modules/stat"
export * from "./modules/code"
export * from "./modules/cooldown"
export * from "./modules/post"
export * from "./modules/verifybar"
export * from "./modules/progressbar"
export * from "./modules/startscreen"
//OPENTICKET DEFAULT MODULES
export * from "./defaults/base"
export * from "./defaults/event"
export * from "./defaults/config"
export * from "./defaults/database"
export * from "./defaults/plugin"
export * from "./defaults/checker"
export * from "./defaults/client"
export * from "./defaults/language"
export * from "./defaults/builder"
export * from "./defaults/responder"
export * from "./defaults/action"
export * from "./defaults/flag"
export * from "./defaults/permission"
export * from "./defaults/helpmenu"
export * from "./defaults/session"
export * from "./defaults/stat"
export * from "./defaults/worker"
export * from "./defaults/code"
export * from "./defaults/cooldown"
export * from "./defaults/post"
export * from "./defaults/progressbar"
export * from "./defaults/startscreen"
export * from "./defaults/console"
//OPENTICKET MODULES
export * from "./openticket/question"
export * from "./openticket/option"
export * from "./openticket/panel"
export * from "./openticket/ticket"
export * from "./openticket/blacklist"
export * from "./openticket/transcript"
export * from "./openticket/role"
export * from "./openticket/priority"
@@ -1,8 +1,7 @@
///////////////////////////////////////
//OPENTICKET BLACKLIST MODULE
///////////////////////////////////////
import { ODManager, ODManagerData, ODValidId } from "../modules/base"
import { ODDebugger } from "../modules/console"
import * as api from "@open-discord-bots/framework/api"
/**## ODBlacklist `class`
* This is an Open Ticket blacklisted user.
@@ -11,22 +10,22 @@ import { ODDebugger } from "../modules/console"
*
* Create this class & add it to the `ODBlacklistManager` to blacklist someone!
*/
export class ODBlacklist extends ODManagerData {
export class ODBlacklist extends api.ODManagerData {
/**The reason why this user got blacklisted. (optional) */
#reason: string|null
private rawReason: string|null
constructor(id:ODValidId,reason:string|null){
constructor(id:api.ODValidId,reason:string|null){
super(id)
this.#reason = reason
this.rawReason = reason
}
/**The reason why this user got blacklisted. (optional) */
set reason(reason:string|null) {
this.#reason = reason
this.rawReason = reason
this._change()
}
get reason(){
return this.#reason
return this.rawReason
}
}
@@ -37,8 +36,8 @@ export class ODBlacklist extends ODManagerData {
*
* All `ODBlacklist`'s added, removed & edited in this list will be synced automatically with the database.
*/
export class ODBlacklistManager extends ODManager<ODBlacklist> {
constructor(debug:ODDebugger){
export class ODBlacklistManager extends api.ODManager<ODBlacklist> {
constructor(debug:api.ODDebugger){
super(debug,"blacklist")
}
}
-45
View File
@@ -1,45 +0,0 @@
///////////////////////////////////////
//BASE MODULE
///////////////////////////////////////
import { ODVersion, ODVersionManager, ODValidId } from "../modules/base"
/**## ODVersionManagerIds_Default `interface`
* This interface is a list of ids available in the `ODVersionManager` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODVersionManagerIds_Default {
"opendiscord:version":ODVersion,
"opendiscord:last-version":ODVersion,
"opendiscord:api":ODVersion,
"opendiscord:transcripts":ODVersion,
"opendiscord:livestatus":ODVersion
}
/**## ODFlagManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODFlagManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.flags`!
*/
export class ODVersionManager_Default extends ODVersionManager {
get<VersionId extends keyof ODVersionManagerIds_Default>(id:VersionId): ODVersionManagerIds_Default[VersionId]
get(id:ODValidId): ODVersion|null
get(id:ODValidId): ODVersion|null {
return super.get(id)
}
remove<VersionId extends keyof ODVersionManagerIds_Default>(id:VersionId): ODVersionManagerIds_Default[VersionId]
remove(id:ODValidId): ODVersion|null
remove(id:ODValidId): ODVersion|null {
return super.remove(id)
}
exists(id:keyof ODVersionManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-549
View File
@@ -1,549 +0,0 @@
///////////////////////////////////////
//DEFAULT BUILDER MODULE
///////////////////////////////////////
import { ODValidButtonColor, ODValidId } from "../modules/base"
import { ODBuilderManager, ODButton, ODButtonInstance, ODButtonManager, ODDropdown, ODDropdownInstance, ODDropdownManager, ODEmbed, ODEmbedInstance, ODEmbedManager, ODFile, ODFileInstance, ODFileManager, ODMessage, ODMessageInstance, ODMessageManager, ODModal, ODModalInstance, ODModalManager } from "../modules/builder"
import { ODWorkerManager_Default } from "./worker"
import { ODTicket, ODTicketClearFilter } from "../openticket/ticket"
import { ODPermissionEmbedType } from "../defaults/permission"
import { ODTextCommandErrorInvalidOption, ODTextCommandErrorMissingOption, ODTextCommandErrorUnknownCommand } from "../modules/client"
import { ODPanel } from "../openticket/panel"
import { ODRoleOption, ODTicketOption, ODWebsiteOption } from "../openticket/option"
import { ODVerifyBar } from "../modules/verifybar"
import * as discord from "discord.js"
import { ODTranscriptCompiler, ODTranscriptCompilerCompileResult } from "../openticket/transcript"
import { ODRole, ODRoleUpdateResult } from "../openticket/role"
import { ODPriorityLevel } from "../openticket/priority"
/**## ODBuilderManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODBuilderManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.builders`!
*/
export class ODBuilderManager_Default extends ODBuilderManager {
declare buttons: ODButtonManager_Default
declare dropdowns: ODDropdownManager_Default
declare files: ODFileManager_Default
declare embeds: ODEmbedManager_Default
declare messages: ODMessageManager_Default
declare modals: ODModalManager_Default
}
/**## ODButtonManagerIds_Default `interface`
* This interface is a list of ids available in the `ODButtonManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODButtonManagerIds_Default {
"opendiscord:verifybar-success":{source:"verifybar"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,customData?:string,customColor?:ODValidButtonColor,customLabel?:string,customEmoji?:string},workers:"opendiscord:verifybar-success"},
"opendiscord:verifybar-failure":{source:"verifybar"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,customData?:string,customColor?:ODValidButtonColor,customLabel?:string,customEmoji?:string},workers:"opendiscord:verifybar-failure"},
"opendiscord:error-ticket-deprecated-transcript":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{},workers:"opendiscord:error-ticket-deprecated-transcript"},
"opendiscord:help-menu-previous":{source:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu-previous"},
"opendiscord:help-menu-next":{source:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu-next"},
"opendiscord:help-menu-page":{source:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu-page"}
"opendiscord:help-menu-switch":{source:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu-switch"},
"opendiscord:ticket-option":{source:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODTicketOption},workers:"opendiscord:ticket-option"},
"opendiscord:website-option":{source:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODWebsiteOption},workers:"opendiscord:website-option"},
"opendiscord:role-option":{source:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODRoleOption},workers:"opendiscord:role-option"}
"opendiscord:visit-ticket":{source:"ticket-created"|"dm"|"logs"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:visit-ticket"},
"opendiscord:close-ticket":{source:"ticket-message"|"reopen-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:close-ticket"},
"opendiscord:delete-ticket":{source:"ticket-message"|"close-message"|"autoclose-message"|"reopen-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:delete-ticket"},
"opendiscord:reopen-ticket":{source:"ticket-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:reopen-ticket"},
"opendiscord:claim-ticket":{source:"ticket-message"|"unclaim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:claim-ticket"},
"opendiscord:unclaim-ticket":{source:"ticket-message"|"claim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:unclaim-ticket"},
"opendiscord:pin-ticket":{source:"ticket-message"|"unpin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:pin-ticket"},
"opendiscord:unpin-ticket":{source:"ticket-message"|"pin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:unpin-ticket"},
"opendiscord:transcript-html-visit":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,result:ODTranscriptCompilerCompileResult<{url:string,availableUntil:Date}>},workers:"opendiscord:transcript-html-visit"},
"opendiscord:transcript-error-retry":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,reason:string|null},workers:"opendiscord:transcript-error-retry"},
"opendiscord:transcript-error-continue":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,reason:string|null},workers:"opendiscord:transcript-error-continue"},
"opendiscord:clear-continue":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-continue"},
}
/**## ODButtonManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODButtonManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.builders.buttons`!
*/
export class ODButtonManager_Default extends ODButtonManager {
get<ButtonId extends keyof ODButtonManagerIds_Default>(id:ButtonId): ODButton_Default<ODButtonManagerIds_Default[ButtonId]["source"],ODButtonManagerIds_Default[ButtonId]["params"],ODButtonManagerIds_Default[ButtonId]["workers"]>
get(id:ODValidId): ODButton<string,any>|null
get(id:ODValidId): ODButton<string,any>|null {
return super.get(id)
}
remove<ButtonId extends keyof ODButtonManagerIds_Default>(id:ButtonId): ODButton_Default<ODButtonManagerIds_Default[ButtonId]["source"],ODButtonManagerIds_Default[ButtonId]["params"],ODButtonManagerIds_Default[ButtonId]["workers"]>
remove(id:ODValidId): ODButton<string,any>|null
remove(id:ODValidId): ODButton<string,any>|null {
return super.remove(id)
}
exists(id:keyof ODButtonManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getSafe<ButtonId extends keyof ODButtonManagerIds_Default>(id:ButtonId): ODButton_Default<ODButtonManagerIds_Default[ButtonId]["source"],ODButtonManagerIds_Default[ButtonId]["params"],ODButtonManagerIds_Default[ButtonId]["workers"]>
getSafe(id:ODValidId): ODButton<string,any>
getSafe(id:ODValidId): ODButton<string,any> {
return super.getSafe(id)
}
}
/**## ODButton_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODButton class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODButton`'s!
*/
export class ODButton_Default<Source extends string, Params, WorkerIds extends string> extends ODButton<Source,Params> {
declare workers: ODWorkerManager_Default<ODButtonInstance,Source,Params,WorkerIds>
}
/**## ODDropdownManagerIds_Default `interface`
* This interface is a list of ids available in the `ODDropdownManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODDropdownManagerIds_Default {
"opendiscord:panel-dropdown-tickets":{source:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,options:ODTicketOption[]},workers:"opendiscord:panel-dropdown-tickets"}
}
/**## ODDropdownManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODDropdownManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.builders.dropdowns`!
*/
export class ODDropdownManager_Default extends ODDropdownManager {
get<DropdownId extends keyof ODDropdownManagerIds_Default>(id:DropdownId): ODDropdown_Default<ODDropdownManagerIds_Default[DropdownId]["source"],ODDropdownManagerIds_Default[DropdownId]["params"],ODDropdownManagerIds_Default[DropdownId]["workers"]>
get(id:ODValidId): ODDropdown<string,any>|null
get(id:ODValidId): ODDropdown<string,any>|null {
return super.get(id)
}
remove<DropdownId extends keyof ODDropdownManagerIds_Default>(id:DropdownId): ODDropdown_Default<ODDropdownManagerIds_Default[DropdownId]["source"],ODDropdownManagerIds_Default[DropdownId]["params"],ODDropdownManagerIds_Default[DropdownId]["workers"]>
remove(id:ODValidId): ODDropdown<string,any>|null
remove(id:ODValidId): ODDropdown<string,any>|null {
return super.remove(id)
}
exists(id:keyof ODDropdownManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getSafe<DropdownId extends keyof ODDropdownManagerIds_Default>(id:DropdownId): ODDropdown_Default<ODDropdownManagerIds_Default[DropdownId]["source"],ODDropdownManagerIds_Default[DropdownId]["params"],ODDropdownManagerIds_Default[DropdownId]["workers"]>
getSafe(id:ODValidId): ODDropdown<string,any>
getSafe(id:ODValidId): ODDropdown<string,any> {
return super.getSafe(id)
}
}
/**## ODDropdown_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODDropdown class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODDropdown`'s!
*/
export class ODDropdown_Default<Source extends string, Params, WorkerIds extends string> extends ODDropdown<Source,Params> {
declare workers: ODWorkerManager_Default<ODDropdownInstance,Source,Params,WorkerIds>
}
/**## ODFileManagerIds_Default `interface`
* This interface is a list of ids available in the `ODFileManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODFileManagerIds_Default {
"opendiscord:text-transcript":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,result:ODTranscriptCompilerCompileResult<any>},workers:"opendiscord:text-transcript"}
}
/**## ODFileManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODFileManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.builders.files`!
*/
export class ODFileManager_Default extends ODFileManager {
get<FileId extends keyof ODFileManagerIds_Default>(id:FileId): ODFile_Default<ODFileManagerIds_Default[FileId]["source"],ODFileManagerIds_Default[FileId]["params"],ODFileManagerIds_Default[FileId]["workers"]>
get(id:ODValidId): ODFile<string,any>|null
get(id:ODValidId): ODFile<string,any>|null {
return super.get(id)
}
remove<FileId extends keyof ODFileManagerIds_Default>(id:FileId): ODFile_Default<ODFileManagerIds_Default[FileId]["source"],ODFileManagerIds_Default[FileId]["params"],ODFileManagerIds_Default[FileId]["workers"]>
remove(id:ODValidId): ODFile<string,any>|null
remove(id:ODValidId): ODFile<string,any>|null {
return super.remove(id)
}
exists(id:keyof ODFileManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getSafe<FileId extends keyof ODFileManagerIds_Default>(id:FileId): ODFile_Default<ODFileManagerIds_Default[FileId]["source"],ODFileManagerIds_Default[FileId]["params"],ODFileManagerIds_Default[FileId]["workers"]>
getSafe(id:ODValidId): ODFile<string,any>
getSafe(id:ODValidId): ODFile<string,any> {
return super.getSafe(id)
}
}
/**## ODFile_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODFile class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODFile`'s!
*/
export class ODFile_Default<Source extends string, Params, WorkerIds extends string> extends ODFile<Source,Params> {
declare workers: ODWorkerManager_Default<ODFileInstance,Source,Params,WorkerIds>
}
/**## ODEmbedManagerIds_Default `interface`
* This interface is a list of ids available in the `ODEmbedManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODEmbedManagerIds_Default {
"opendiscord:error":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:string,layout:"simple"|"advanced",customTitle?:string},workers:"opendiscord:error"},
"opendiscord:error-option-missing":{source:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:ODTextCommandErrorMissingOption},workers:"opendiscord:error-option-missing"},
"opendiscord:error-option-invalid":{source:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:ODTextCommandErrorInvalidOption},workers:"opendiscord:error-option-invalid"},
"opendiscord:error-unknown-command":{source:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:ODTextCommandErrorUnknownCommand},workers:"opendiscord:error-unknown-command"},
"opendiscord:error-no-permissions":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,permissions:ODPermissionEmbedType[]},workers:"opendiscord:error-no-permissions"},
"opendiscord:error-no-permissions-cooldown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,until?:Date},workers:"opendiscord:error-no-permissions-cooldown"},
"opendiscord:error-no-permissions-blacklisted":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-no-permissions-blacklisted"},
"opendiscord:error-no-permissions-limits":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,limit:"global"|"global-user"|"option"|"option-user"},workers:"opendiscord:error-no-permissions-limits"},
"opendiscord:error-responder-timeout":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-responder-timeout"},
"opendiscord:error-ticket-unknown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-ticket-unknown"},
"opendiscord:error-ticket-deprecated":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-ticket-deprecated"},
"opendiscord:error-option-unknown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-option-unknown"},
"opendiscord:error-panel-unknown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-panel-unknown"},
"opendiscord:error-not-in-guild":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-not-in-guild"},
"opendiscord:error-channel-rename":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"ticket-pin"|"ticket-unpin"|"ticket-rename"|"ticket-move"|"ticket-priority"|"ticket-transfer"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,originalName:string,newName:string},workers:"opendiscord:error-channel-rename"},
"opendiscord:error-ticket-busy":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-ticket-busy"},
"opendiscord:help-menu":{source:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu"},
"opendiscord:stats-global":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:stats-global"},
"opendiscord:stats-ticket":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,scopeData:ODTicket},workers:"opendiscord:stats-ticket"},
"opendiscord:stats-user":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,scopeData:discord.User},workers:"opendiscord:stats-user"|"opendiscord:easter-egg"},
"opendiscord:stats-reset":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,reason:string|null},workers:"opendiscord:stats-reset"},
"opendiscord:stats-ticket-unknown":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,id:string},workers:"opendiscord:stats-ticket-unknown"},
"opendiscord:panel":{source:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel},workers:"opendiscord:panel"},
"opendiscord:ticket-created":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created"},
"opendiscord:ticket-created-dm":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created-dm"},
"opendiscord:ticket-created-logs":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created-logs"},
"opendiscord:ticket-message":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-message"},
"opendiscord:close-message":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"autoclose"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:close-message"},
"opendiscord:reopen-message":{source:"slash"|"text"|"ticket-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:reopen-message"},
"opendiscord:delete-message":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:delete-message"},
"opendiscord:claim-message":{source:"slash"|"text"|"ticket-message"|"unclaim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:claim-message"},
"opendiscord:unclaim-message":{source:"slash"|"text"|"ticket-message"|"claim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:unclaim-message"},
"opendiscord:pin-message":{source:"slash"|"text"|"ticket-message"|"unpin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:pin-message"},
"opendiscord:unpin-message":{source:"slash"|"text"|"ticket-message"|"pin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:unpin-message"},
"opendiscord:rename-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:string},workers:"opendiscord:rename-message"},
"opendiscord:move-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:ODTicketOption},workers:"opendiscord:move-message"},
"opendiscord:add-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:discord.User},workers:"opendiscord:add-message"},
"opendiscord:remove-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:discord.User},workers:"opendiscord:remove-message"},
"opendiscord:ticket-action-dm":{source:"slash"|"text"|"ticket-message"|"close-message"|"reopen-message"|"delete-message"|"claim-message"|"unclaim-message"|"pin-message"|"unpin-message"|"autoclose-message"|"autoclose"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"close"|"reopen"|"delete"|"claim"|"unclaim"|"pin"|"unpin"|"rename"|"move"|"add"|"remove",ticket:ODTicket,reason:string|null,additionalData:null|string|discord.User|ODTicketOption},workers:"opendiscord:ticket-action-dm"},
"opendiscord:ticket-action-logs":{source:"slash"|"text"|"ticket-message"|"close-message"|"reopen-message"|"delete-message"|"claim-message"|"unclaim-message"|"pin-message"|"unpin-message"|"autoclose-message"|"autoclose"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"close"|"reopen"|"delete"|"claim"|"unclaim"|"pin"|"unpin"|"rename"|"move"|"add"|"remove",ticket:ODTicket,reason:string|null,additionalData:null|string|discord.User|ODTicketOption},workers:"opendiscord:ticket-action-logs"},
"opendiscord:blacklist-view":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:blacklist-view"},
"opendiscord:blacklist-get":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User},workers:"opendiscord:blacklist-get"},
"opendiscord:blacklist-add":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User,reason:string|null},workers:"opendiscord:blacklist-add"},
"opendiscord:blacklist-remove":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User,reason:string|null},workers:"opendiscord:blacklist-remove"}
"opendiscord:blacklist-dm":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-dm"},
"opendiscord:blacklist-logs":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-logs"},
"opendiscord:transcript-text-ready":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{contents:string},null>,result:ODTranscriptCompilerCompileResult<{contents:string}>},workers:"opendiscord:transcript-text-ready"},
"opendiscord:transcript-html-ready":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,result:ODTranscriptCompilerCompileResult<{url:string,availableUntil:Date}>},workers:"opendiscord:transcript-html-ready"},
"opendiscord:transcript-html-progress":{source:"channel"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,remaining:number},workers:"opendiscord:transcript-html-progress"},
"opendiscord:transcript-error":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,reason:string|null},workers:"opendiscord:transcript-error"},
"opendiscord:reaction-role":{source:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role"},
"opendiscord:reaction-role-dm":{source:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role-dm"},
"opendiscord:reaction-role-logs":{source:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role-logs"},
"opendiscord:clear-verify-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-verify-message"},
"opendiscord:clear-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-message"},
"opendiscord:clear-logs":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-logs"},
"opendiscord:autoclose-message":{source:"timeout"|"leave"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:autoclose-message"},
"opendiscord:autodelete-message":{source:"timeout"|"leave"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:autodelete-message"},
"opendiscord:autoclose-enable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,time:number,reason:string|null},workers:"opendiscord:autoclose-enable"},
"opendiscord:autodelete-enable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,time:number,reason:string|null},workers:"opendiscord:autodelete-enable"},
"opendiscord:autoclose-disable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:autoclose-disable"},
"opendiscord:autodelete-disable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:autodelete-disable"},
"opendiscord:topic-set":{source:"slash"|"text"|"ticket-action"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,topic:string},workers:"opendiscord:topic-set"},
"opendiscord:priority-set":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,priority:ODPriorityLevel,reason:string|null},workers:"opendiscord:priority-set"},
"opendiscord:priority-get":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,priority:ODPriorityLevel},workers:"opendiscord:priority-get"},
"opendiscord:transfer-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,oldCreator:discord.User,newCreator:discord.User,reason:string|null},workers:"opendiscord:transfer-message"},
}
/**## ODEmbedManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODEmbedManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.builders.embeds`!
*/
export class ODEmbedManager_Default extends ODEmbedManager {
get<EmbedId extends keyof ODEmbedManagerIds_Default>(id:EmbedId): ODEmbed_Default<ODEmbedManagerIds_Default[EmbedId]["source"],ODEmbedManagerIds_Default[EmbedId]["params"],ODEmbedManagerIds_Default[EmbedId]["workers"]>
get(id:ODValidId): ODEmbed<string,any>|null
get(id:ODValidId): ODEmbed<string,any>|null {
return super.get(id)
}
remove<EmbedId extends keyof ODEmbedManagerIds_Default>(id:EmbedId): ODEmbed_Default<ODEmbedManagerIds_Default[EmbedId]["source"],ODEmbedManagerIds_Default[EmbedId]["params"],ODEmbedManagerIds_Default[EmbedId]["workers"]>
remove(id:ODValidId): ODEmbed<string,any>|null
remove(id:ODValidId): ODEmbed<string,any>|null {
return super.remove(id)
}
exists(id:keyof ODEmbedManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getSafe<EmbedId extends keyof ODEmbedManagerIds_Default>(id:EmbedId): ODEmbed_Default<ODEmbedManagerIds_Default[EmbedId]["source"],ODEmbedManagerIds_Default[EmbedId]["params"],ODEmbedManagerIds_Default[EmbedId]["workers"]>
getSafe(id:ODValidId): ODEmbed<string,any>
getSafe(id:ODValidId): ODEmbed<string,any> {
return super.getSafe(id)
}
}
/**## ODEmbed_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODEmbed class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODEmbed`'s!
*/
export class ODEmbed_Default<Source extends string, Params, WorkerIds extends string> extends ODEmbed<Source,Params> {
declare workers: ODWorkerManager_Default<ODEmbedInstance,Source,Params,WorkerIds>
}
/**## ODMessageManagerIds_Default `interface`
* This interface is a list of ids available in the `ODMessageManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODMessageManagerIds_Default {
"opendiscord:verifybar-ticket-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"opendiscord:verifybar-ticket-message"},
"opendiscord:verifybar-close-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"opendiscord:verifybar-close-message"},
"opendiscord:verifybar-reopen-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"opendiscord:verifybar-reopen-message"},
"opendiscord:verifybar-claim-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"opendiscord:verifybar-claim-message"},
"opendiscord:verifybar-unclaim-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"opendiscord:verifybar-unclaim-message"},
"opendiscord:verifybar-pin-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"opendiscord:verifybar-pin-message"},
"opendiscord:verifybar-unpin-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"opendiscord:verifybar-unpin-message"}
"opendiscord:verifybar-autoclose-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"opendiscord:verifybar-autoclose-message"}
"opendiscord:error":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:string,layout:"simple"|"advanced",customTitle?:string},workers:"opendiscord:error"},
"opendiscord:error-option-missing":{source:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:ODTextCommandErrorMissingOption},workers:"opendiscord:error-option-missing"},
"opendiscord:error-option-invalid":{source:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:ODTextCommandErrorInvalidOption},workers:"opendiscord:error-option-invalid"},
"opendiscord:error-unknown-command":{source:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:ODTextCommandErrorUnknownCommand},workers:"opendiscord:error-unknown-command"},
"opendiscord:error-no-permissions":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,permissions:ODPermissionEmbedType[]},workers:"opendiscord:error-no-permissions"},
"opendiscord:error-no-permissions-cooldown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,until?:Date},workers:"opendiscord:error-no-permissions-cooldown"},
"opendiscord:error-no-permissions-blacklisted":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-no-permissions-blacklisted"},
"opendiscord:error-no-permissions-limits":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,limit:"global"|"global-user"|"option"|"option-user"},workers:"opendiscord:error-no-permissions-limits"},
"opendiscord:error-responder-timeout":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-responder-timeout"},
"opendiscord:error-ticket-unknown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-ticket-unknown"},
"opendiscord:error-ticket-deprecated":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-ticket-deprecated"},
"opendiscord:error-option-unknown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-option-unknown"},
"opendiscord:error-panel-unknown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-panel-unknown"},
"opendiscord:error-not-in-guild":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-not-in-guild"},
"opendiscord:error-channel-rename":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"ticket-pin"|"ticket-unpin"|"ticket-rename"|"ticket-move"|"ticket-priority"|"ticket-transfer"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,originalName:string,newName:string},workers:"opendiscord:error-channel-rename"},
"opendiscord:error-ticket-busy":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-ticket-busy"},
"opendiscord:help-menu":{source:"slash"|"text"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu"},
"opendiscord:stats-global":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:stats-global"},
"opendiscord:stats-ticket":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,scopeData:ODTicket},workers:"opendiscord:stats-ticket"},
"opendiscord:stats-user":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,scopeData:discord.User},workers:"opendiscord:stats-user"|"opendiscord:easter-egg"},
"opendiscord:stats-reset":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,reason:string|null},workers:"opendiscord:stats-reset"},
"opendiscord:stats-ticket-unknown":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,id:string},workers:"opendiscord:stats-ticket-unknown"},
"opendiscord:panel":{source:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel},workers:"opendiscord:panel-layout"|"opendiscord:panel-components"},
"opendiscord:panel-ready":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel},workers:"opendiscord:panel-ready"},
"opendiscord:ticket-created":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created"},
"opendiscord:ticket-created-dm":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created-dm"},
"opendiscord:ticket-created-logs":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created-logs"},
"opendiscord:ticket-message":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-message-layout"|"opendiscord:ticket-message-components"|"opendiscord:ticket-message-disable-components"},
"opendiscord:close-message":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"autoclose"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:close-message"},
"opendiscord:reopen-message":{source:"slash"|"text"|"ticket-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:reopen-message"},
"opendiscord:delete-message":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:delete-message"},
"opendiscord:claim-message":{source:"slash"|"text"|"ticket-message"|"unclaim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:claim-message"},
"opendiscord:unclaim-message":{source:"slash"|"text"|"ticket-message"|"claim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:unclaim-message"},
"opendiscord:pin-message":{source:"slash"|"text"|"ticket-message"|"unpin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:pin-message"},
"opendiscord:unpin-message":{source:"slash"|"text"|"ticket-message"|"pin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:unpin-message"},
"opendiscord:rename-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:string},workers:"opendiscord:rename-message"},
"opendiscord:move-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:ODTicketOption},workers:"opendiscord:move-message"},
"opendiscord:add-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:discord.User},workers:"opendiscord:add-message"},
"opendiscord:remove-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:discord.User},workers:"opendiscord:remove-message"},
"opendiscord:ticket-action-dm":{source:"slash"|"text"|"ticket-message"|"close-message"|"reopen-message"|"delete-message"|"claim-message"|"unclaim-message"|"pin-message"|"unpin-message"|"autoclose-message"|"autoclose"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"close"|"reopen"|"delete"|"claim"|"unclaim"|"pin"|"unpin"|"rename"|"move"|"add"|"remove",ticket:ODTicket,reason:string|null,additionalData:null|string|discord.User|ODTicketOption},workers:"opendiscord:ticket-action-dm"},
"opendiscord:ticket-action-logs":{source:"slash"|"text"|"ticket-message"|"close-message"|"reopen-message"|"delete-message"|"claim-message"|"unclaim-message"|"pin-message"|"unpin-message"|"autoclose-message"|"autoclose"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"close"|"reopen"|"delete"|"claim"|"unclaim"|"pin"|"unpin"|"rename"|"move"|"add"|"remove",ticket:ODTicket,reason:string|null,additionalData:null|string|discord.User|ODTicketOption},workers:"opendiscord:ticket-action-logs"},
"opendiscord:blacklist-view":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:blacklist-view"},
"opendiscord:blacklist-get":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User},workers:"opendiscord:blacklist-get"},
"opendiscord:blacklist-add":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User,reason:string|null},workers:"opendiscord:blacklist-add"},
"opendiscord:blacklist-remove":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User,reason:string|null},workers:"opendiscord:blacklist-remove"},
"opendiscord:blacklist-dm":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-dm"},
"opendiscord:blacklist-logs":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-logs"},
"opendiscord:transcript-text-ready":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{contents:string},null>,result:ODTranscriptCompilerCompileResult<{contents:string}>},workers:"opendiscord:transcript-text-ready"},
"opendiscord:transcript-html-ready":{source:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,result:ODTranscriptCompilerCompileResult<{url:string,availableUntil:Date}>},workers:"opendiscord:transcript-html-ready"},
"opendiscord:transcript-html-progress":{source:"channel"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,remaining:number},workers:"opendiscord:transcript-html-progress"},
"opendiscord:transcript-error":{source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,reason:string|null},workers:"opendiscord:transcript-error"},
"opendiscord:reaction-role":{source:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role"},
"opendiscord:reaction-role-dm":{source:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role-dm"},
"opendiscord:reaction-role-logs":{source:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role-logs"},
"opendiscord:clear-verify-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-verify-message"},
"opendiscord:clear-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-message"},
"opendiscord:clear-logs":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-logs"},
"opendiscord:autoclose-message":{source:"timeout"|"leave"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:autoclose-message"},
"opendiscord:autodelete-message":{source:"timeout"|"leave"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:autodelete-message"},
"opendiscord:autoclose-enable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,time:number,reason:string|null},workers:"opendiscord:autoclose-enable"},
"opendiscord:autodelete-enable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,time:number,reason:string|null},workers:"opendiscord:autodelete-enable"},
"opendiscord:autoclose-disable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:autoclose-disable"},
"opendiscord:autodelete-disable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:autodelete-disable"},
"opendiscord:topic-set":{source:"slash"|"text"|"ticket-action"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,topic:string},workers:"opendiscord:topic-set"},
"opendiscord:priority-set":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,priority:ODPriorityLevel,reason:string|null},workers:"opendiscord:priority-set"},
"opendiscord:priority-get":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,priority:ODPriorityLevel},workers:"opendiscord:priority-get"},
"opendiscord:transfer-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,oldCreator:discord.User,newCreator:discord.User,reason:string|null},workers:"opendiscord:transfer-message"},
}
/**## ODMessageManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODMessageManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.builders.messages`!
*/
export class ODMessageManager_Default extends ODMessageManager {
get<MessageId extends keyof ODMessageManagerIds_Default>(id:MessageId): ODMessage_Default<ODMessageManagerIds_Default[MessageId]["source"],ODMessageManagerIds_Default[MessageId]["params"],ODMessageManagerIds_Default[MessageId]["workers"]>
get(id:ODValidId): ODMessage<string,any>|null
get(id:ODValidId): ODMessage<string,any>|null {
return super.get(id)
}
remove<MessageId extends keyof ODMessageManagerIds_Default>(id:MessageId): ODMessage_Default<ODMessageManagerIds_Default[MessageId]["source"],ODMessageManagerIds_Default[MessageId]["params"],ODMessageManagerIds_Default[MessageId]["workers"]>
remove(id:ODValidId): ODMessage<string,any>|null
remove(id:ODValidId): ODMessage<string,any>|null {
return super.remove(id)
}
exists(id:keyof ODMessageManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getSafe<MessageId extends keyof ODMessageManagerIds_Default>(id:MessageId): ODMessage_Default<ODMessageManagerIds_Default[MessageId]["source"],ODMessageManagerIds_Default[MessageId]["params"],ODMessageManagerIds_Default[MessageId]["workers"]>
getSafe(id:ODValidId): ODMessage<string,any>
getSafe(id:ODValidId): ODMessage<string,any> {
return super.getSafe(id)
}
}
/**## ODMessage_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODMessage class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODMessage`'s!
*/
export class ODMessage_Default<Source extends string, Params, WorkerIds extends string> extends ODMessage<Source,Params> {
declare workers: ODWorkerManager_Default<ODMessageInstance,Source,Params,WorkerIds>
}
/**## ODModalManagerIds_Default `interface`
* This interface is a list of ids available in the `ODModalManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODModalManagerIds_Default {
"opendiscord:ticket-questions":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,option:ODTicketOption},workers:"opendiscord:ticket-questions"}
"opendiscord:close-ticket-reason":{source:"ticket-message"|"reopen-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:close-ticket-reason"}
"opendiscord:reopen-ticket-reason":{source:"ticket-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:reopen-ticket-reason"}
"opendiscord:delete-ticket-reason":{source:"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:delete-ticket-reason"}
"opendiscord:claim-ticket-reason":{source:"ticket-message"|"unclaim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:claim-ticket-reason"}
"opendiscord:unclaim-ticket-reason":{source:"ticket-message"|"claim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:unclaim-ticket-reason"}
"opendiscord:pin-ticket-reason":{source:"ticket-message"|"unpin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:pin-ticket-reason"}
"opendiscord:unpin-ticket-reason":{source:"ticket-message"|"pin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:unpin-ticket-reason"}
}
/**## ODModalManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODModalManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.builders.modals`!
*/
export class ODModalManager_Default extends ODModalManager {
get<ModalId extends keyof ODModalManagerIds_Default>(id:ModalId): ODModal_Default<ODModalManagerIds_Default[ModalId]["source"],ODModalManagerIds_Default[ModalId]["params"],ODModalManagerIds_Default[ModalId]["workers"]>
get(id:ODValidId): ODModal<string,any>|null
get(id:ODValidId): ODModal<string,any>|null {
return super.get(id)
}
remove<ModalId extends keyof ODModalManagerIds_Default>(id:ModalId): ODModal_Default<ODModalManagerIds_Default[ModalId]["source"],ODModalManagerIds_Default[ModalId]["params"],ODModalManagerIds_Default[ModalId]["workers"]>
remove(id:ODValidId): ODModal<string,any>|null
remove(id:ODValidId): ODModal<string,any>|null {
return super.remove(id)
}
exists(id:keyof ODModalManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getSafe<ModalId extends keyof ODModalManagerIds_Default>(id:ModalId): ODModal_Default<ODModalManagerIds_Default[ModalId]["source"],ODModalManagerIds_Default[ModalId]["params"],ODModalManagerIds_Default[ModalId]["workers"]>
getSafe(id:ODValidId): ODModal<string,any>
getSafe(id:ODValidId): ODModal<string,any> {
return super.getSafe(id)
}
}
/**## ODModal_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODModal class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODModal`'s!
*/
export class ODModal_Default<Source extends string, Params, WorkerIds extends string> extends ODModal<Source,Params> {
declare workers: ODWorkerManager_Default<ODModalInstance,Source,Params,WorkerIds>
}
-385
View File
@@ -1,385 +0,0 @@
///////////////////////////////////////
//DEFAULT CONFIG CHECKER MODULE
///////////////////////////////////////
import { ODLanguageManager_Default } from "../api"
import { ODValidId } from "../modules/base"
import { ODCheckerManager, ODChecker, ODCheckerTranslationRegister, ODCheckerRenderer, ODCheckerFunctionManager, ODCheckerResult, ODCheckerFunction } from "../modules/checker"
import ansis from "ansis"
/**## ODCheckerManagerIds_Default `interface`
* This interface is a list of ids available in the `ODCheckerManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODCheckerManagerIds_Default {
"opendiscord:general":ODChecker,
"opendiscord:questions":ODChecker,
"opendiscord:options":ODChecker,
"opendiscord:panels":ODChecker,
"opendiscord:transcripts":ODChecker
}
/**## ODCheckerManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODCheckerManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.checkers`!
*/
export class ODCheckerManager_Default extends ODCheckerManager {
declare translation: ODCheckerTranslationRegister_Default
declare renderer: ODCheckerRenderer_Default
declare functions: ODCheckerFunctionManager_Default
get<CheckerId extends keyof ODCheckerManagerIds_Default>(id:CheckerId): ODCheckerManagerIds_Default[CheckerId]
get(id:ODValidId): ODChecker|null
get(id:ODValidId): ODChecker|null {
return super.get(id)
}
remove<CheckerId extends keyof ODCheckerManagerIds_Default>(id:CheckerId): ODCheckerManagerIds_Default[CheckerId]
remove(id:ODValidId): ODChecker|null
remove(id:ODValidId): ODChecker|null {
return super.remove(id)
}
exists(id:keyof ODCheckerManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODCheckerRenderer_Default `default_class`
* This is a special class that adds type definitions & features to the ODCheckerRenderer class.
* It contains the code that renders the default config checker.
*
* This default class is made for the global variable `opendiscord.checkers.renderer`!
*/
export class ODCheckerRenderer_Default extends ODCheckerRenderer {
extraHeaderText: string[] = []
extraFooterText: string[] = []
extraTopText: string[] = []
extraBottomText: string[] = []
horizontalFiller: string = "="
verticalFiller: string = "|"
descriptionSeparator: string = " => "
headerSeparator: string = " => "
footerTipPrefix: string = "=> "
disableHeader: boolean = false
disableFooter: boolean = false
getComponents(compact:boolean, renderEmpty:boolean, translation:ODCheckerTranslationRegister_Default, data:ODCheckerResult): string[] {
const tm = translation
const t = {
headerOpenticket:tm.get("other","opendiscord:header-openticket") ?? "OPEN TICKET",
headerConfigchecker:tm.get("other","opendiscord:header-configchecker") ?? "CONFIG CHECKER",
headerDescription:tm.get("other","opendiscord:header-description") ?? "check for errors in your config files!",
footerError:tm.get("other","opendiscord:footer-error") ?? "the bot won't start until all {0}'s are fixed!",
footerWarning:tm.get("other","opendiscord:footer-warning") ?? "it's recommended to fix all {0}'s before starting!",
footerSupport:tm.get("other","opendiscord:footer-support") ?? "SUPPORT: {0} - DOCS: {1}",
error:tm.get("other","opendiscord:type-error") ?? "[ERROR]",
warning:tm.get("other","opendiscord:type-warning") ?? "[WARNING]",
info:tm.get("other","opendiscord:type-info") ?? "[INFO]",
compactInfo:tm.get("other","opendiscord:compact-information") ?? "use {0} for more information!",
dataPath:tm.get("other","opendiscord:data-path") ?? "path",
dataDocs:tm.get("other","opendiscord:data-docs") ?? "docs",
dataMessage:tm.get("other","opendiscord:data-message") ?? "message"
}
const hasErrors = data.messages.filter((m) => m.type == "error").length > 0
const hasWarnings = data.messages.filter((m) => m.type == "warning").length > 0
const hasInfo = data.messages.filter((m) => m.type == "info").length > 0
if (!renderEmpty && !hasErrors && !hasWarnings && (!hasInfo || compact)) return []
const headerText = ansis.bold.hex("#f8ba00")(t.headerOpenticket)+" "+t.headerConfigchecker+this.headerSeparator+ansis.hex("#f8ba00")(t.headerDescription)
const footerErrorText = (hasErrors) ? this.footerTipPrefix+ansis.gray(tm.insertTranslationParams(t.footerError,[ansis.bold.red(t.error)])) : ""
const footerWarningText = (hasWarnings) ? this.footerTipPrefix+ansis.gray(tm.insertTranslationParams(t.footerWarning,[ansis.bold.yellow(t.warning)])) : ""
const footerSupportText = tm.insertTranslationParams(t.footerSupport,[ansis.green("https://discord.dj-dj.be"),ansis.green("https://otdocs.dj-dj.be")])
const bottomCompactInfo = (compact) ? ansis.gray(tm.insertTranslationParams(t.compactInfo,[ansis.bold.green("npm start -- --checker")])) : ""
const finalHeader = [headerText,...this.extraHeaderText]
const finalFooter = [footerErrorText,footerWarningText,footerSupportText,...this.extraFooterText]
const finalTop = [...this.extraTopText]
const finalBottom = [bottomCompactInfo,...this.extraBottomText]
const borderLength = this.#getLongestLength([...finalHeader,...finalFooter])
const finalComponents: string[] = []
//header
if (!this.disableHeader){
finalHeader.forEach((text) => {
if (text.length < 1) return
finalComponents.push(this.#createBlockFromText(text,borderLength))
})
}
finalComponents.push(this.#getHorizontalDivider(borderLength+4))
//top
finalTop.forEach((text) => {
if (text.length < 1) return
finalComponents.push(this.verticalFiller+" "+text)
})
finalComponents.push(this.verticalFiller)
//messages
if (compact){
//use compact messages
data.messages.forEach((msg,index) => {
//compact mode doesn't render info
if (msg.type == "info") return
//check if translation available & use it if possible
const rawTranslation = tm.get("message",msg.messageId.value)
const translatedMessage = (rawTranslation) ? tm.insertTranslationParams(rawTranslation,msg.translationParams) : msg.message
if (msg.type == "error") finalComponents.push(this.verticalFiller+" "+ansis.bold.red(`${t.error} ${translatedMessage}`))
else if (msg.type == "warning") finalComponents.push(this.verticalFiller+" "+ansis.bold.yellow(`${t.warning} ${translatedMessage}`))
const pathSplitter = msg.path ? ":" : ""
finalComponents.push(this.verticalFiller+ansis.bold(this.descriptionSeparator)+ansis.cyan(`${ansis.magenta(msg.filepath+pathSplitter)} ${msg.path}`))
if (index != data.messages.length-1) finalComponents.push(this.verticalFiller)
})
}else{
//use full messages
data.messages.forEach((msg,index) => {
//check if translation available & use it if possible
const rawTranslation = tm.get("message",msg.messageId.value)
const translatedMessage = (rawTranslation) ? tm.insertTranslationParams(rawTranslation,msg.translationParams) : msg.message
if (msg.type == "error") finalComponents.push(this.verticalFiller+" "+ansis.bold.red(`${t.error} ${translatedMessage}`))
else if (msg.type == "warning") finalComponents.push(this.verticalFiller+" "+ansis.bold.yellow(`${t.warning} ${translatedMessage}`))
else if (msg.type == "info") finalComponents.push(this.verticalFiller+" "+ansis.bold.blue(`${t.info} ${translatedMessage}`))
const pathSplitter = msg.path ? ":" : ""
finalComponents.push(this.verticalFiller+" "+ansis.bold((t.dataPath)+this.descriptionSeparator)+ansis.cyan(`${ansis.magenta(msg.filepath+pathSplitter)} ${msg.path}`))
if (msg.locationDocs) finalComponents.push(this.verticalFiller+" "+ansis.bold(t.dataDocs+this.descriptionSeparator)+ansis.italic.gray(msg.locationDocs))
if (msg.messageDocs) finalComponents.push(this.verticalFiller+" "+ansis.bold(t.dataMessage+this.descriptionSeparator)+ansis.italic.gray(msg.messageDocs))
if (index != data.messages.length-1) finalComponents.push(this.verticalFiller)
})
}
//bottom
finalComponents.push(this.verticalFiller)
finalBottom.forEach((text) => {
if (text.length < 1) return
finalComponents.push(this.verticalFiller+" "+text)
})
//footer
finalComponents.push(this.#getHorizontalDivider(borderLength+4))
if (!this.disableFooter){
finalFooter.forEach((text) => {
if (text.length < 1) return
finalComponents.push(this.#createBlockFromText(text,borderLength))
})
finalComponents.push(this.#getHorizontalDivider(borderLength+4))
}
//return all components
return finalComponents
}
/**Get the length of the longest string in the array. */
#getLongestLength(texts:string[]): number {
return Math.max(...texts.map((t) => ansis.strip(t).length))
}
/**Get a horizontal divider used between different parts of the config checker result. */
#getHorizontalDivider(width:number): string {
if (width > 2) width = width-2
else return this.verticalFiller+this.verticalFiller
let divider = this.verticalFiller + this.horizontalFiller.repeat(width) + this.verticalFiller
return divider
}
/**Create a block of text with a vertical divider on the left & right side. */
#createBlockFromText(text:string,width:number): string {
if (width < 3) return this.verticalFiller+this.verticalFiller
let newWidth = width-ansis.strip(text).length+1
let final = this.verticalFiller+" "+text+" ".repeat(newWidth)+this.verticalFiller
return final
}
}
/**## ODCheckerTranslationRegisterOtherIds_Default `interface`
* This interface is a list of ids available in the `ODCheckerTranslationRegister_Default` class.
* It's used to generate typescript declarations for this class.
*/
export type ODCheckerTranslationRegisterOtherIds_Default = (
"opendiscord:header-openticket"|
"opendiscord:header-configchecker"|
"opendiscord:header-description"|
"opendiscord:type-error"|
"opendiscord:type-warning"|
"opendiscord:type-info"|
"opendiscord:data-path"|
"opendiscord:data-docs"|
"opendiscord:data-message"|
"opendiscord:compact-information"|
"opendiscord:footer-error"|
"opendiscord:footer-warning"|
"opendiscord:footer-support"
)
/**## ODCheckerTranslationRegisterMessageIds_Default `interface`
* This interface is a list of ids available in the `ODCheckerTranslationRegister_Default` class.
* It's used to generate typescript declarations for this class.
*/
export type ODCheckerTranslationRegisterMessageIds_Default = (
"opendiscord:invalid-type"|
"opendiscord:property-missing"|
"opendiscord:property-optional"|
"opendiscord:object-disabled"|
"opendiscord:null-invalid"|
"opendiscord:switch-invalid-type"|
"opendiscord:object-switch-invalid-type"|
"opendiscord:string-too-short"|
"opendiscord:string-too-long"|
"opendiscord:string-length-invalid"|
"opendiscord:string-starts-with"|
"opendiscord:string-ends-with"|
"opendiscord:string-contains"|
"opendiscord:string-inverted-contains"|
"opendiscord:string-choices"|
"opendiscord:string-lowercase"|
"opendiscord:string-uppercase"|
"opendiscord:string-special-characters"|
"opendiscord:string-no-spaces"|
"opendiscord:string-regex"|
"opendiscord:string-capital-word"|
"opendiscord:string-capital-sentence"|
"opendiscord:string-punctuation"|
"opendiscord:number-nan"|
"opendiscord:number-too-short"|
"opendiscord:number-too-long"|
"opendiscord:number-length-invalid"|
"opendiscord:number-too-small"|
"opendiscord:number-too-large"|
"opendiscord:number-not-equal"|
"opendiscord:number-step"|
"opendiscord:number-step-offset"|
"opendiscord:number-starts-with"|
"opendiscord:number-ends-with"|
"opendiscord:number-contains"|
"opendiscord:number-inverted-contains"|
"opendiscord:number-choices"|
"opendiscord:number-float"|
"opendiscord:number-negative"|
"opendiscord:number-positive"|
"opendiscord:number-zero"|
"opendiscord:boolean-true"|
"opendiscord:boolean-false"|
"opendiscord:array-empty-disabled"|
"opendiscord:array-empty-required"|
"opendiscord:array-too-short"|
"opendiscord:array-too-long"|
"opendiscord:array-length-invalid"|
"opendiscord:array-invalid-types"|
"opendiscord:array-double"|
"opendiscord:discord-invalid-id"|
"opendiscord:discord-invalid-id-options"|
"opendiscord:discord-invalid-token"|
"opendiscord:color-invalid"|
"opendiscord:emoji-too-short"|
"opendiscord:emoji-too-long"|
"opendiscord:emoji-custom"|
"opendiscord:emoji-invalid"|
"opendiscord:url-invalid"|
"opendiscord:url-invalid-http"|
"opendiscord:url-invalid-protocol"|
"opendiscord:url-invalid-hostname"|
"opendiscord:url-invalid-extension"|
"opendiscord:url-invalid-path"|
"opendiscord:id-not-unique"|
"opendiscord:id-non-existent"|
"opendiscord:invalid-language"|
"opendiscord:invalid-button"|
"opendiscord:unused-option"|
"opendiscord:unused-question"|
"opendiscord:dropdown-option"
)
/**## ODCheckerTranslationRegister_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODCheckerTranslationRegister class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.checkers.translation`!
*/
export class ODCheckerTranslationRegister_Default extends ODCheckerTranslationRegister {
get(type:"other", id:ODCheckerTranslationRegisterOtherIds_Default): string
get(type:"message", id:ODCheckerTranslationRegisterMessageIds_Default): string
get(type:"message"|"other", id:string): string|null
get(type:"message"|"other", id:string): string|null {
return super.get(type,id)
}
set(type:"other", id:ODCheckerTranslationRegisterOtherIds_Default, translation:string): boolean
set(type:"message", id:ODCheckerTranslationRegisterMessageIds_Default, translation:string): boolean
set(type:"message"|"other", id:string, translation:string): boolean
set(type:"message"|"other", id:string, translation:string): boolean {
return super.set(type,id,translation)
}
delete(type:"other", id:ODCheckerTranslationRegisterOtherIds_Default): boolean
delete(type:"message", id:ODCheckerTranslationRegisterMessageIds_Default): boolean
delete(type:"message"|"other", id:string): boolean
delete(type:"message"|"other", id:string): boolean {
return super.delete(type,id)
}
quickTranslate(manager:ODLanguageManager_Default, translationId:string, type:"other"|"message", id:ODCheckerTranslationRegisterOtherIds_Default|ODCheckerTranslationRegisterMessageIds_Default)
quickTranslate(manager:ODLanguageManager_Default, translationId:string, type:"other"|"message", id:string)
quickTranslate(manager:ODLanguageManager_Default, translationId:string, type:"other"|"message", id:ODCheckerTranslationRegisterOtherIds_Default|ODCheckerTranslationRegisterMessageIds_Default|string){
super.quickTranslate(manager,translationId,type,id)
}
}
/**## ODCheckerFunctionManagerIds_Default `interface`
* This interface is a list of ids available in the `ODCheckerFunctionManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODCheckerFunctionManagerIds_Default {
"opendiscord:unused-options":ODCheckerFunction,
"opendiscord:unused-questions":ODCheckerFunction,
"opendiscord:dropdown-options":ODCheckerFunction
}
/**## ODCheckerFunctionManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODCheckerFunctionManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.checkers.functions`!
*/
export class ODCheckerFunctionManager_Default extends ODCheckerFunctionManager {
get<CheckerFunctionId extends keyof ODCheckerFunctionManagerIds_Default>(id:CheckerFunctionId): ODCheckerFunctionManagerIds_Default[CheckerFunctionId]
get(id:ODValidId): ODCheckerFunction|null
get(id:ODValidId): ODCheckerFunction|null {
return super.get(id)
}
remove<CheckerFunctionId extends keyof ODCheckerFunctionManagerIds_Default>(id:CheckerFunctionId): ODCheckerFunctionManagerIds_Default[CheckerFunctionId]
remove(id:ODValidId): ODCheckerFunction|null
remove(id:ODValidId): ODCheckerFunction|null {
return super.remove(id)
}
exists(id:keyof ODCheckerFunctionManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-207
View File
@@ -1,207 +0,0 @@
///////////////////////////////////////
//DEFAULT CLIENT MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODClientManager, ODSlashCommand, ODTextCommand, ODSlashCommandManager, ODTextCommandManager, ODSlashCommandInteractionCallback, ODTextCommandInteractionCallback, ODContextMenu, ODContextMenuManager, ODContextMenuInteractionCallback } from "../modules/client"
/** (CONTRIBUTOR GUIDE) HOW TO ADD NEW COMMANDS?
* - Register the command in loadAllSlashCommands() & loadAllTextCommands() in (./src/data/framework/commandLoader.ts)
* - Add autocomplete for the command in OD(Slash/Text)CommandManagerIds_Default in (./src/core/api/defaults/client.ts)
* - Add the command to the help menu in (./src/data/framework/helpMenuLoader.ts)
* - If required, new config variables should be added (incl. logs, dm-logs & permissions).
* - Update the Open Ticket Documentation.
* - If the command contains complex logic or can be executed from a button/dropdown, it should be placed inside an `ODAction`.
* - Check all files, test the bot carefully & try a lot of different scenario's with different settings.
*/
/**## ODClientManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODClientManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.client`!
*/
export class ODClientManager_Default extends ODClientManager {
declare slashCommands: ODSlashCommandManager_Default
declare textCommands: ODTextCommandManager_Default
declare contextMenus: ODContextMenuManager_Default
}
/**## ODSlashCommandManagerIds_Default `interface`
* This interface is a list of ids available in the `ODSlashCommandManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODSlashCommandManagerIds_Default {
"opendiscord:help":ODSlashCommand,
"opendiscord:panel":ODSlashCommand,
"opendiscord:ticket":ODSlashCommand,
"opendiscord:close":ODSlashCommand,
"opendiscord:delete":ODSlashCommand,
"opendiscord:reopen":ODSlashCommand,
"opendiscord:claim":ODSlashCommand,
"opendiscord:unclaim":ODSlashCommand,
"opendiscord:pin":ODSlashCommand,
"opendiscord:unpin":ODSlashCommand,
"opendiscord:move":ODSlashCommand,
"opendiscord:rename":ODSlashCommand,
"opendiscord:add":ODSlashCommand,
"opendiscord:remove":ODSlashCommand,
"opendiscord:blacklist":ODSlashCommand,
"opendiscord:stats":ODSlashCommand,
"opendiscord:clear":ODSlashCommand,
"opendiscord:autoclose":ODSlashCommand,
"opendiscord:autodelete":ODSlashCommand,
"opendiscord:topic":ODSlashCommand,
"opendiscord:priority":ODSlashCommand,
"opendiscord:transfer":ODSlashCommand,
}
/**## ODSlashCommandManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODSlashCommandManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.client.slashCommands`!
*/
export class ODSlashCommandManager_Default extends ODSlashCommandManager {
get<SlashCommandId extends keyof ODSlashCommandManagerIds_Default>(id:SlashCommandId): ODSlashCommandManagerIds_Default[SlashCommandId]
get(id:ODValidId): ODSlashCommand|null
get(id:ODValidId): ODSlashCommand|null {
return super.get(id)
}
remove<SlashCommandId extends keyof ODSlashCommandManagerIds_Default>(id:SlashCommandId): ODSlashCommandManagerIds_Default[SlashCommandId]
remove(id:ODValidId): ODSlashCommand|null
remove(id:ODValidId): ODSlashCommand|null {
return super.remove(id)
}
exists(id:keyof ODSlashCommandManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
onInteraction(commandName:keyof ODSlashCommandManagerIds_Default, callback:ODSlashCommandInteractionCallback): void
onInteraction(commandName:string|RegExp, callback:ODSlashCommandInteractionCallback): void
onInteraction(commandName:string|RegExp, callback:ODSlashCommandInteractionCallback): void {
return super.onInteraction(commandName,callback)
}
}
/**## ODTextCommandManagerIds_Default `interface`
* This interface is a list of ids available in the `ODTextCommandManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODTextCommandManagerIds_Default {
"opendiscord:dump":ODTextCommand,
"opendiscord:help":ODTextCommand,
"opendiscord:panel":ODTextCommand,
"opendiscord:close":ODTextCommand,
"opendiscord:delete":ODTextCommand,
"opendiscord:reopen":ODTextCommand,
"opendiscord:claim":ODTextCommand,
"opendiscord:unclaim":ODTextCommand,
"opendiscord:pin":ODTextCommand,
"opendiscord:unpin":ODTextCommand,
"opendiscord:move":ODTextCommand,
"opendiscord:rename":ODTextCommand,
"opendiscord:add":ODTextCommand,
"opendiscord:remove":ODTextCommand,
"opendiscord:blacklist-view":ODTextCommand,
"opendiscord:blacklist-add":ODTextCommand,
"opendiscord:blacklist-remove":ODTextCommand,
"opendiscord:blacklist-get":ODTextCommand,
"opendiscord:stats-global":ODTextCommand,
"opendiscord:stats-reset":ODTextCommand,
"opendiscord:stats-ticket":ODTextCommand,
"opendiscord:stats-user":ODTextCommand,
"opendiscord:clear":ODTextCommand,
"opendiscord:autoclose-disable":ODTextCommand,
"opendiscord:autoclose-enable":ODTextCommand,
"opendiscord:autodelete-disable":ODTextCommand,
"opendiscord:autodelete-enable":ODTextCommand,
"opendiscord:topic-set":ODTextCommand,
"opendiscord:priority-set":ODTextCommand,
"opendiscord:priority-get":ODTextCommand,
"opendiscord:transfer":ODTextCommand,
}
/**## ODTextCommandManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODTextCommandManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.client.textCommands`!
*/
export class ODTextCommandManager_Default extends ODTextCommandManager {
get<TextCommandId extends keyof ODTextCommandManagerIds_Default>(id:TextCommandId): ODTextCommandManagerIds_Default[TextCommandId]
get(id:ODValidId): ODTextCommand|null
get(id:ODValidId): ODTextCommand|null {
return super.get(id)
}
remove<TextCommandId extends keyof ODTextCommandManagerIds_Default>(id:TextCommandId): ODTextCommandManagerIds_Default[TextCommandId]
remove(id:ODValidId): ODTextCommand|null
remove(id:ODValidId): ODTextCommand|null {
return super.remove(id)
}
exists(id:keyof ODTextCommandManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
onInteraction(commandPrefix:string, commandName:string|RegExp, callback:ODTextCommandInteractionCallback): void {
return super.onInteraction(commandPrefix,commandName,callback)
}
}
/**## ODContextMenuManagerIds_Default `interface`
* This interface is a list of ids available in the `ODContextMenuManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODContextMenuManagerIds_Default {
//"opendiscord:test-menu":ODContextMenu
}
/**## ODContextMenuManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODContextMenuManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.client.contextMenus`!
*/
export class ODContextMenuManager_Default extends ODContextMenuManager {
get<ContextMenuId extends keyof ODContextMenuManagerIds_Default>(id:ContextMenuId): ODContextMenuManagerIds_Default[ContextMenuId]
get(id:ODValidId): ODContextMenu|null
get(id:ODValidId): ODContextMenu|null {
return super.get(id)
}
remove<ContextMenuId extends keyof ODContextMenuManagerIds_Default>(id:ContextMenuId): ODContextMenuManagerIds_Default[ContextMenuId]
remove(id:ODValidId): ODContextMenu|null
remove(id:ODValidId): ODContextMenu|null {
return super.remove(id)
}
exists(id:keyof ODContextMenuManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
onInteraction(menuName:keyof ODContextMenuManagerIds_Default, callback:ODContextMenuInteractionCallback): void
onInteraction(menuName:string|RegExp, callback:ODContextMenuInteractionCallback): void
onInteraction(menuName:string|RegExp, callback:ODContextMenuInteractionCallback): void {
return super.onInteraction(menuName,callback)
}
}
-57
View File
@@ -1,57 +0,0 @@
///////////////////////////////////////
//DEFAULT CODE MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODCode, ODCodeManager } from "../modules/code"
/**## ODCodeManagerIds_Default `interface`
* This interface is a list of ids available in the `ODCodeManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODCodeManagerIds_Default {
"opendiscord:command-error-handling":ODCode,
"opendiscord:start-listening-interactions":ODCode,
"opendiscord:panel-database-cleaner":ODCode,
"opendiscord:suffix-database-cleaner":ODCode,
"opendiscord:option-database-cleaner":ODCode,
"opendiscord:user-database-cleaner":ODCode,
"opendiscord:ticket-database-cleaner":ODCode,
"opendiscord:panel-auto-update":ODCode,
"opendiscord:ticket-saver":ODCode,
"opendiscord:blacklist-saver":ODCode,
"opendiscord:auto-role-on-join":ODCode,
"opendiscord:autoclose-timeout":ODCode,
"opendiscord:autoclose-leave":ODCode,
"opendiscord:autodelete-timeout":ODCode,
"opendiscord:autodelete-leave":ODCode,
"opendiscord:ticket-anti-busy":ODCode,
}
/**## ODCodeManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODCodeManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.code`!
*/
export class ODCodeManager_Default extends ODCodeManager {
get<CodeId extends keyof ODCodeManagerIds_Default>(id:CodeId): ODCodeManagerIds_Default[CodeId]
get(id:ODValidId): ODCode|null
get(id:ODValidId): ODCode|null {
return super.get(id)
}
remove<CodeId extends keyof ODCodeManagerIds_Default>(id:CodeId): ODCodeManagerIds_Default[CodeId]
remove(id:ODValidId): ODCode|null
remove(id:ODValidId): ODCode|null {
return super.remove(id)
}
exists(id:keyof ODCodeManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-42
View File
@@ -1,42 +0,0 @@
///////////////////////////////////////
//DEFAULT CONSOLE MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODLiveStatusUrlSource, ODLiveStatusManager, ODLiveStatusSource } from "../modules/console"
/**## ODLiveStatusManagerIds_Default `interface`
* This interface is a list of ids available in the `ODLiveStatusManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODLiveStatusManagerIds_Default {
"opendiscord:default-djdj-dev":ODLiveStatusUrlSource
}
/**## ODLiveStatusManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODLiveStatusManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.livestatus`!
*/
export class ODLiveStatusManager_Default extends ODLiveStatusManager {
get<LiveStatusId extends keyof ODLiveStatusManagerIds_Default>(id:LiveStatusId): ODLiveStatusManagerIds_Default[LiveStatusId]
get(id:ODValidId): ODLiveStatusSource|null
get(id:ODValidId): ODLiveStatusSource|null {
return super.get(id)
}
remove<LiveStatusId extends keyof ODLiveStatusManagerIds_Default>(id:LiveStatusId): ODLiveStatusManagerIds_Default[LiveStatusId]
remove(id:ODValidId): ODLiveStatusSource|null
remove(id:ODValidId): ODLiveStatusSource|null {
return super.remove(id)
}
exists(id:keyof ODLiveStatusManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-42
View File
@@ -1,42 +0,0 @@
///////////////////////////////////////
//DEFAULT COOLDOWN MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODCooldown, ODCooldownManager } from "../modules/cooldown"
/**## ODCooldownManagerIds_Default `interface`
* This interface is a list of ids available in the `ODCooldownManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODCooldownManagerIds_Default {
}
/**## ODCooldownManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODCooldownManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.cooldowns`!
*/
export class ODCooldownManager_Default extends ODCooldownManager {
get<CooldownId extends keyof ODCooldownManagerIds_Default>(id:CooldownId): ODCooldownManagerIds_Default[CooldownId]
get(id:ODValidId): ODCooldown<object>|null
get(id:ODValidId): ODCooldown<object>|null {
return super.get(id)
}
remove<CooldownId extends keyof ODCooldownManagerIds_Default>(id:CooldownId): ODCooldownManagerIds_Default[CooldownId]
remove(id:ODValidId): ODCooldown<object>|null
remove(id:ODValidId): ODCooldown<object>|null {
return super.remove(id)
}
exists(id:keyof ODCooldownManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-257
View File
@@ -1,257 +0,0 @@
///////////////////////////////////////
//DEFAULT DATABASE MODULE
///////////////////////////////////////
import { ODOptionalPromise, ODValidId, ODValidJsonType } from "../modules/base"
import { ODDatabaseManager, ODDatabase, ODFormattedJsonDatabase } from "../modules/database"
import { ODTicketJson } from "../openticket/ticket"
import { ODOptionJson } from "../openticket/option"
/**## ODDatabaseManagerIds_Default `interface`
* This interface is a list of ids available in the `ODDatabaseManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODDatabaseManagerIds_Default {
"opendiscord:global":ODFormattedJsonDatabase_DefaultGlobal,
"opendiscord:stats":ODFormattedJsonDatabase,
"opendiscord:tickets":ODFormattedJsonDatabase_DefaultTickets,
"opendiscord:users":ODFormattedJsonDatabase_DefaultUsers,
"opendiscord:options":ODFormattedJsonDatabase_DefaultOptions,
}
/**## ODDatabaseManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODDatabaseManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.databases`!
*/
export class ODDatabaseManager_Default extends ODDatabaseManager {
get<DatabaseId extends keyof ODDatabaseManagerIds_Default>(id:DatabaseId): ODDatabaseManagerIds_Default[DatabaseId]
get(id:ODValidId): ODDatabase|null
get(id:ODValidId): ODDatabase|null {
return super.get(id)
}
remove<DatabaseId extends keyof ODDatabaseManagerIds_Default>(id:DatabaseId): ODDatabaseManagerIds_Default[DatabaseId]
remove(id:ODValidId): ODDatabase|null
remove(id:ODValidId): ODDatabase|null {
return super.remove(id)
}
exists(id:keyof ODDatabaseManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODFormattedJsonDatabaseIds_DefaultGlobal `type`
* This interface is a list of ids available in the `ODFormattedJsonDatabase_DefaultGlobal` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODFormattedJsonDatabaseIds_DefaultGlobal {
"opendiscord:panel-message":string,
"opendiscord:panel-update":string,
"opendiscord:option-suffix-counter":number,
"opendiscord:option-suffix-history":string[],
"opendiscord:last-version":string
}
/**## ODFormattedJsonDatabase_DefaultGlobal `default_class`
* This is a special class that adds type definitions & typescript to the ODFormattedJsonDatabase class.
* It doesn't add any extra features!
*
* This default class is made for the `global.json` database!
*/
export class ODFormattedJsonDatabase_DefaultGlobal extends ODFormattedJsonDatabase {
set<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultGlobal>(category:CategoryId, key:string, value:ODFormattedJsonDatabaseIds_DefaultGlobal[CategoryId]): ODOptionalPromise<boolean>
set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean>
set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> {
return super.set(category,key,value)
}
get<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultGlobal>(category:CategoryId, key:string): ODOptionalPromise<ODFormattedJsonDatabaseIds_DefaultGlobal[CategoryId]|undefined>
get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined>
get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined> {
return super.get(category,key)
}
delete<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultGlobal>(category:CategoryId, key:string): ODOptionalPromise<boolean>
delete(category:string, key:string): ODOptionalPromise<boolean>
delete(category:string, key:string): ODOptionalPromise<boolean> {
return super.delete(category,key)
}
exists(category:keyof ODFormattedJsonDatabaseIds_DefaultGlobal, key:string): ODOptionalPromise<boolean>
exists(category:string, key:string): ODOptionalPromise<boolean>
exists(category:string, key:string): ODOptionalPromise<boolean> {
return super.exists(category,key)
}
getCategory<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultGlobal>(category:CategoryId): ODOptionalPromise<{key:string, value:ODFormattedJsonDatabaseIds_DefaultGlobal[CategoryId]}[]|undefined>
getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined>
getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> {
return super.getCategory(category)
}
}
/**## ODFormattedJsonDatabaseIds_DefaultTickets `type`
* This interface is a list of ids available in the `ODDatabaseManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODFormattedJsonDatabaseIds_DefaultTickets {
"opendiscord:ticket":ODTicketJson
}
/**## ODFormattedJsonDatabase_DefaultTickets `default_class`
* This is a special class that adds type definitions & typescript to the ODFormattedJsonDatabase class.
* It doesn't add any extra features!
*
* This default class is made for the `tickets.json` database!
*/
export class ODFormattedJsonDatabase_DefaultTickets extends ODFormattedJsonDatabase {
set<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultTickets>(category:CategoryId, key:string, value:ODFormattedJsonDatabaseIds_DefaultTickets[CategoryId]): ODOptionalPromise<boolean>
set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean>
set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> {
return super.set(category,key,value)
}
get<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultTickets>(category:CategoryId, key:string): ODOptionalPromise<ODFormattedJsonDatabaseIds_DefaultTickets[CategoryId]|undefined>
get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined>
get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined> {
return super.get(category,key)
}
delete<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultTickets>(category:CategoryId, key:string): ODOptionalPromise<boolean>
delete(category:string, key:string): ODOptionalPromise<boolean>
delete(category:string, key:string): ODOptionalPromise<boolean> {
return super.delete(category,key)
}
exists(category:keyof ODFormattedJsonDatabaseIds_DefaultTickets, key:string): ODOptionalPromise<boolean>
exists(category:string, key:string): ODOptionalPromise<boolean>
exists(category:string, key:string): ODOptionalPromise<boolean> {
return super.exists(category,key)
}
getCategory<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultTickets>(category:CategoryId): ODOptionalPromise<{key:string, value:ODFormattedJsonDatabaseIds_DefaultTickets[CategoryId]}[]|undefined>
getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined>
getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> {
return super.getCategory(category)
}
}
/**## ODFormattedJsonDatabaseIds_DefaultUsers `type`
* This interface is a list of ids available in the `ODDatabaseManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODFormattedJsonDatabaseIds_DefaultUsers {
"opendiscord:blacklist":ODTicketJson
}
/**## ODFormattedJsonDatabase_DefaultUsers `default_class`
* This is a special class that adds type definitions & typescript to the ODFormattedJsonDatabase class.
* It doesn't add any extra features!
*
* This default class is made for the `users.json` database!
*/
export class ODFormattedJsonDatabase_DefaultUsers extends ODFormattedJsonDatabase {
set<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultUsers>(category:CategoryId, key:string, value:ODFormattedJsonDatabaseIds_DefaultUsers[CategoryId]): ODOptionalPromise<boolean>
set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean>
set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> {
return super.set(category,key,value)
}
get<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultUsers>(category:CategoryId, key:string): ODOptionalPromise<ODFormattedJsonDatabaseIds_DefaultUsers[CategoryId]|undefined>
get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined>
get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined> {
return super.get(category,key)
}
delete<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultUsers>(category:CategoryId, key:string): ODOptionalPromise<boolean>
delete(category:string, key:string): ODOptionalPromise<boolean>
delete(category:string, key:string): ODOptionalPromise<boolean> {
return super.delete(category,key)
}
exists(category:keyof ODFormattedJsonDatabaseIds_DefaultUsers, key:string): ODOptionalPromise<boolean>
exists(category:string, key:string): ODOptionalPromise<boolean>
exists(category:string, key:string): ODOptionalPromise<boolean> {
return super.exists(category,key)
}
getCategory<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultUsers>(category:CategoryId): ODOptionalPromise<{key:string, value:ODFormattedJsonDatabaseIds_DefaultUsers[CategoryId]}[]|undefined>
getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined>
getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> {
return super.getCategory(category)
}
}
/**## ODFormattedJsonDatabaseIds_DefaultOptions `type`
* This interface is a list of ids available in the `ODDatabaseManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODFormattedJsonDatabaseIds_DefaultOptions {
"opendiscord:used-option":ODOptionJson
}
/**## ODFormattedJsonDatabase_DefaultOptions `default_class`
* This is a special class that adds type definitions & typescript to the ODFormattedJsonDatabase class.
* It doesn't add any extra features!
*
* This default class is made for the `options.json` database!
*/
export class ODFormattedJsonDatabase_DefaultOptions extends ODFormattedJsonDatabase {
set<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultOptions>(category:CategoryId, key:string, value:ODFormattedJsonDatabaseIds_DefaultOptions[CategoryId]): ODOptionalPromise<boolean>
set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean>
set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> {
return super.set(category,key,value)
}
get<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultOptions>(category:CategoryId, key:string): ODOptionalPromise<ODFormattedJsonDatabaseIds_DefaultOptions[CategoryId]|undefined>
get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined>
get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined> {
return super.get(category,key)
}
delete<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultOptions>(category:CategoryId, key:string): ODOptionalPromise<boolean>
delete(category:string, key:string): ODOptionalPromise<boolean>
delete(category:string, key:string): ODOptionalPromise<boolean> {
return super.delete(category,key)
}
exists(category:keyof ODFormattedJsonDatabaseIds_DefaultOptions, key:string): ODOptionalPromise<boolean>
exists(category:string, key:string): ODOptionalPromise<boolean>
exists(category:string, key:string): ODOptionalPromise<boolean> {
return super.exists(category,key)
}
getCategory<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultOptions>(category:CategoryId): ODOptionalPromise<{key:string, value:ODFormattedJsonDatabaseIds_DefaultOptions[CategoryId]}[]|undefined>
getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined>
getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> {
return super.getCategory(category)
}
}
-390
View File
@@ -1,390 +0,0 @@
///////////////////////////////////////
//DEFAULT EVENT MODULE
///////////////////////////////////////
//BASE MODULES
import { ODPromiseVoid, ODValidId } from "../modules/base"
import { ODConsoleManager, ODError } from "../modules/console"
import { ODCheckerResult, ODCheckerStorage } from "../modules/checker"
import { ODDefaultsManager } from "../modules/defaults"
import { ODLanguage } from "../modules/language"
import { ODClientActivityManager } from "../modules/client"
import { ODEvent, ODEventManager } from "../modules/event"
import * as discord from "discord.js"
//DEFAULT MODULES
import { ODPluginClassManager_Default, ODPluginManager_Default } from "./plugin"
import { ODConfigManager_Default} from "./config"
import { ODDatabaseManager_Default } from "./database"
import { ODFlagManager_Default } from "./flag"
import { ODSessionManager_Default } from "./session"
import { ODLanguageManager_Default } from "./language"
import { ODCheckerFunctionManager_Default, ODCheckerManager_Default, ODCheckerRenderer_Default, ODCheckerTranslationRegister_Default } from "./checker"
import { ODClientManager_Default, ODContextMenuManager_Default, ODSlashCommandManager_Default, ODTextCommandManager_Default } from "./client"
import { ODBuilderManager_Default, ODButtonManager_Default, ODDropdownManager_Default, ODEmbedManager_Default, ODFileManager_Default, ODMessageManager_Default, ODModalManager_Default } from "./builder"
import { ODAutocompleteResponderManager_Default, ODButtonResponderManager_Default, ODCommandResponderManager_Default, ODContextMenuResponderManager_Default, ODDropdownResponderManager_Default, ODModalResponderManager_Default, ODResponderManager_Default } from "./responder"
import { ODActionManager_Default } from "./action"
import { ODPermissionManager_Default } from "./permission"
import { ODHelpMenuManager_Default } from "./helpmenu"
import { ODStatsManager_Default } from "./stat"
import { ODCodeManager_Default } from "./code"
import { ODCooldownManager_Default } from "./cooldown"
import { ODPostManager_Default } from "./post"
import { ODVerifyBarManager_Default } from "./verifybar"
import { ODStartScreenManager_Default } from "./startscreen"
import { ODLiveStatusManager_Default } from "./console"
import { ODProgressBarManager_Default, ODProgressBarRendererManager_Default } from "./progressbar"
//OPEN TICKET MODULES
import { ODOptionManager, ODTicketOption } from "../openticket/option"
import { ODPanel, ODPanelManager } from "../openticket/panel"
import { ODTicket, ODTicketClearFilter, ODTicketManager } from "../openticket/ticket"
import { ODQuestionManager } from "../openticket/question"
import { ODBlacklistManager } from "../openticket/blacklist"
import { ODTranscriptManager_Default } from "../openticket/transcript"
import { ODRole, ODRoleManager } from "../openticket/role"
import { ODPriorityLevel, ODPriorityManager_Default } from "../openticket/priority"
/**## ODEventIds_Default `interface`
* This interface is a list of ids available in the `ODEvent_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODEventIds_Default {
//error handling
"onErrorHandling": ODEvent_Default<(error:Error, origin:NodeJS.UncaughtExceptionOrigin) => ODPromiseVoid>
"afterErrorHandling": ODEvent_Default<(error:Error, origin:NodeJS.UncaughtExceptionOrigin, message:ODError) => ODPromiseVoid>
//plugins
"afterPluginsLoaded": ODEvent_Default<(plugins:ODPluginManager_Default) => ODPromiseVoid>
"onPluginClassLoad": ODEvent_Default<(classes:ODPluginClassManager_Default, plugins:ODPluginManager_Default) => ODPromiseVoid>
"afterPluginClassesLoaded": ODEvent_Default<(classes:ODPluginClassManager_Default, plugins:ODPluginManager_Default) => ODPromiseVoid>
//flags
"onFlagLoad": ODEvent_Default<(flags:ODFlagManager_Default) => ODPromiseVoid>
"afterFlagsLoaded": ODEvent_Default<(flags:ODFlagManager_Default) => ODPromiseVoid>
"onFlagInit": ODEvent_Default<(flags:ODFlagManager_Default) => ODPromiseVoid>
"afterFlagsInitiated": ODEvent_Default<(flags:ODFlagManager_Default) => ODPromiseVoid>
//progress bars
"onProgressBarRendererLoad": ODEvent_Default<(renderers:ODProgressBarRendererManager_Default) => ODPromiseVoid>
"afterProgressBarRenderersLoaded": ODEvent_Default<(renderers:ODProgressBarRendererManager_Default) => ODPromiseVoid>
"onProgressBarLoad": ODEvent_Default<(progressbars:ODProgressBarManager_Default) => ODPromiseVoid>
"afterProgressBarsLoaded": ODEvent_Default<(progressbars:ODProgressBarManager_Default) => ODPromiseVoid>
//configs
"onConfigLoad": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid>
"afterConfigsLoaded": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid>
"onConfigInit": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid>
"afterConfigsInitiated": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid>
//databases
"onDatabaseLoad": ODEvent_Default<(databases:ODDatabaseManager_Default) => ODPromiseVoid>
"afterDatabasesLoaded": ODEvent_Default<(databases:ODDatabaseManager_Default) => ODPromiseVoid>
"onDatabaseInit": ODEvent_Default<(databases:ODDatabaseManager_Default) => ODPromiseVoid>
"afterDatabasesInitiated": ODEvent_Default<(databases:ODDatabaseManager_Default) => ODPromiseVoid>
//languages
"onLanguageLoad": ODEvent_Default<(languages:ODLanguageManager_Default) => ODPromiseVoid>
"afterLanguagesLoaded": ODEvent_Default<(languages:ODLanguageManager_Default) => ODPromiseVoid>
"onLanguageInit": ODEvent_Default<(languages:ODLanguageManager_Default) => ODPromiseVoid>
"afterLanguagesInitiated": ODEvent_Default<(languages:ODLanguageManager_Default) => ODPromiseVoid>
"onLanguageSelect": ODEvent_Default<(languages:ODLanguageManager_Default) => ODPromiseVoid>
"afterLanguagesSelected": ODEvent_Default<(main:ODLanguage|null, backup:ODLanguage|null, languages:ODLanguageManager_Default) => ODPromiseVoid>
//sessions
"onSessionLoad": ODEvent_Default<(languages:ODSessionManager_Default) => ODPromiseVoid>
"afterSessionsLoaded": ODEvent_Default<(languages:ODSessionManager_Default) => ODPromiseVoid>
//config checkers
"onCheckerLoad": ODEvent_Default<(checkers:ODCheckerManager_Default) => ODPromiseVoid>
"afterCheckersLoaded": ODEvent_Default<(checkers:ODCheckerManager_Default) => ODPromiseVoid>
"onCheckerFunctionLoad": ODEvent_Default<(functions:ODCheckerFunctionManager_Default, checkers:ODCheckerManager_Default) => ODPromiseVoid>
"afterCheckerFunctionsLoaded": ODEvent_Default<(functions:ODCheckerFunctionManager_Default, checkers:ODCheckerManager_Default) => ODPromiseVoid>
"onCheckerExecute": ODEvent_Default<(checkers:ODCheckerManager_Default) => ODPromiseVoid>
"afterCheckersExecuted": ODEvent_Default<(result:ODCheckerResult, checkers:ODCheckerManager_Default) => ODPromiseVoid>
"onCheckerTranslationLoad": ODEvent_Default<(translations:ODCheckerTranslationRegister_Default, enabled:boolean, checkers:ODCheckerManager_Default) => ODPromiseVoid>
"afterCheckerTranslationsLoaded": ODEvent_Default<(translations:ODCheckerTranslationRegister_Default, checkers:ODCheckerManager_Default) => ODPromiseVoid>
"onCheckerRender": ODEvent_Default<(renderer:ODCheckerRenderer_Default, checkers:ODCheckerManager_Default) => ODPromiseVoid>
"afterCheckersRendered": ODEvent_Default<(renderer:ODCheckerRenderer_Default, checkers:ODCheckerManager_Default) => ODPromiseVoid>
"onCheckerQuit": ODEvent_Default<(checkers:ODCheckerManager_Default) => ODPromiseVoid>
//plugin loading before client
"onPluginBeforeClientLoad": ODEvent_Default<() => ODPromiseVoid>,
"afterPluginBeforeClientLoaded": ODEvent_Default<() => ODPromiseVoid>,
//client configuration
"onClientLoad": ODEvent_Default<(client:ODClientManager_Default) => ODPromiseVoid>
"afterClientLoaded": ODEvent_Default<(client:ODClientManager_Default) => ODPromiseVoid>
"onClientInit": ODEvent_Default<(client:ODClientManager_Default) => ODPromiseVoid>
"afterClientInitiated": ODEvent_Default<(client:ODClientManager_Default) => ODPromiseVoid>
"onClientReady": ODEvent_Default<(client:ODClientManager_Default) => ODPromiseVoid>
"afterClientReady": ODEvent_Default<(client:ODClientManager_Default) => ODPromiseVoid>
"onClientActivityLoad": ODEvent_Default<(activity:ODClientActivityManager, client:ODClientManager_Default) => ODPromiseVoid>
"afterClientActivityLoaded": ODEvent_Default<(activity:ODClientActivityManager, client:ODClientManager_Default) => ODPromiseVoid>
"onClientActivityInit": ODEvent_Default<(activity:ODClientActivityManager, client:ODClientManager_Default) => ODPromiseVoid>
"afterClientActivityInitiated": ODEvent_Default<(activity:ODClientActivityManager, client:ODClientManager_Default) => ODPromiseVoid>
//priority levels
"onPriorityLoad": ODEvent_Default<(priorities:ODPriorityManager_Default) => ODPromiseVoid>
"afterPrioritiesLoaded": ODEvent_Default<(priorities:ODPriorityManager_Default) => ODPromiseVoid>
//client slash commands
"onSlashCommandLoad": ODEvent_Default<(slash:ODSlashCommandManager_Default, client:ODClientManager_Default) => ODPromiseVoid>
"afterSlashCommandsLoaded": ODEvent_Default<(slash:ODSlashCommandManager_Default, client:ODClientManager_Default) => ODPromiseVoid>
"onSlashCommandRegister": ODEvent_Default<(slash:ODSlashCommandManager_Default, client:ODClientManager_Default) => ODPromiseVoid>
"afterSlashCommandsRegistered": ODEvent_Default<(slash:ODSlashCommandManager_Default, client:ODClientManager_Default) => ODPromiseVoid>
//client context menus
"onContextMenuLoad": ODEvent_Default<(menu:ODContextMenuManager_Default, client:ODClientManager_Default) => ODPromiseVoid>
"afterContextMenusLoaded": ODEvent_Default<(menu:ODContextMenuManager_Default, client:ODClientManager_Default) => ODPromiseVoid>
"onContextMenuRegister": ODEvent_Default<(menu:ODContextMenuManager_Default, client:ODClientManager_Default) => ODPromiseVoid>
"afterContextMenusRegistered": ODEvent_Default<(menu:ODContextMenuManager_Default, client:ODClientManager_Default) => ODPromiseVoid>
//client text commands
"onTextCommandLoad": ODEvent_Default<(text:ODTextCommandManager_Default, client:ODClientManager_Default,) => ODPromiseVoid>
"afterTextCommandsLoaded": ODEvent_Default<(text:ODTextCommandManager_Default, client:ODClientManager_Default) => ODPromiseVoid>
//plugin loading before managers
"onPluginBeforeManagerLoad": ODEvent_Default<() => ODPromiseVoid>,
"afterPluginBeforeManagerLoaded": ODEvent_Default<() => ODPromiseVoid>,
//questions
"onQuestionLoad": ODEvent_Default<(questions:ODQuestionManager) => ODPromiseVoid>
"afterQuestionsLoaded": ODEvent_Default<(questions:ODQuestionManager) => ODPromiseVoid>
//options
"onOptionLoad": ODEvent_Default<(options:ODOptionManager) => ODPromiseVoid>
"afterOptionsLoaded": ODEvent_Default<(options:ODOptionManager) => ODPromiseVoid>
//panels
"onPanelLoad": ODEvent_Default<(panels:ODPanelManager) => ODPromiseVoid>
"afterPanelsLoaded": ODEvent_Default<(panels:ODPanelManager) => ODPromiseVoid>
"onPanelSpawn": ODEvent_Default<(panel:ODPanel) => ODPromiseVoid>
"afterPanelSpawned": ODEvent_Default<(panel:ODPanel) => ODPromiseVoid>
//tickets
"onTicketLoad": ODEvent_Default<(tickets:ODTicketManager) => ODPromiseVoid>
"afterTicketsLoaded": ODEvent_Default<(tickets:ODTicketManager) => ODPromiseVoid>
//ticket creation
"onTicketChannelCreation": ODEvent_Default<(option:ODTicketOption, user:discord.User) => ODPromiseVoid>
"afterTicketChannelCreated": ODEvent_Default<(option:ODTicketOption, channel:discord.GuildTextBasedChannel, user:discord.User) => ODPromiseVoid>
"onTicketChannelDeletion": ODEvent_Default<(ticket:ODTicket, channel:discord.GuildTextBasedChannel, user:discord.User) => ODPromiseVoid>
"afterTicketChannelDeleted": ODEvent_Default<(ticket:ODTicket, user:discord.User) => ODPromiseVoid>
"onTicketPermissionsCreated": ODEvent_Default<(option:ODTicketOption, permissions:ODPermissionManager_Default, channel:discord.GuildTextBasedChannel, user:discord.User) => ODPromiseVoid>
"afterTicketPermissionsCreated": ODEvent_Default<(option:ODTicketOption, permissions:ODPermissionManager_Default, channel:discord.GuildTextBasedChannel, user:discord.User) => ODPromiseVoid>
"onTicketMainMessageCreated": ODEvent_Default<(ticket:ODTicket, channel:discord.GuildTextBasedChannel, user:discord.User) => ODPromiseVoid>
"afterTicketMainMessageCreated": ODEvent_Default<(ticket:ODTicket, message:discord.Message, channel:discord.GuildTextBasedChannel, user:discord.User) => ODPromiseVoid>
//ticket actions
"onTicketCreate": ODEvent_Default<(creator:discord.User) => ODPromiseVoid>
"afterTicketCreated": ODEvent_Default<(ticket:ODTicket, creator:discord.User, channel:discord.GuildTextBasedChannel) => ODPromiseVoid>
"onTicketClose": ODEvent_Default<(ticket:ODTicket, closer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"afterTicketClosed": ODEvent_Default<(ticket:ODTicket, closer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"onTicketReopen": ODEvent_Default<(ticket:ODTicket, reopener:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"afterTicketReopened": ODEvent_Default<(ticket:ODTicket, reopener:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"onTicketDelete": ODEvent_Default<(ticket:ODTicket, deleter:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"afterTicketDeleted": ODEvent_Default<(ticket:ODTicket, deleter:discord.User, reason:string|null) => ODPromiseVoid>
"onTicketMove": ODEvent_Default<(ticket:ODTicket, mover:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"afterTicketMoved": ODEvent_Default<(ticket:ODTicket, mover:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"onTicketClaim": ODEvent_Default<(ticket:ODTicket, claimer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"afterTicketClaimed": ODEvent_Default<(ticket:ODTicket, claimer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"onTicketUnclaim": ODEvent_Default<(ticket:ODTicket, unclaimer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"afterTicketUnclaimed": ODEvent_Default<(ticket:ODTicket, unclaimer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"onTicketPin": ODEvent_Default<(ticket:ODTicket, pinner:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"afterTicketPinned": ODEvent_Default<(ticket:ODTicket, pinner:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"onTicketUnpin": ODEvent_Default<(ticket:ODTicket, unpinner:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"afterTicketUnpinned": ODEvent_Default<(ticket:ODTicket, unpinner:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"onTicketUserAdd": ODEvent_Default<(ticket:ODTicket, adder:discord.User, user:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"afterTicketUserAdded": ODEvent_Default<(ticket:ODTicket, adder:discord.User, user:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"onTicketUserRemove": ODEvent_Default<(ticket:ODTicket, remover:discord.User, user:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"afterTicketUserRemoved": ODEvent_Default<(ticket:ODTicket, remover:discord.User, user:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"onTicketRename": ODEvent_Default<(ticket:ODTicket, renamer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"afterTicketRenamed": ODEvent_Default<(ticket:ODTicket, renamer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => ODPromiseVoid>
"onTicketsClear": ODEvent_Default<(tickets:ODTicket[], clearer:discord.User, channel:discord.GuildTextBasedChannel, filter:ODTicketClearFilter) => ODPromiseVoid>
"afterTicketsCleared": ODEvent_Default<(tickets:ODTicket[], clearer:discord.User, channel:discord.GuildTextBasedChannel, filter:ODTicketClearFilter) => ODPromiseVoid>
"onTicketTopicChange": ODEvent_Default<(ticket:ODTicket, changer:discord.User, channel:discord.GuildTextBasedChannel, oldTopic:string, newTopic:string) => ODPromiseVoid>
"afterTicketTopicChanged": ODEvent_Default<(ticket:ODTicket, changer:discord.User, channel:discord.GuildTextBasedChannel, oldTopic:string, newTopic:string) => ODPromiseVoid>
"onTicketPriorityChange": ODEvent_Default<(ticket:ODTicket, changer:discord.User, channel:discord.GuildTextBasedChannel, oldPriority:ODPriorityLevel, newPriority:ODPriorityLevel, reason:string|null) => ODPromiseVoid>
"afterTicketPriorityChanged": ODEvent_Default<(ticket:ODTicket, changer:discord.User, channel:discord.GuildTextBasedChannel, oldPriority:ODPriorityLevel, newPriority:ODPriorityLevel, reason:string|null) => ODPromiseVoid>
"onTicketTransfer": ODEvent_Default<(ticket:ODTicket, changer:discord.User, channel:discord.GuildTextBasedChannel, oldCreator:discord.User, newCreator:discord.User, reason:string|null) => ODPromiseVoid>
"afterTicketTransferred": ODEvent_Default<(ticket:ODTicket, changer:discord.User, channel:discord.GuildTextBasedChannel, oldCreator:discord.User, newCreator:discord.User, reason:string|null) => ODPromiseVoid>
//roles
"onRoleLoad": ODEvent_Default<(roles:ODRoleManager) => ODPromiseVoid>
"afterRolesLoaded": ODEvent_Default<(roles:ODRoleManager) => ODPromiseVoid>
"onRoleUpdate": ODEvent_Default<(user:discord.User,role:ODRole) => ODPromiseVoid>
"afterRolesUpdated": ODEvent_Default<(user:discord.User,role:ODRole) => ODPromiseVoid>
//blacklist
"onBlacklistLoad": ODEvent_Default<(blacklist:ODBlacklistManager) => ODPromiseVoid>
"afterBlacklistLoaded": ODEvent_Default<(blacklist:ODBlacklistManager) => ODPromiseVoid>
//transcripts
"onTranscriptCompilerLoad": ODEvent_Default<(transcripts:ODTranscriptManager_Default) => ODPromiseVoid>
"afterTranscriptCompilersLoaded": ODEvent_Default<(transcripts:ODTranscriptManager_Default) => ODPromiseVoid>
"onTranscriptHistoryLoad": ODEvent_Default<(transcripts:ODTranscriptManager_Default) => ODPromiseVoid>
"afterTranscriptHistoryLoaded": ODEvent_Default<(transcripts:ODTranscriptManager_Default) => ODPromiseVoid>
//transcript creation
"onTranscriptCreate": ODEvent_Default<(transcripts:ODTranscriptManager_Default,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => ODPromiseVoid>
"afterTranscriptCreated": ODEvent_Default<(transcripts:ODTranscriptManager_Default,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => ODPromiseVoid>
"onTranscriptInit": ODEvent_Default<(transcripts:ODTranscriptManager_Default,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => ODPromiseVoid>
"afterTranscriptInitiated": ODEvent_Default<(transcripts:ODTranscriptManager_Default,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => ODPromiseVoid>
"onTranscriptCompile": ODEvent_Default<(transcripts:ODTranscriptManager_Default,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => ODPromiseVoid>
"afterTranscriptCompiled": ODEvent_Default<(transcripts:ODTranscriptManager_Default,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => ODPromiseVoid>
"onTranscriptReady": ODEvent_Default<(transcripts:ODTranscriptManager_Default,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => ODPromiseVoid>
"afterTranscriptReady": ODEvent_Default<(transcripts:ODTranscriptManager_Default,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => ODPromiseVoid>
//plugin loading before builders
"onPluginBeforeBuilderLoad": ODEvent_Default<() => ODPromiseVoid>,
"afterPluginBeforeBuilderLoaded": ODEvent_Default<() => ODPromiseVoid>,
//builders
"onButtonBuilderLoad": ODEvent_Default<(buttons:ODButtonManager_Default, builders:ODBuilderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"afterButtonBuildersLoaded": ODEvent_Default<(buttons:ODButtonManager_Default, builders:ODBuilderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"onDropdownBuilderLoad": ODEvent_Default<(dropdowns:ODDropdownManager_Default, builders:ODBuilderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"afterDropdownBuildersLoaded": ODEvent_Default<(dropdowns:ODDropdownManager_Default, builders:ODBuilderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"onFileBuilderLoad": ODEvent_Default<(files:ODFileManager_Default, builders:ODBuilderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"afterFileBuildersLoaded": ODEvent_Default<(files:ODFileManager_Default, builders:ODBuilderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"onEmbedBuilderLoad": ODEvent_Default<(embeds:ODEmbedManager_Default, builders:ODBuilderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"afterEmbedBuildersLoaded": ODEvent_Default<(embeds:ODEmbedManager_Default, builders:ODBuilderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"onMessageBuilderLoad": ODEvent_Default<(messages:ODMessageManager_Default, builders:ODBuilderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"afterMessageBuildersLoaded": ODEvent_Default<(messages:ODMessageManager_Default, builders:ODBuilderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"onModalBuilderLoad": ODEvent_Default<(modals:ODModalManager_Default, builders:ODBuilderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"afterModalBuildersLoaded": ODEvent_Default<(modals:ODModalManager_Default, builders:ODBuilderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
//plugin loading before responders
"onPluginBeforeResponderLoad": ODEvent_Default<() => ODPromiseVoid>,
"afterPluginBeforeResponderLoaded": ODEvent_Default<() => ODPromiseVoid>,
//responders
"onCommandResponderLoad": ODEvent_Default<(commands:ODCommandResponderManager_Default, responders:ODResponderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"afterCommandRespondersLoaded": ODEvent_Default<(commands:ODCommandResponderManager_Default, responders:ODResponderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"onButtonResponderLoad": ODEvent_Default<(buttons:ODButtonResponderManager_Default, responders:ODResponderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"afterButtonRespondersLoaded": ODEvent_Default<(buttons:ODButtonResponderManager_Default, responders:ODResponderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"onDropdownResponderLoad": ODEvent_Default<(dropdowns:ODDropdownResponderManager_Default, responders:ODResponderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"afterDropdownRespondersLoaded": ODEvent_Default<(dropdowns:ODDropdownResponderManager_Default, responders:ODResponderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"onModalResponderLoad": ODEvent_Default<(modals:ODModalResponderManager_Default, responders:ODResponderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"afterModalRespondersLoaded": ODEvent_Default<(modals:ODModalResponderManager_Default, responders:ODResponderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"onContextMenuResponderLoad": ODEvent_Default<(menus:ODContextMenuResponderManager_Default, responders:ODResponderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"afterContextMenuRespondersLoaded": ODEvent_Default<(menus:ODContextMenuResponderManager_Default, responders:ODResponderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"onAutocompleteResponderLoad": ODEvent_Default<(autocomplete:ODAutocompleteResponderManager_Default, responders:ODResponderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
"afterAutocompleteRespondersLoaded": ODEvent_Default<(autocomplete:ODAutocompleteResponderManager_Default, responders:ODResponderManager_Default, actions:ODActionManager_Default) => ODPromiseVoid>
//plugin loading before finalizations
"onPluginBeforeFinalizationLoad": ODEvent_Default<() => ODPromiseVoid>,
"afterPluginBeforeFinalizationLoaded": ODEvent_Default<() => ODPromiseVoid>,
//actions
"onActionLoad": ODEvent_Default<(actions:ODActionManager_Default) => ODPromiseVoid>
"afterActionsLoaded": ODEvent_Default<(actions:ODActionManager_Default) => ODPromiseVoid>
//verifybars
"onVerifyBarLoad": ODEvent_Default<(verifybars:ODVerifyBarManager_Default) => ODPromiseVoid>
"afterVerifyBarsLoaded": ODEvent_Default<(verifybars:ODVerifyBarManager_Default) => ODPromiseVoid>
//permissions
"onPermissionLoad": ODEvent_Default<(permissions:ODPermissionManager_Default) => ODPromiseVoid>
"afterPermissionsLoaded": ODEvent_Default<(permissions:ODPermissionManager_Default) => ODPromiseVoid>
//posts
"onPostLoad": ODEvent_Default<(posts:ODPostManager_Default) => ODPromiseVoid>
"afterPostsLoaded": ODEvent_Default<(posts:ODPostManager_Default) => ODPromiseVoid>
"onPostInit": ODEvent_Default<(posts:ODPostManager_Default) => ODPromiseVoid>
"afterPostsInitiated": ODEvent_Default<(posts:ODPostManager_Default) => ODPromiseVoid>
//cooldowns
"onCooldownLoad": ODEvent_Default<(cooldowns:ODCooldownManager_Default) => ODPromiseVoid>
"afterCooldownsLoaded": ODEvent_Default<(cooldowns:ODCooldownManager_Default) => ODPromiseVoid>
"onCooldownInit": ODEvent_Default<(cooldowns:ODCooldownManager_Default) => ODPromiseVoid>
"afterCooldownsInitiated": ODEvent_Default<(cooldowns:ODCooldownManager_Default) => ODPromiseVoid>
//help menu
"onHelpMenuCategoryLoad": ODEvent_Default<(menu:ODHelpMenuManager_Default) => ODPromiseVoid>
"afterHelpMenuCategoriesLoaded": ODEvent_Default<(menu:ODHelpMenuManager_Default) => ODPromiseVoid>
"onHelpMenuComponentLoad": ODEvent_Default<(menu:ODHelpMenuManager_Default) => ODPromiseVoid>
"afterHelpMenuComponentsLoaded": ODEvent_Default<(menu:ODHelpMenuManager_Default) => ODPromiseVoid>
//stats
"onStatScopeLoad": ODEvent_Default<(stats:ODStatsManager_Default) => ODPromiseVoid>
"afterStatScopesLoaded": ODEvent_Default<(stats:ODStatsManager_Default) => ODPromiseVoid>
"onStatLoad": ODEvent_Default<(stats:ODStatsManager_Default) => ODPromiseVoid>
"afterStatsLoaded": ODEvent_Default<(stats:ODStatsManager_Default) => ODPromiseVoid>
"onStatInit": ODEvent_Default<(stats:ODStatsManager_Default) => ODPromiseVoid>
"afterStatsInitiated": ODEvent_Default<(stats:ODStatsManager_Default) => ODPromiseVoid>
//plugin loading before code
"onPluginBeforeCodeLoad": ODEvent_Default<() => ODPromiseVoid>,
"afterPluginBeforeCodeLoaded": ODEvent_Default<() => ODPromiseVoid>,
//code
"onCodeLoad": ODEvent_Default<(code:ODCodeManager_Default) => ODPromiseVoid>
"afterCodeLoaded": ODEvent_Default<(code:ODCodeManager_Default) => ODPromiseVoid>
"onCodeExecute": ODEvent_Default<(code:ODCodeManager_Default) => ODPromiseVoid>
"afterCodeExecuted": ODEvent_Default<(code:ODCodeManager_Default) => ODPromiseVoid>
//livestatus
"onLiveStatusSourceLoad": ODEvent_Default<(livestatus:ODLiveStatusManager_Default) => ODPromiseVoid>
"afterLiveStatusSourcesLoaded": ODEvent_Default<(livestatus:ODLiveStatusManager_Default) => ODPromiseVoid>
//startscreen
"onStartScreenLoad": ODEvent_Default<(startscreen:ODStartScreenManager_Default) => ODPromiseVoid>
"afterStartScreensLoaded": ODEvent_Default<(startscreen:ODStartScreenManager_Default) => ODPromiseVoid>
"onStartScreenRender": ODEvent_Default<(startscreen:ODStartScreenManager_Default) => ODPromiseVoid>
"afterStartScreensRendered": ODEvent_Default<(startscreen:ODStartScreenManager_Default) => ODPromiseVoid>
//ready
"beforeReadyForUsage": ODEvent_Default<() => ODPromiseVoid>
"onReadyForUsage": ODEvent_Default<() => ODPromiseVoid>
}
/**## ODEventManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODEvent class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.events`!
*/
export class ODEventManager_Default extends ODEventManager {
get<StartScreenId extends keyof ODEventIds_Default>(id:StartScreenId): ODEventIds_Default[StartScreenId]
get(id:ODValidId): ODEvent|null
get(id:ODValidId): ODEvent|null {
return super.get(id)
}
remove<StartScreenId extends keyof ODEventIds_Default>(id:StartScreenId): ODEventIds_Default[StartScreenId]
remove(id:ODValidId): ODEvent|null
remove(id:ODValidId): ODEvent|null {
return super.remove(id)
}
exists(id:keyof ODEventIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODEventManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODEvent class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.events`!
*/
export class ODEvent_Default<Callback extends ((...args:any) => ODPromiseVoid)> extends ODEvent {
listen(callback:Callback): void {
return super.listen(callback)
}
listenOnce(callback:Callback): void {
return super.listenOnce(callback)
}
wait(): Promise<Parameters<Callback>>
wait(): Promise<any[]> {
return super.wait()
}
emit(params:Parameters<Callback>): Promise<void> {
return super.emit(params)
}
}
-57
View File
@@ -1,57 +0,0 @@
///////////////////////////////////////
//DEFAULT PROCESS MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODFlagManager, ODFlag } from "../modules/flag"
/**## ODFlagManagerIds_Default `interface`
* This interface is a list of ids available in the `ODFlagManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODFlagManagerIds_Default {
"opendiscord:no-migration":ODFlag,
"opendiscord:dev-config":ODFlag,
"opendiscord:dev-database":ODFlag,
"opendiscord:debug":ODFlag,
"opendiscord:crash":ODFlag,
"opendiscord:no-transcripts":ODFlag,
"opendiscord:no-checker":ODFlag,
"opendiscord:checker":ODFlag,
"opendiscord:no-easter":ODFlag,
"opendiscord:no-plugins":ODFlag,
"opendiscord:soft-plugins":ODFlag,
"opendiscord:force-slash-update":ODFlag,
"opendiscord:no-compile":ODFlag,
"opendiscord:compile-only":ODFlag,
"opendiscord:silent":ODFlag,
"opendiscord:cli":ODFlag,
}
/**## ODFlagManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODFlagManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.flags`!
*/
export class ODFlagManager_Default extends ODFlagManager {
get<FlagId extends keyof ODFlagManagerIds_Default>(id:FlagId): ODFlagManagerIds_Default[FlagId]
get(id:ODValidId): ODFlag|null
get(id:ODValidId): ODFlag|null {
return super.get(id)
}
remove<FlagId extends keyof ODFlagManagerIds_Default>(id:FlagId): ODFlagManagerIds_Default[FlagId]
remove(id:ODValidId): ODFlag|null
remove(id:ODValidId): ODFlag|null {
return super.remove(id)
}
exists(id:keyof ODFlagManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-338
View File
@@ -1,338 +0,0 @@
///////////////////////////////////////
//DEFAULT HELP MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODHelpMenuCategory, ODHelpMenuCommandComponent, ODHelpMenuComponent, ODHelpMenuManager } from "../modules/helpmenu"
/** (CONTRIBUTOR GUIDE) HOW TO ADD NEW COMMANDS?
* - Register the command in loadAllSlashCommands() & loadAllTextCommands() in (./src/data/framework/commandLoader.ts)
* - Add autocomplete for the command in OD(Slash/Text)CommandManagerIds_Default in (./src/core/api/defaults/client.ts)
* - Add the command to the help menu in (./src/data/framework/helpMenuLoader.ts)
* - If required, new config variables should be added (incl. logs, dm-logs & permissions).
* - Update the Open Ticket Documentation.
* - If the command contains complex logic or can be executed from a button/dropdown, it should be placed inside an `ODAction`.
* - Check all files, test the bot carefully & try a lot of different scenario's with different settings.
*/
/**## ODHelpMenuManagerIds_Default `interface`
* This interface is a list of ids available in the `ODHelpMenuManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerIds_Default {
"opendiscord:general":ODHelpMenuCategory_DefaultGeneral,
"opendiscord:ticket-basic":ODHelpMenuCategory_DefaultTicketBasic,
"opendiscord:ticket-advanced":ODHelpMenuCategory_DefaultTicketAdvanced,
"opendiscord:ticket-user":ODHelpMenuCategory_DefaultTicketUser,
"opendiscord:admin":ODHelpMenuCategory_DefaultAdmin,
"opendiscord:advanced":ODHelpMenuCategory_DefaultAdvanced,
"opendiscord:extra":ODHelpMenuCategory_DefaultExtra
}
/**## ODHelpMenuManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODHelpMenuManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.helpmenu`!
*/
export class ODHelpMenuManager_Default extends ODHelpMenuManager {
get<HelpMenuCategoryId extends keyof ODHelpMenuManagerIds_Default>(id:HelpMenuCategoryId): ODHelpMenuManagerIds_Default[HelpMenuCategoryId]
get(id:ODValidId): ODHelpMenuCategory|null
get(id:ODValidId): ODHelpMenuCategory|null {
return super.get(id)
}
remove<HelpMenuCategoryId extends keyof ODHelpMenuManagerIds_Default>(id:HelpMenuCategoryId): ODHelpMenuManagerIds_Default[HelpMenuCategoryId]
remove(id:ODValidId): ODHelpMenuCategory|null
remove(id:ODValidId): ODHelpMenuCategory|null {
return super.remove(id)
}
exists(id:keyof ODHelpMenuManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODHelpMenuManagerCategoryIds_DefaultGeneral `type`
* This interface is a list of ids available in the `ODHelpMenuCategory_DefaultGeneral` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultGeneral {
"opendiscord:help":ODHelpMenuCommandComponent,
"opendiscord:ticket":ODHelpMenuCommandComponent|null
}
/**## ODHelpMenuCategory_DefaultGeneral `default_class`
* This is a special class that adds type definitions & typescript to the ODHelpMenuManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:general` category in `opendiscord.helpmenu`!
*/
export class ODHelpMenuCategory_DefaultGeneral extends ODHelpMenuCategory {
get<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultGeneral>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultGeneral[HelpMenuCategoryId]
get(id:ODValidId): ODHelpMenuComponent|null
get(id:ODValidId): ODHelpMenuComponent|null {
return super.get(id)
}
remove<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultGeneral>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultGeneral[HelpMenuCategoryId]
remove(id:ODValidId): ODHelpMenuComponent|null
remove(id:ODValidId): ODHelpMenuComponent|null {
return super.remove(id)
}
exists(id:keyof ODHelpMenuManagerCategoryIds_DefaultGeneral): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODHelpMenuManagerCategoryIds_DefaultTicketBasic `type`
* This interface is a list of ids available in the `ODHelpMenuCategory_DefaultTicketBasic` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultTicketBasic {
"opendiscord:close":ODHelpMenuCommandComponent,
"opendiscord:delete":ODHelpMenuCommandComponent,
"opendiscord:reopen":ODHelpMenuCommandComponent
}
/**## ODHelpMenuCategory_DefaultTicketBasic `default_class`
* This is a special class that adds type definitions & typescript to the ODHelpMenuManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:ticket` category in `opendiscord.helpmenu`!
*/
export class ODHelpMenuCategory_DefaultTicketBasic extends ODHelpMenuCategory {
get<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultTicketBasic>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultTicketBasic[HelpMenuCategoryId]
get(id:ODValidId): ODHelpMenuComponent|null
get(id:ODValidId): ODHelpMenuComponent|null {
return super.get(id)
}
remove<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultTicketBasic>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultTicketBasic[HelpMenuCategoryId]
remove(id:ODValidId): ODHelpMenuComponent|null
remove(id:ODValidId): ODHelpMenuComponent|null {
return super.remove(id)
}
exists(id:keyof ODHelpMenuManagerCategoryIds_DefaultTicketBasic): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODHelpMenuManagerCategoryIds_DefaultTicketAdvanced `type`
* This interface is a list of ids available in the `ODHelpMenuCategory_DefaultTicketAdvanced` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultTicketAdvanced {
"opendiscord:pin":ODHelpMenuCommandComponent,
"opendiscord:unpin":ODHelpMenuCommandComponent,
"opendiscord:move":ODHelpMenuCommandComponent,
"opendiscord:rename":ODHelpMenuCommandComponent
}
/**## ODHelpMenuCategory_DefaultTicketAdvanced `default_class`
* This is a special class that adds type definitions & typescript to the ODHelpMenuManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:ticket` category in `opendiscord.helpmenu`!
*/
export class ODHelpMenuCategory_DefaultTicketAdvanced extends ODHelpMenuCategory {
get<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultTicketAdvanced>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultTicketAdvanced[HelpMenuCategoryId]
get(id:ODValidId): ODHelpMenuComponent|null
get(id:ODValidId): ODHelpMenuComponent|null {
return super.get(id)
}
remove<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultTicketAdvanced>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultTicketAdvanced[HelpMenuCategoryId]
remove(id:ODValidId): ODHelpMenuComponent|null
remove(id:ODValidId): ODHelpMenuComponent|null {
return super.remove(id)
}
exists(id:keyof ODHelpMenuManagerCategoryIds_DefaultTicketAdvanced): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODHelpMenuManagerCategoryIds_DefaultTicketUser `type`
* This interface is a list of ids available in the `ODHelpMenuCategory_DefaultTicketUser` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultTicketUser {
"opendiscord:claim":ODHelpMenuCommandComponent,
"opendiscord:unclaim":ODHelpMenuCommandComponent,
"opendiscord:add":ODHelpMenuCommandComponent,
"opendiscord:remove":ODHelpMenuCommandComponent,
"opendiscord:transfer":ODHelpMenuCommandComponent,
}
/**## ODHelpMenuCategory_DefaultTicketUser `default_class`
* This is a special class that adds type definitions & typescript to the ODHelpMenuManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:ticket` category in `opendiscord.helpmenu`!
*/
export class ODHelpMenuCategory_DefaultTicketUser extends ODHelpMenuCategory {
get<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultTicketUser>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultTicketUser[HelpMenuCategoryId]
get(id:ODValidId): ODHelpMenuComponent|null
get(id:ODValidId): ODHelpMenuComponent|null {
return super.get(id)
}
remove<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultTicketUser>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultTicketUser[HelpMenuCategoryId]
remove(id:ODValidId): ODHelpMenuComponent|null
remove(id:ODValidId): ODHelpMenuComponent|null {
return super.remove(id)
}
exists(id:keyof ODHelpMenuManagerCategoryIds_DefaultTicketUser): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODHelpMenuManagerCategoryIds_DefaultAdmin `type`
* This interface is a list of ids available in the `ODHelpMenuCategory_DefaultAdmin` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultAdmin {
"opendiscord:panel":ODHelpMenuCommandComponent,
"opendiscord:blacklist-view":ODHelpMenuCommandComponent,
"opendiscord:blacklist-add":ODHelpMenuCommandComponent,
"opendiscord:blacklist-remove":ODHelpMenuCommandComponent,
"opendiscord:blacklist-get":ODHelpMenuCommandComponent
}
/**## ODHelpMenuCategory_DefaultAdmin `default_class`
* This is a special class that adds type definitions & typescript to the ODHelpMenuManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:admin` category in `opendiscord.helpmenu`!
*/
export class ODHelpMenuCategory_DefaultAdmin extends ODHelpMenuCategory {
get<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultAdmin>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultAdmin[HelpMenuCategoryId]
get(id:ODValidId): ODHelpMenuComponent|null
get(id:ODValidId): ODHelpMenuComponent|null {
return super.get(id)
}
remove<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultAdmin>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultAdmin[HelpMenuCategoryId]
remove(id:ODValidId): ODHelpMenuComponent|null
remove(id:ODValidId): ODHelpMenuComponent|null {
return super.remove(id)
}
exists(id:keyof ODHelpMenuManagerCategoryIds_DefaultAdmin): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODHelpMenuManagerCategoryIds_DefaultAdvanced `type`
* This interface is a list of ids available in the `ODHelpMenuCategory_DefaultAdvanced` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultAdvanced {
"opendiscord:stats-global":ODHelpMenuCommandComponent,
"opendiscord:stats-reset":ODHelpMenuCommandComponent,
"opendiscord:stats-ticket":ODHelpMenuCommandComponent,
"opendiscord:stats-user":ODHelpMenuCommandComponent,
"opendiscord:autoclose-disable":ODHelpMenuCommandComponent,
"opendiscord:autoclose-enable":ODHelpMenuCommandComponent,
"opendiscord:autodelete-disable":ODHelpMenuCommandComponent,
"opendiscord:autodelete-enable":ODHelpMenuCommandComponent,
"opendiscord:topic-set":ODHelpMenuCommandComponent,
"opendiscord:priority-set":ODHelpMenuCommandComponent,
}
/**## ODHelpMenuCategory_DefaultAdvanced `default_class`
* This is a special class that adds type definitions & typescript to the ODHelpMenuManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:advanced` category in `opendiscord.helpmenu`!
*/
export class ODHelpMenuCategory_DefaultAdvanced extends ODHelpMenuCategory {
get<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultAdvanced>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultAdvanced[HelpMenuCategoryId]
get(id:ODValidId): ODHelpMenuComponent|null
get(id:ODValidId): ODHelpMenuComponent|null {
return super.get(id)
}
remove<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultAdvanced>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultAdvanced[HelpMenuCategoryId]
remove(id:ODValidId): ODHelpMenuComponent|null
remove(id:ODValidId): ODHelpMenuComponent|null {
return super.remove(id)
}
exists(id:keyof ODHelpMenuManagerCategoryIds_DefaultAdvanced): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODHelpMenuManagerCategoryIds_DefaultExtra `type`
* This interface is a list of ids available in the `ODHelpMenuCategory_DefaultExtra` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultExtra {}
/**## ODHelpMenuCategory_DefaultExtra `default_class`
* This is a special class that adds type definitions & typescript to the ODHelpMenuManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:general` category in `opendiscord.helpmenu`!
*/
export class ODHelpMenuCategory_DefaultExtra extends ODHelpMenuCategory {
get<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultExtra>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultExtra[HelpMenuCategoryId]
get(id:ODValidId): ODHelpMenuComponent|null
get(id:ODValidId): ODHelpMenuComponent|null {
return super.get(id)
}
remove<HelpMenuCategoryId extends keyof ODHelpMenuManagerCategoryIds_DefaultExtra>(id:HelpMenuCategoryId): ODHelpMenuManagerCategoryIds_DefaultExtra[HelpMenuCategoryId]
remove(id:ODValidId): ODHelpMenuComponent|null
remove(id:ODValidId): ODHelpMenuComponent|null {
return super.remove(id)
}
exists(id:keyof ODHelpMenuManagerCategoryIds_DefaultExtra): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-31
View File
@@ -1,31 +0,0 @@
///////////////////////////////////////
//DEFAULT PERMISSION MODULE
///////////////////////////////////////
import { ODDebugger } from "../modules/console"
import { ODPermissionManager } from "../modules/permission"
import { ODClientManager_Default } from "./client"
/**## ODPermissionManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODPermissionManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.permissions`!
*/
export class ODPermissionManager_Default extends ODPermissionManager {
constructor(debug:ODDebugger,client:ODClientManager_Default){
super(debug,client,true)
}
}
/**## ODPermissionEmbedType `type`
* This type contains all types available in the `opendiscord:no-permissions` embed.
*/
export type ODPermissionEmbedType = (
"developer"|
"owner"|
"admin"|
"moderator"|
"support"|
"member"|
"discord-administrator"
)
-77
View File
@@ -1,77 +0,0 @@
///////////////////////////////////////
//DEFAULT POST MODULE
///////////////////////////////////////
import { ODValidId, ODManagerData } from "../modules/base"
import { ODPlugin, ODPluginClassManager, ODPluginManager } from "../modules/plugin"
/**## ODPluginManagerIds_Default `interface`
* This interface is a list of ids available in the `ODPluginManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODPluginManagerIds_Default {}
/**## ODPluginManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODPluginManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.plugins`!
*/
export class ODPluginManager_Default extends ODPluginManager {
declare classes: ODPluginClassManager_Default
get<PluginId extends keyof ODPluginManagerIds_Default>(id:PluginId): ODPluginManagerIds_Default[PluginId]
get(id:ODValidId): ODPlugin|null
get(id:ODValidId): ODPlugin|null {
return super.get(id)
}
remove<PluginId extends keyof ODPluginManagerIds_Default>(id:PluginId): ODPluginManagerIds_Default[PluginId]
remove(id:ODValidId): ODPlugin|null
remove(id:ODValidId): ODPlugin|null {
return super.remove(id)
}
exists(id:keyof ODPluginManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODPluginClassManagerIds_Default `interface`
* This interface is a list of ids available in the `ODPluginClassManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODPluginClassManagerIds_Default {}
/**## ODPluginClassManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODPluginClassManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.plugins.classes`!
*/
export class ODPluginClassManager_Default extends ODPluginClassManager {
get<PluginClassId extends keyof ODPluginClassManagerIds_Default>(id:PluginClassId): ODPluginClassManagerIds_Default[PluginClassId]
get(id:ODValidId): ODManagerData|null
get(id:ODValidId): ODManagerData|null {
return super.get(id)
}
remove<PluginClassId extends keyof ODPluginClassManagerIds_Default>(id:PluginClassId): ODPluginClassManagerIds_Default[PluginClassId]
remove(id:ODValidId): ODManagerData|null
remove(id:ODValidId): ODManagerData|null {
return super.remove(id)
}
exists(id:keyof ODPluginClassManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-44
View File
@@ -1,44 +0,0 @@
///////////////////////////////////////
//DEFAULT POST MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODPost, ODPostManager } from "../modules/post"
import * as discord from "discord.js"
/**## ODPostManagerIds_Default `interface`
* This interface is a list of ids available in the `ODPostManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODPostManagerIds_Default {
"opendiscord:logs":ODPost<discord.GuildTextBasedChannel>|null,
"opendiscord:transcripts":ODPost<discord.GuildTextBasedChannel>|null
}
/**## ODPostManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODPostManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.code`!
*/
export class ODPostManager_Default extends ODPostManager {
get<PostId extends keyof ODPostManagerIds_Default>(id:PostId): ODPostManagerIds_Default[PostId]
get(id:ODValidId): ODPost<discord.GuildBasedChannel>|null
get(id:ODValidId): ODPost<discord.GuildBasedChannel>|null {
return super.get(id)
}
remove<PostId extends keyof ODPostManagerIds_Default>(id:PostId): ODPostManagerIds_Default[PostId]
remove(id:ODValidId): ODPost<discord.GuildBasedChannel>|null
remove(id:ODValidId): ODPost<discord.GuildBasedChannel>|null {
return super.remove(id)
}
exists(id:keyof ODPostManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-171
View File
@@ -1,171 +0,0 @@
///////////////////////////////////////
//DEFAULT PROGRESS BAR MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODValidConsoleColor } from "../modules/console"
import { ODManualProgressBar, ODProgressBar, ODProgressBarManager, ODProgressBarRenderer, ODProgressBarRendererManager } from "../modules/progressbar"
import ansis from "ansis"
/**## ODProgressBarRenderer_DefaultSettingsLabel `type`
* All available label types for the default progress bar renderer
*/
export type ODProgressBarRenderer_DefaultSettingsLabel = "value"|"percentage"|"fraction"|"time-ms"|"time-sec"|"time-min"
/**## ODProgressBarRenderer_DefaultSettings `interface`
* This interface contains the settings for the default progress bar renderer.
*/
export interface ODProgressBarRenderer_DefaultSettings {
/**The color of the progress bar border. */
borderColor:ODValidConsoleColor|"openticket",
/**The color of the progress bar (filled side). */
filledBarColor:ODValidConsoleColor|"openticket",
/**The color of the progress bar (empty side). */
emptyBarColor:ODValidConsoleColor|"openticket",
/**The color of the text before the progress bar. */
prefixColor:ODValidConsoleColor|"openticket",
/**The color of the text after the progress bar. */
suffixColor:ODValidConsoleColor|"openticket",
/**The color of the progress bar label. */
labelColor:ODValidConsoleColor|"openticket",
/**The character used in the left border. */
leftBorderChar:string,
/**The character used in the right border. */
rightBorderChar:string,
/**The character used in the filled side of the progress bar. */
filledBarChar:string,
/**The character used in the empty side of the progress bar. */
emptyBarChar:string,
/**The label type. (will show a number related to the progress) */
labelType:ODProgressBarRenderer_DefaultSettingsLabel,
/**The position of the label. */
labelPosition:"start"|"end",
/**The width of the bar. (50 characters by default) */
barWidth:number,
/**Show the bar. */
showBar:boolean,
/**Show the label. */
showLabel:boolean,
/**Show the border. */
showBorder:boolean,
}
export class ODProgressBarRenderer_Default extends ODProgressBarRenderer<ODProgressBarRenderer_DefaultSettings> {
constructor(id:ODValidId,settings:ODProgressBarRenderer_DefaultSettings){
super(id,(settings,min,max,value,rawPrefix,rawSuffix) => {
const percentage = (value-min)/(max-min)
const barLevel = Math.round(percentage*settings.barWidth)
const borderAnsis = (settings.borderColor == "openticket") ? ansis.hex("#f8ba00") : ansis[settings.borderColor]
const filledBarAnsis = (settings.filledBarColor == "openticket") ? ansis.hex("#f8ba00") : ansis[settings.filledBarColor]
const emptyBarAnsis = (settings.emptyBarColor == "openticket") ? ansis.hex("#f8ba00") : ansis[settings.emptyBarColor]
const labelAnsis = (settings.labelColor == "openticket") ? ansis.hex("#f8ba00") : ansis[settings.labelColor]
const prefixAnsis = (settings.prefixColor == "openticket") ? ansis.hex("#f8ba00") : ansis[settings.prefixColor]
const suffixAnsis = (settings.suffixColor == "openticket") ? ansis.hex("#f8ba00") : ansis[settings.suffixColor]
const leftBorder = (settings.showBorder) ? borderAnsis(settings.leftBorderChar) : ""
const rightBorder = (settings.showBorder) ? borderAnsis(settings.rightBorderChar) : ""
const bar = (settings.showBar) ? filledBarAnsis(settings.filledBarChar.repeat(barLevel))+emptyBarAnsis(settings.emptyBarChar.repeat(settings.barWidth-barLevel)) : ""
const prefix = (rawPrefix) ? prefixAnsis(rawPrefix)+" " : ""
const suffix = (rawSuffix) ? " "+suffixAnsis(rawSuffix) : ""
let label: string
if (!settings.showLabel) label = ""
if (settings.labelType == "fraction") label = labelAnsis(value+"/"+max)
else if (settings.labelType == "percentage") label = labelAnsis(Math.round(percentage*100)+"%")
else if (settings.labelType == "time-ms") label = labelAnsis(value+"ms")
else if (settings.labelType == "time-sec") label = labelAnsis(Math.round(value*10)/10+"sec")
else if (settings.labelType == "time-min") label = labelAnsis(Math.round(value*10)/10+"min")
else label = labelAnsis(value.toString())
const labelWithPrefixAndSuffix = prefix+label+suffix
return (settings.labelPosition == "start") ? labelWithPrefixAndSuffix+" "+leftBorder+bar+rightBorder : leftBorder+bar+rightBorder+" "+labelWithPrefixAndSuffix
},settings)
}
}
/**## ODProgressBarRendererManagerIds_Default `interface`
* This interface is a list of ids available in the `ODProgressBarRendererManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODProgressBarRendererManagerIds_Default {
"opendiscord:value-renderer":ODProgressBarRenderer_Default,
"opendiscord:fraction-renderer":ODProgressBarRenderer_Default,
"opendiscord:percentage-renderer":ODProgressBarRenderer_Default,
"opendiscord:time-ms-renderer":ODProgressBarRenderer_Default,
"opendiscord:time-sec-renderer":ODProgressBarRenderer_Default,
"opendiscord:time-min-renderer":ODProgressBarRenderer_Default,
}
/**## ODProgressBarRendererManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODProgressBarRendererManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.progressbars.renderers`!
*/
export class ODProgressBarRendererManager_Default extends ODProgressBarRendererManager {
get<ProgressBarId extends keyof ODProgressBarRendererManagerIds_Default>(id:ProgressBarId): ODProgressBarRendererManagerIds_Default[ProgressBarId]
get(id:ODValidId): ODProgressBarRenderer<{}>|null
get(id:ODValidId): ODProgressBarRenderer<{}>|null {
return super.get(id)
}
remove<ProgressBarId extends keyof ODProgressBarRendererManagerIds_Default>(id:ProgressBarId): ODProgressBarRendererManagerIds_Default[ProgressBarId]
remove(id:ODValidId): ODProgressBarRenderer<{}>|null
remove(id:ODValidId): ODProgressBarRenderer<{}>|null {
return super.remove(id)
}
exists(id:keyof ODProgressBarRendererManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODProgressBarManagerIds_Default `interface`
* This interface is a list of ids available in the `ODProgressBarManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODProgressBarManagerIds_Default {
"opendiscord:slash-command-remove":ODManualProgressBar,
"opendiscord:slash-command-create":ODManualProgressBar,
"opendiscord:slash-command-update":ODManualProgressBar,
"opendiscord:context-menu-remove":ODManualProgressBar,
"opendiscord:context-menu-create":ODManualProgressBar,
"opendiscord:context-menu-update":ODManualProgressBar,
}
/**## ODProgressBarManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODProgressBarManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.progressbars`!
*/
export class ODProgressBarManager_Default extends ODProgressBarManager {
declare renderers: ODProgressBarRendererManager_Default
get<ProgressBarId extends keyof ODProgressBarManagerIds_Default>(id:ProgressBarId): ODProgressBarManagerIds_Default[ProgressBarId]
get(id:ODValidId): ODProgressBar|null
get(id:ODValidId): ODProgressBar|null {
return super.get(id)
}
remove<ProgressBarId extends keyof ODProgressBarManagerIds_Default>(id:ProgressBarId): ODProgressBarManagerIds_Default[ProgressBarId]
remove(id:ODValidId): ODProgressBar|null
remove(id:ODValidId): ODProgressBar|null {
return super.remove(id)
}
exists(id:keyof ODProgressBarManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-355
View File
@@ -1,355 +0,0 @@
///////////////////////////////////////
//DEFAULT RESPONDER MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODAutocompleteResponder, ODAutocompleteResponderInstance, ODAutocompleteResponderManager, ODButtonResponder, ODButtonResponderInstance, ODButtonResponderManager, ODCommandResponder, ODCommandResponderInstance, ODCommandResponderManager, ODContextMenuResponder, ODContextMenuResponderInstance, ODContextMenuResponderManager, ODDropdownResponder, ODDropdownResponderInstance, ODDropdownResponderManager, ODModalResponder, ODModalResponderInstance, ODModalResponderManager, ODResponderManager } from "../modules/responder"
import { ODWorkerManager_Default } from "./worker"
/**## ODResponderManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODResponderManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.responders`!
*/
export class ODResponderManager_Default extends ODResponderManager {
declare commands: ODCommandResponderManager_Default
declare buttons: ODButtonResponderManager_Default
declare dropdowns: ODDropdownResponderManager_Default
declare modals: ODModalResponderManager_Default
declare contextMenus: ODContextMenuResponderManager_Default
declare autocomplete: ODAutocompleteResponderManager_Default
}
/**## ODCommandResponderManagerIds_Default `interface`
* This interface is a list of ids available in the `ODCommandResponderManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODCommandResponderManagerIds_Default {
"opendiscord:help":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:help"|"opendiscord:logs"},
"opendiscord:stats":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:stats"|"opendiscord:logs"},
"opendiscord:panel":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:panel"|"opendiscord:logs"},
"opendiscord:ticket":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:ticket"|"opendiscord:logs"},
"opendiscord:blacklist":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:blacklist"|"opendiscord:discord-logs"|"opendiscord:logs"},
"opendiscord:close":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:close"|"opendiscord:logs"},
"opendiscord:reopen":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:reopen"|"opendiscord:logs"},
"opendiscord:delete":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:delete"|"opendiscord:logs"},
"opendiscord:claim":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:claim"|"opendiscord:logs"},
"opendiscord:unclaim":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:unclaim"|"opendiscord:logs"},
"opendiscord:pin":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:pin"|"opendiscord:logs"},
"opendiscord:unpin":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:unpin"|"opendiscord:logs"},
"opendiscord:rename":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:rename"|"opendiscord:logs"},
"opendiscord:move":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:move"|"opendiscord:logs"},
"opendiscord:add":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:add"|"opendiscord:logs"},
"opendiscord:remove":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:remove"|"opendiscord:logs"},
"opendiscord:clear":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:clear"|"opendiscord:logs"},
"opendiscord:topic":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:topic"|"opendiscord:logs"},
"opendiscord:priority":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:priority"|"opendiscord:logs"},
"opendiscord:transfer":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:transfer"|"opendiscord:logs"},
"opendiscord:autoclose":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:autoclose"|"opendiscord:logs"},
"opendiscord:autodelete":{source:"slash"|"text",params:{},workers:"opendiscord:permissions"|"opendiscord:autodelete"|"opendiscord:logs"},
}
/**## ODCommandResponderManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODCommandResponderManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.responders.commands`!
*/
export class ODCommandResponderManager_Default extends ODCommandResponderManager {
get<CommandResponderId extends keyof ODCommandResponderManagerIds_Default>(id:CommandResponderId): ODCommandResponder_Default<ODCommandResponderManagerIds_Default[CommandResponderId]["source"],ODCommandResponderManagerIds_Default[CommandResponderId]["params"],ODCommandResponderManagerIds_Default[CommandResponderId]["workers"]>
get(id:ODValidId): ODCommandResponder<"slash"|"text",any>|null
get(id:ODValidId): ODCommandResponder<"slash"|"text",any>|null {
return super.get(id)
}
remove<CommandResponderId extends keyof ODCommandResponderManagerIds_Default>(id:CommandResponderId): ODCommandResponder_Default<ODCommandResponderManagerIds_Default[CommandResponderId]["source"],ODCommandResponderManagerIds_Default[CommandResponderId]["params"],ODCommandResponderManagerIds_Default[CommandResponderId]["workers"]>
remove(id:ODValidId): ODCommandResponder<"slash"|"text",any>|null
remove(id:ODValidId): ODCommandResponder<"slash"|"text",any>|null {
return super.remove(id)
}
exists(id:keyof ODCommandResponderManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODCommandResponder_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODCommandResponder class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODCommandResponder`'s!
*/
export class ODCommandResponder_Default<Source extends "slash"|"text", Params, WorkerIds extends string> extends ODCommandResponder<Source,Params> {
declare workers: ODWorkerManager_Default<ODCommandResponderInstance,Source,Params,WorkerIds>
}
/**## ODButtonResponderManagerIds_Default `interface`
* This interface is a list of ids available in the `ODButtonResponderManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODButtonResponderManagerIds_Default {
"opendiscord:verifybar-success":{source:"button",params:{},workers:"opendiscord:handle-verifybar"},
"opendiscord:verifybar-failure":{source:"button",params:{},workers:"opendiscord:handle-verifybar"},
"opendiscord:help-menu-switch":{source:"button",params:{},workers:"opendiscord:update-help-menu"},
"opendiscord:help-menu-previous":{source:"button",params:{},workers:"opendiscord:update-help-menu"},
"opendiscord:help-menu-next":{source:"button",params:{},workers:"opendiscord:update-help-menu"},
"opendiscord:ticket-option":{source:"button",params:{},workers:"opendiscord:ticket-option"},
"opendiscord:role-option":{source:"button",params:{},workers:"opendiscord:role-option"},
"opendiscord:claim-ticket":{source:"button",params:{},workers:"opendiscord:claim-ticket"},
"opendiscord:unclaim-ticket":{source:"button",params:{},workers:"opendiscord:unclaim-ticket"},
"opendiscord:pin-ticket":{source:"button",params:{},workers:"opendiscord:pin-ticket"},
"opendiscord:unpin-ticket":{source:"button",params:{},workers:"opendiscord:unpin-ticket"},
"opendiscord:close-ticket":{source:"button",params:{},workers:"opendiscord:close-ticket"},
"opendiscord:reopen-ticket":{source:"button",params:{},workers:"opendiscord:reopen-ticket"},
"opendiscord:delete-ticket":{source:"button",params:{},workers:"opendiscord:delete-ticket"},
"opendiscord:transcript-error-retry":{source:"button",params:{},workers:"opendiscord:permissions"|"opendiscord:delete-ticket"|"opendiscord:logs"},
"opendiscord:transcript-error-continue":{source:"button",params:{},workers:"opendiscord:permissions"|"opendiscord:delete-ticket"|"opendiscord:logs"},
"opendiscord:clear-continue":{source:"button",params:{},workers:"opendiscord:clear-continue"},
}
/**## ODButtonResponderManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODButtonResponderManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.responders.buttons`!
*/
export class ODButtonResponderManager_Default extends ODButtonResponderManager {
get<ButtonResponderId extends keyof ODButtonResponderManagerIds_Default>(id:ButtonResponderId): ODButtonResponder_Default<ODButtonResponderManagerIds_Default[ButtonResponderId]["source"],ODButtonResponderManagerIds_Default[ButtonResponderId]["params"],ODButtonResponderManagerIds_Default[ButtonResponderId]["workers"]>
get(id:ODValidId): ODButtonResponder<"button",any>|null
get(id:ODValidId): ODButtonResponder<"button",any>|null {
return super.get(id)
}
remove<ButtonResponderId extends keyof ODButtonResponderManagerIds_Default>(id:ButtonResponderId): ODButtonResponder_Default<ODButtonResponderManagerIds_Default[ButtonResponderId]["source"],ODButtonResponderManagerIds_Default[ButtonResponderId]["params"],ODButtonResponderManagerIds_Default[ButtonResponderId]["workers"]>
remove(id:ODValidId): ODButtonResponder<"button",any>|null
remove(id:ODValidId): ODButtonResponder<"button",any>|null {
return super.remove(id)
}
exists(id:keyof ODButtonResponderManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODButtonResponder_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODButtonResponder class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODButtonResponder`'s!
*/
export class ODButtonResponder_Default<Source extends string, Params, WorkerIds extends string> extends ODButtonResponder<Source,Params> {
declare workers: ODWorkerManager_Default<ODButtonResponderInstance,Source,Params,WorkerIds>
}
/**## ODDropdownResponderManagerIds_Default `interface`
* This interface is a list of ids available in the `ODDropdownResponderManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODDropdownResponderManagerIds_Default {
"opendiscord:panel-dropdown-tickets":{source:"dropdown",params:{},workers:"opendiscord:panel-dropdown-tickets"},
}
/**## ODDropdownResponderManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODDropdownResponderManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.responders.dropdowns`!
*/
export class ODDropdownResponderManager_Default extends ODDropdownResponderManager {
get<DropdownResponderId extends keyof ODDropdownResponderManagerIds_Default>(id:DropdownResponderId): ODDropdownResponder_Default<ODDropdownResponderManagerIds_Default[DropdownResponderId]["source"],ODDropdownResponderManagerIds_Default[DropdownResponderId]["params"],ODDropdownResponderManagerIds_Default[DropdownResponderId]["workers"]>
get(id:ODValidId): ODDropdownResponder<"dropdown",any>|null
get(id:ODValidId): ODDropdownResponder<"dropdown",any>|null {
return super.get(id)
}
remove<DropdownResponderId extends keyof ODDropdownResponderManagerIds_Default>(id:DropdownResponderId): ODDropdownResponder_Default<ODDropdownResponderManagerIds_Default[DropdownResponderId]["source"],ODDropdownResponderManagerIds_Default[DropdownResponderId]["params"],ODDropdownResponderManagerIds_Default[DropdownResponderId]["workers"]>
remove(id:ODValidId): ODDropdownResponder<"dropdown",any>|null
remove(id:ODValidId): ODDropdownResponder<"dropdown",any>|null {
return super.remove(id)
}
exists(id:keyof ODDropdownResponderManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODDropdownResponder_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODDropdownResponder class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODDropdownResponder`'s!
*/
export class ODDropdownResponder_Default<Source extends string, Params, WorkerIds extends string> extends ODDropdownResponder<Source,Params> {
declare workers: ODWorkerManager_Default<ODDropdownResponderInstance,Source,Params,WorkerIds>
}
/**## ODModalResponderManagerIds_Default `interface`
* This interface is a list of ids available in the `ODModalResponderManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODModalResponderManagerIds_Default {
"opendiscord:ticket-questions":{source:"modal",params:{},workers:"opendiscord:ticket-questions"},
"opendiscord:close-ticket-reason":{source:"modal",params:{},workers:"opendiscord:close-ticket-reason"},
"opendiscord:reopen-ticket-reason":{source:"modal",params:{},workers:"opendiscord:reopen-ticket-reason"},
"opendiscord:delete-ticket-reason":{source:"modal",params:{},workers:"opendiscord:delete-ticket-reason"},
"opendiscord:claim-ticket-reason":{source:"modal",params:{},workers:"opendiscord:claim-ticket-reason"},
"opendiscord:unclaim-ticket-reason":{source:"modal",params:{},workers:"opendiscord:unclaim-ticket-reason"},
"opendiscord:pin-ticket-reason":{source:"modal",params:{},workers:"opendiscord:pin-ticket-reason"},
"opendiscord:unpin-ticket-reason":{source:"modal",params:{},workers:"opendiscord:unpin-ticket-reason"},
}
/**## ODModalResponderManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODModalResponderManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.responders.dropdowns`!
*/
export class ODModalResponderManager_Default extends ODModalResponderManager {
get<ModalResponderId extends keyof ODModalResponderManagerIds_Default>(id:ModalResponderId): ODModalResponder_Default<ODModalResponderManagerIds_Default[ModalResponderId]["source"],ODModalResponderManagerIds_Default[ModalResponderId]["params"],ODModalResponderManagerIds_Default[ModalResponderId]["workers"]>
get(id:ODValidId): ODModalResponder<"modal",any>|null
get(id:ODValidId): ODModalResponder<"modal",any>|null {
return super.get(id)
}
remove<ModalResponderId extends keyof ODModalResponderManagerIds_Default>(id:ModalResponderId): ODModalResponder_Default<ODModalResponderManagerIds_Default[ModalResponderId]["source"],ODModalResponderManagerIds_Default[ModalResponderId]["params"],ODModalResponderManagerIds_Default[ModalResponderId]["workers"]>
remove(id:ODValidId): ODModalResponder<"modal",any>|null
remove(id:ODValidId): ODModalResponder<"modal",any>|null {
return super.remove(id)
}
exists(id:keyof ODModalResponderManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODModalResponder_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODModalResponder class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODModalResponder`'s!
*/
export class ODModalResponder_Default<Source extends string, Params, WorkerIds extends string> extends ODModalResponder<Source,Params> {
declare workers: ODWorkerManager_Default<ODModalResponderInstance,Source,Params,WorkerIds>
}
/**## ODContextMenuResponderManagerIds_Default `interface`
* This interface is a list of ids available in the `ODContextMenuResponderManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODContextMenuResponderManagerIds_Default {
//"opendiscord:example":{source:"context-menu",params:{},workers:"opendiscord:example"},
}
/**## ODContextMenuResponderManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODContextMenuResponderManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.responders.contextMenus`!
*/
export class ODContextMenuResponderManager_Default extends ODContextMenuResponderManager {
get<ModalResponderId extends keyof ODContextMenuResponderManagerIds_Default>(id:ModalResponderId): ODContextMenuResponder_Default<ODContextMenuResponderManagerIds_Default[ModalResponderId]["source"],ODContextMenuResponderManagerIds_Default[ModalResponderId]["params"],ODContextMenuResponderManagerIds_Default[ModalResponderId]["workers"]>
get(id:ODValidId): ODContextMenuResponder<"context-menu",any>|null
get(id:ODValidId): ODContextMenuResponder<"context-menu",any>|null {
return super.get(id)
}
remove<ModalResponderId extends keyof ODContextMenuResponderManagerIds_Default>(id:ModalResponderId): ODContextMenuResponder_Default<ODContextMenuResponderManagerIds_Default[ModalResponderId]["source"],ODContextMenuResponderManagerIds_Default[ModalResponderId]["params"],ODContextMenuResponderManagerIds_Default[ModalResponderId]["workers"]>
remove(id:ODValidId): ODContextMenuResponder<"context-menu",any>|null
remove(id:ODValidId): ODContextMenuResponder<"context-menu",any>|null {
return super.remove(id)
}
exists(id:keyof ODContextMenuResponderManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODContextMenuResponder_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODContextMenuResponder class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODContextMenuResponder`'s!
*/
export class ODContextMenuResponder_Default<Source extends string, Params, WorkerIds extends string> extends ODContextMenuResponder<Source,Params> {
declare workers: ODWorkerManager_Default<ODContextMenuResponderInstance,Source,Params,WorkerIds>
}
/**## ODAutocompleteResponderManagerIds_Default `interface`
* This interface is a list of ids available in the `ODAutocompleteResponderManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODAutocompleteResponderManagerIds_Default {
"opendiscord:panel-id":{source:"autocomplete",params:{},workers:"opendiscord:panel-id"},
"opendiscord:option-id":{source:"autocomplete",params:{},workers:"opendiscord:option-id"}
}
/**## ODAutocompleteResponderManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODAutocompleteResponderManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.responders.autocomplete`!
*/
export class ODAutocompleteResponderManager_Default extends ODAutocompleteResponderManager {
get<ModalResponderId extends keyof ODAutocompleteResponderManagerIds_Default>(id:ModalResponderId): ODAutocompleteResponder_Default<ODAutocompleteResponderManagerIds_Default[ModalResponderId]["source"],ODAutocompleteResponderManagerIds_Default[ModalResponderId]["params"],ODAutocompleteResponderManagerIds_Default[ModalResponderId]["workers"]>
get(id:ODValidId): ODAutocompleteResponder<"autocomplete",any>|null
get(id:ODValidId): ODAutocompleteResponder<"autocomplete",any>|null {
return super.get(id)
}
remove<ModalResponderId extends keyof ODAutocompleteResponderManagerIds_Default>(id:ModalResponderId): ODAutocompleteResponder_Default<ODAutocompleteResponderManagerIds_Default[ModalResponderId]["source"],ODAutocompleteResponderManagerIds_Default[ModalResponderId]["params"],ODAutocompleteResponderManagerIds_Default[ModalResponderId]["workers"]>
remove(id:ODValidId): ODAutocompleteResponder<"autocomplete",any>|null
remove(id:ODValidId): ODAutocompleteResponder<"autocomplete",any>|null {
return super.remove(id)
}
exists(id:keyof ODAutocompleteResponderManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODAutocompleteResponder_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODAutocompleteResponder class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODAutocompleteResponder`'s!
*/
export class ODAutocompleteResponder_Default<Source extends string, Params, WorkerIds extends string> extends ODAutocompleteResponder<Source,Params> {
declare workers: ODWorkerManager_Default<ODAutocompleteResponderInstance,Source,Params,WorkerIds>
}
-42
View File
@@ -1,42 +0,0 @@
///////////////////////////////////////
//DEFAULT SESSION MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODSession, ODSessionManager } from "../modules/session"
/**## ODSessionManagerIds_Default `interface`
* This interface is a list of ids available in the `ODSessionManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODSessionManagerIds_Default {
//"test-session":ODSession
}
/**## ODSessionManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODSessionManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.sessions`!
*/
export class ODSessionManager_Default extends ODSessionManager {
get<SessionId extends keyof ODSessionManagerIds_Default>(id:SessionId): ODSessionManagerIds_Default[SessionId]
get(id:ODValidId): ODSession|null
get(id:ODValidId): ODSession|null {
return super.get(id)
}
remove<SessionId extends keyof ODSessionManagerIds_Default>(id:SessionId): ODSessionManagerIds_Default[SessionId]
remove(id:ODValidId): ODSession|null
remove(id:ODValidId): ODSession|null {
return super.remove(id)
}
exists(id:keyof ODSessionManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-48
View File
@@ -1,48 +0,0 @@
///////////////////////////////////////
//DEFAULT STARTSCREEN MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODStartScreenCategoryComponent, ODStartScreenComponent, ODStartScreenFlagsCategoryComponent, ODStartScreenHeaderComponent, ODStartScreenLiveStatusCategoryComponent, ODStartScreenLogoComponent, ODStartScreenManager, ODStartScreenPluginsCategoryComponent, ODStartScreenPropertiesCategoryComponent } from "../modules/startscreen"
/**## ODStartScreenManagerIds_Default `interface`
* This interface is a list of ids available in the `ODStartScreenManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStartScreenManagerIds_Default {
"opendiscord:logo":ODStartScreenLogoComponent,
"opendiscord:header":ODStartScreenHeaderComponent,
"opendiscord:flags":ODStartScreenFlagsCategoryComponent,
"opendiscord:plugins":ODStartScreenPluginsCategoryComponent,
"opendiscord:stats":ODStartScreenPropertiesCategoryComponent,
"opendiscord:livestatus":ODStartScreenLiveStatusCategoryComponent,
"opendiscord:logs":ODStartScreenCategoryComponent
}
/**## ODStartScreenManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODStartScreenManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.startscreen`!
*/
export class ODStartScreenManager_Default extends ODStartScreenManager {
get<StartScreenId extends keyof ODStartScreenManagerIds_Default>(id:StartScreenId): ODStartScreenManagerIds_Default[StartScreenId]
get(id:ODValidId): ODStartScreenComponent|null
get(id:ODValidId): ODStartScreenComponent|null {
return super.get(id)
}
remove<StartScreenId extends keyof ODStartScreenManagerIds_Default>(id:StartScreenId): ODStartScreenManagerIds_Default[StartScreenId]
remove(id:ODValidId): ODStartScreenComponent|null
remove(id:ODValidId): ODStartScreenComponent|null {
return super.remove(id)
}
exists(id:keyof ODStartScreenManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-472
View File
@@ -1,472 +0,0 @@
///////////////////////////////////////
//DEFAULT SESSION MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODStatScope, ODStatGlobalScope, ODStatsManager, ODStat, ODBasicStat, ODDynamicStat, ODValidStatValue, ODStatScopeSetMode } from "../modules/stat"
/**## ODStatsManagerIds_Default `interface`
* This interface is a list of ids available in the `ODStatsManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatsManagerIds_Default {
"opendiscord:global":ODStatGlobalScope_DefaultGlobal,
"opendiscord:system":ODStatGlobalScope_DefaultSystem,
"opendiscord:user":ODStatScope_DefaultUser,
"opendiscord:ticket":ODStatScope_DefaultTicket,
"opendiscord:participants":ODStatScope_DefaultParticipants,
"opendiscord:messages":ODStatScope_DefaultMessages,
}
/**## ODStatsManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODStatsManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.stats`!
*/
export class ODStatsManager_Default extends ODStatsManager {
get<StatsId extends keyof ODStatsManagerIds_Default>(id:StatsId): ODStatsManagerIds_Default[StatsId]
get(id:ODValidId): ODStatScope|null
get(id:ODValidId): ODStatScope|null {
return super.get(id)
}
remove<StatsId extends keyof ODStatsManagerIds_Default>(id:StatsId): ODStatsManagerIds_Default[StatsId]
remove(id:ODValidId): ODStatScope|null
remove(id:ODValidId): ODStatScope|null {
return super.remove(id)
}
exists(id:keyof ODStatsManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODStatGlobalScopeIds_DefaultGlobal `type`
* This interface is a list of ids available in the `ODStatGlobalScope_DefaultGlobal` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatGlobalScopeIds_DefaultGlobal {
"opendiscord:tickets-created":ODBasicStat,
"opendiscord:tickets-closed":ODBasicStat,
"opendiscord:tickets-deleted":ODBasicStat,
"opendiscord:tickets-reopened":ODBasicStat,
"opendiscord:tickets-autoclosed":ODBasicStat,
"opendiscord:tickets-autodeleted":ODBasicStat,
"opendiscord:tickets-claimed":ODBasicStat,
"opendiscord:tickets-pinned":ODBasicStat,
"opendiscord:tickets-moved":ODBasicStat,
"opendiscord:tickets-transferred":ODBasicStat,
"opendiscord:users-blacklisted":ODBasicStat,
"opendiscord:transcripts-created":ODBasicStat,
"opendiscord:ticket-volume":ODDynamicStat,
"opendiscord:average-tickets":ODDynamicStat,
}
/**## ODStatGlobalScope_DefaultGlobal `default_class`
* This is a special class that adds type definitions & typescript to the ODStatsManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:global` category in `opendiscord.stats`!
*/
export class ODStatGlobalScope_DefaultGlobal extends ODStatGlobalScope {
get<StatsId extends keyof ODStatGlobalScopeIds_DefaultGlobal>(id:StatsId): ODStatGlobalScopeIds_DefaultGlobal[StatsId]
get(id:ODValidId): ODStat|null
get(id:ODValidId): ODStat|null {
return super.get(id)
}
remove<StatsId extends keyof ODStatGlobalScopeIds_DefaultGlobal>(id:StatsId): ODStatGlobalScopeIds_DefaultGlobal[StatsId]
remove(id:ODValidId): ODStat|null
remove(id:ODValidId): ODStat|null {
return super.remove(id)
}
exists(id:keyof ODStatGlobalScopeIds_DefaultGlobal): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getStat<StatsId extends keyof ODStatGlobalScopeIds_DefaultGlobal>(id:StatsId): Promise<ODValidStatValue|null>
getStat(id:ODValidId): Promise<ODValidStatValue|null>
getStat(id:ODValidId): Promise<ODValidStatValue|null> {
return super.getStat(id)
}
getAllStats<StatsId extends keyof ODStatGlobalScopeIds_DefaultGlobal>(id:StatsId): Promise<{id:string,value:ODValidStatValue}[]>
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]>
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]> {
return super.getAllStats(id)
}
setStat<StatsId extends keyof ODStatGlobalScopeIds_DefaultGlobal>(id:StatsId, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean>
setStat(id:ODValidId, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean>
setStat(id:ODValidId, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean> {
return super.setStat(id,value,mode)
}
resetStat<StatsId extends keyof ODStatGlobalScopeIds_DefaultGlobal>(id:ODValidId): Promise<ODValidStatValue|null>
resetStat(id:ODValidId): Promise<ODValidStatValue|null>
resetStat(id:ODValidId): Promise<ODValidStatValue|null> {
return super.resetStat(id)
}
}
/**## ODStatGlobalScopeIds_DefaultSystem `type`
* This interface is a list of ids available in the `ODStatScope_DefaultSystem` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatGlobalScopeIds_DefaultSystem {
"opendiscord:startup-date":ODDynamicStat,
"opendiscord:system-uptime":ODDynamicStat,
"opendiscord:version":ODDynamicStat
}
/**## ODStatGlobalScope_DefaultSystem `default_class`
* This is a special class that adds type definitions & typescript to the ODStatsManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:system` category in `opendiscord.stats`!
*/
export class ODStatGlobalScope_DefaultSystem extends ODStatGlobalScope {
get<StatsId extends keyof ODStatGlobalScopeIds_DefaultSystem>(id:StatsId): ODStatGlobalScopeIds_DefaultSystem[StatsId]
get(id:ODValidId): ODStat|null
get(id:ODValidId): ODStat|null {
return super.get(id)
}
remove<StatsId extends keyof ODStatGlobalScopeIds_DefaultSystem>(id:StatsId): ODStatGlobalScopeIds_DefaultSystem[StatsId]
remove(id:ODValidId): ODStat|null
remove(id:ODValidId): ODStat|null {
return super.remove(id)
}
exists(id:keyof ODStatGlobalScopeIds_DefaultSystem): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getStat<StatsId extends keyof ODStatGlobalScopeIds_DefaultSystem>(id:StatsId): Promise<ODValidStatValue|null>
getStat(id:ODValidId): Promise<ODValidStatValue|null>
getStat(id:ODValidId): Promise<ODValidStatValue|null> {
return super.getStat(id)
}
getAllStats<StatsId extends keyof ODStatGlobalScopeIds_DefaultSystem>(id:StatsId): Promise<{id:string,value:ODValidStatValue}[]>
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]>
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]> {
return super.getAllStats(id)
}
setStat<StatsId extends keyof ODStatGlobalScopeIds_DefaultSystem>(id:StatsId, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean>
setStat(id:ODValidId, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean>
setStat(id:ODValidId, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean> {
return super.setStat(id,value,mode)
}
resetStat<StatsId extends keyof ODStatGlobalScopeIds_DefaultSystem>(id:ODValidId): Promise<ODValidStatValue|null>
resetStat(id:ODValidId): Promise<ODValidStatValue|null>
resetStat(id:ODValidId): Promise<ODValidStatValue|null> {
return super.resetStat(id)
}
}
/**## ODStatScopeIds_DefaultUser `type`
* This interface is a list of ids available in the `ODStatScope_DefaultUser` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatScopeIds_DefaultUser {
"opendiscord:name":ODDynamicStat,
"opendiscord:role":ODDynamicStat,
"opendiscord:tickets-created":ODBasicStat,
"opendiscord:tickets-closed":ODBasicStat,
"opendiscord:tickets-deleted":ODBasicStat,
"opendiscord:tickets-reopened":ODBasicStat,
"opendiscord:tickets-claimed":ODBasicStat,
"opendiscord:tickets-pinned":ODBasicStat,
"opendiscord:tickets-moved":ODBasicStat,
"opendiscord:tickets-transferred":ODBasicStat,
"opendiscord:users-blacklisted":ODBasicStat,
"opendiscord:transcripts-created":ODBasicStat,
"opendiscord:current-tickets":ODDynamicStat,
}
/**## ODStatScope_DefaultUser `default_class`
* This is a special class that adds type definitions & typescript to the ODStatsManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:user` category in `opendiscord.stats`!
*/
export class ODStatScope_DefaultUser extends ODStatScope {
get<StatsId extends keyof ODStatScopeIds_DefaultUser>(id:StatsId): ODStatScopeIds_DefaultUser[StatsId]
get(id:ODValidId): ODStat|null
get(id:ODValidId): ODStat|null {
return super.get(id)
}
remove<StatsId extends keyof ODStatScopeIds_DefaultUser>(id:StatsId): ODStatScopeIds_DefaultUser[StatsId]
remove(id:ODValidId): ODStat|null
remove(id:ODValidId): ODStat|null {
return super.remove(id)
}
exists(id:keyof ODStatScopeIds_DefaultUser): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getStat<StatsId extends keyof ODStatScopeIds_DefaultUser>(id:StatsId, scopeId:string): Promise<ODValidStatValue|null>
getStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null>
getStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null> {
return super.getStat(id,scopeId)
}
getAllStats<StatsId extends keyof ODStatScopeIds_DefaultUser>(id:StatsId): Promise<{id:string,value:ODValidStatValue}[]>
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]>
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]> {
return super.getAllStats(id)
}
setStat<StatsId extends keyof ODStatScopeIds_DefaultUser>(id:StatsId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean>
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean>
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean> {
return super.setStat(id,scopeId,value,mode)
}
resetStat<StatsId extends keyof ODStatScopeIds_DefaultUser>(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null>
resetStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null>
resetStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null> {
return super.resetStat(id,scopeId)
}
}
/**## ODStatScopeIds_DefaultTicket `type`
* This interface is a list of ids available in the `ODStatScope_DefaultTicket` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatScopeIds_DefaultTicket {
"opendiscord:name":ODDynamicStat,
"opendiscord:status":ODDynamicStat,
"opendiscord:claimed":ODDynamicStat,
"opendiscord:pinned":ODDynamicStat,
"opendiscord:creation-date":ODDynamicStat,
"opendiscord:creator":ODDynamicStat,
"opendiscord:ticket-age":ODDynamicStat,
"opendiscord:response-time":ODDynamicStat,
"opendiscord:resolution-time":ODDynamicStat,
}
/**## ODStatScope_DefaultTicket `default_class`
* This is a special class that adds type definitions & typescript to the ODStatsManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:ticket` category in `opendiscord.stats`!
*/
export class ODStatScope_DefaultTicket extends ODStatScope {
get<StatsId extends keyof ODStatScopeIds_DefaultTicket>(id:StatsId): ODStatScopeIds_DefaultTicket[StatsId]
get(id:ODValidId): ODStat|null
get(id:ODValidId): ODStat|null {
return super.get(id)
}
remove<StatsId extends keyof ODStatScopeIds_DefaultTicket>(id:StatsId): ODStatScopeIds_DefaultTicket[StatsId]
remove(id:ODValidId): ODStat|null
remove(id:ODValidId): ODStat|null {
return super.remove(id)
}
exists(id:keyof ODStatScopeIds_DefaultTicket): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getStat<StatsId extends keyof ODStatScopeIds_DefaultTicket>(id:StatsId, scopeId:string): Promise<ODValidStatValue|null>
getStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null>
getStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null> {
return super.getStat(id,scopeId)
}
getAllStats<StatsId extends keyof ODStatScopeIds_DefaultTicket>(id:StatsId): Promise<{id:string,value:ODValidStatValue}[]>
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]>
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]> {
return super.getAllStats(id)
}
setStat<StatsId extends keyof ODStatScopeIds_DefaultTicket>(id:StatsId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean>
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean>
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean> {
return super.setStat(id,scopeId,value,mode)
}
resetStat<StatsId extends keyof ODStatScopeIds_DefaultTicket>(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null>
resetStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null>
resetStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null> {
return super.resetStat(id,scopeId)
}
}
/**## ODStatScopeIds_DefaultParticipants `type`
* This interface is a list of ids available in the `ODStatScope_DefaultParticipants` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatScopeIds_DefaultParticipants {
"opendiscord:participants":ODDynamicStat
}
/**## ODStatScope_DefaultParticipants `default_class`
* This is a special class that adds type definitions & typescript to the ODStatsManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:participants` category in `opendiscord.stats`!
*/
export class ODStatScope_DefaultParticipants extends ODStatScope {
get<StatsId extends keyof ODStatScopeIds_DefaultParticipants>(id:StatsId): ODStatScopeIds_DefaultParticipants[StatsId]
get(id:ODValidId): ODStat|null
get(id:ODValidId): ODStat|null {
return super.get(id)
}
remove<StatsId extends keyof ODStatScopeIds_DefaultParticipants>(id:StatsId): ODStatScopeIds_DefaultParticipants[StatsId]
remove(id:ODValidId): ODStat|null
remove(id:ODValidId): ODStat|null {
return super.remove(id)
}
exists(id:keyof ODStatScopeIds_DefaultParticipants): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getStat<StatsId extends keyof ODStatScopeIds_DefaultParticipants>(id:StatsId, scopeId:string): Promise<ODValidStatValue|null>
getStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null>
getStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null> {
return super.getStat(id,scopeId)
}
getAllStats<StatsId extends keyof ODStatScopeIds_DefaultParticipants>(id:StatsId): Promise<{id:string,value:ODValidStatValue}[]>
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]>
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]> {
return super.getAllStats(id)
}
setStat<StatsId extends keyof ODStatScopeIds_DefaultParticipants>(id:StatsId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean>
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean>
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean> {
return super.setStat(id,scopeId,value,mode)
}
resetStat<StatsId extends keyof ODStatScopeIds_DefaultParticipants>(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null>
resetStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null>
resetStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null> {
return super.resetStat(id,scopeId)
}
}
/**## ODStatScopeIds_DefaultMessages `type`
* This interface is a list of ids available in the `ODStatScope_DefaultMessages` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatScopeIds_DefaultMessages {
"opendiscord:count":ODDynamicStat
}
/**## ODStatScope_DefaultMessages `default_class`
* This is a special class that adds type definitions & typescript to the ODStatsManager class.
* It doesn't add any extra features!
*
* This default class is made for the `opendiscord:participants` category in `opendiscord.stats`!
*/
export class ODStatScope_DefaultMessages extends ODStatScope {
get<StatsId extends keyof ODStatScopeIds_DefaultMessages>(id:StatsId): ODStatScopeIds_DefaultMessages[StatsId]
get(id:ODValidId): ODStat|null
get(id:ODValidId): ODStat|null {
return super.get(id)
}
remove<StatsId extends keyof ODStatScopeIds_DefaultMessages>(id:StatsId): ODStatScopeIds_DefaultMessages[StatsId]
remove(id:ODValidId): ODStat|null
remove(id:ODValidId): ODStat|null {
return super.remove(id)
}
exists(id:keyof ODStatScopeIds_DefaultMessages): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getStat<StatsId extends keyof ODStatScopeIds_DefaultMessages>(id:StatsId, scopeId:string): Promise<ODValidStatValue|null>
getStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null>
getStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null> {
return super.getStat(id,scopeId)
}
getAllStats<StatsId extends keyof ODStatScopeIds_DefaultMessages>(id:StatsId): Promise<{id:string,value:ODValidStatValue}[]>
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]>
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]> {
return super.getAllStats(id)
}
setStat<StatsId extends keyof ODStatScopeIds_DefaultMessages>(id:StatsId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean>
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean>
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean> {
return super.setStat(id,scopeId,value,mode)
}
resetStat<StatsId extends keyof ODStatScopeIds_DefaultMessages>(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null>
resetStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null>
resetStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null> {
return super.resetStat(id,scopeId)
}
}
-72
View File
@@ -1,72 +0,0 @@
///////////////////////////////////////
//DEFAULT VERIFYBAR MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODButtonResponderInstance } from "../modules/responder"
import { ODWorkerManager_Default } from "../defaults/worker"
import { ODVerifyBarManager, ODVerifyBar } from "../modules/verifybar"
import * as discord from "discord.js"
/**## ODVerifyBarManagerIds_Default `interface`
* This interface is a list of ids available in the `ODVerifyBarManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODVerifyBarManagerIds_Default {
"opendiscord:claim-ticket-ticket-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:claim-ticket",failureWorkerIds:"opendiscord:back-to-ticket-message"},
"opendiscord:claim-ticket-unclaim-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:claim-ticket",failureWorkerIds:"opendiscord:back-to-unclaim-message"},
"opendiscord:unclaim-ticket-ticket-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:unclaim-ticket",failureWorkerIds:"opendiscord:back-to-ticket-message"},
"opendiscord:unclaim-ticket-claim-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:unclaim-ticket",failureWorkerIds:"opendiscord:back-to-claim-message"},
"opendiscord:pin-ticket-ticket-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:pin-ticket",failureWorkerIds:"opendiscord:back-to-ticket-message"},
"opendiscord:pin-ticket-unpin-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:pin-ticket",failureWorkerIds:"opendiscord:back-to-unpin-message"},
"opendiscord:unpin-ticket-ticket-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:unpin-ticket",failureWorkerIds:"opendiscord:back-to-ticket-message"},
"opendiscord:unpin-ticket-pin-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:unpin-ticket",failureWorkerIds:"opendiscord:back-to-pin-message"},
"opendiscord:close-ticket-ticket-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:close-ticket",failureWorkerIds:"opendiscord:back-to-ticket-message"},
"opendiscord:close-ticket-reopen-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:close-ticket",failureWorkerIds:"opendiscord:back-to-reopen-message"},
"opendiscord:reopen-ticket-ticket-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:reopen-ticket",failureWorkerIds:"opendiscord:back-to-ticket-message"},
"opendiscord:reopen-ticket-close-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:reopen-ticket",failureWorkerIds:"opendiscord:back-to-close-message"},
"opendiscord:reopen-ticket-autoclose-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:reopen-ticket",failureWorkerIds:"opendiscord:back-to-autoclose-message"},
"opendiscord:delete-ticket-ticket-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:delete-ticket",failureWorkerIds:"opendiscord:back-to-ticket-message"}
"opendiscord:delete-ticket-close-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:delete-ticket",failureWorkerIds:"opendiscord:back-to-close-message"}
"opendiscord:delete-ticket-reopen-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:delete-ticket",failureWorkerIds:"opendiscord:back-to-reopen-message"}
"opendiscord:delete-ticket-autoclose-message":{successWorkerIds:"opendiscord:permissions"|"opendiscord:delete-ticket",failureWorkerIds:"opendiscord:back-to-autoclose-message"}
}
/**## ODVerifyBarManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODVerifyBarManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.verifybars`!
*/
export class ODVerifyBarManager_Default extends ODVerifyBarManager {
get<VerifyBarId extends keyof ODVerifyBarManagerIds_Default>(id:VerifyBarId): ODVerifyBar_Default<ODVerifyBarManagerIds_Default[VerifyBarId]["successWorkerIds"],ODVerifyBarManagerIds_Default[VerifyBarId]["failureWorkerIds"]>
get(id:ODValidId): ODVerifyBar|null
get(id:ODValidId): ODVerifyBar|null {
return super.get(id)
}
remove<VerifyBarId extends keyof ODVerifyBarManagerIds_Default>(id:VerifyBarId): ODVerifyBar_Default<ODVerifyBarManagerIds_Default[VerifyBarId]["successWorkerIds"],ODVerifyBarManagerIds_Default[VerifyBarId]["failureWorkerIds"]>
remove(id:ODValidId): ODVerifyBar|null
remove(id:ODValidId): ODVerifyBar|null {
return super.remove(id)
}
exists(id:keyof ODVerifyBarManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODVerifyBar_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODVerifyBar class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODVerifyBar`'s!
*/
export class ODVerifyBar_Default<SuccessWorkerIds extends string,FailureWorkerIds extends string> extends ODVerifyBar {
declare success: ODWorkerManager_Default<ODButtonResponderInstance,"verifybar",{data:string|null,verifybarMessage:discord.Message<boolean>|null},SuccessWorkerIds>
declare failure: ODWorkerManager_Default<ODButtonResponderInstance,"verifybar",{data:string|null,verifybarMessage:discord.Message<boolean>|null},FailureWorkerIds>
}
-35
View File
@@ -1,35 +0,0 @@
///////////////////////////////////////
//DEFAULT WORKER MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODWorker, ODWorkerManager } from "../modules/worker"
/**## ODWorkerManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODWorkerManager class.
* It doesn't add any extra features!
*
* This default class is made for the worker manager in actions, builders & responders!
*/
export class ODWorkerManager_Default<Instance, Source extends string, Params, WorkerIds extends string> extends ODWorkerManager<Instance,Source,Params> {
get(id:WorkerIds): ODWorker<Instance,Source,Params>
get(id:ODValidId): ODWorker<Instance,Source,Params>|null
get(id:ODValidId): ODWorker<Instance,Source,Params>|null {
return super.get(id)
}
remove(id:WorkerIds): ODWorker<Instance,Source,Params>
remove(id:ODValidId): ODWorker<Instance,Source,Params>|null
remove(id:ODValidId): ODWorker<Instance,Source,Params>|null {
return super.remove(id)
}
exists(id:WorkerIds): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
-193
View File
@@ -1,193 +0,0 @@
//BASE MODULES
import { ODEnvHelper, ODVersion } from "./modules/base"
import { ODConsoleManager, ODConsoleMessage, ODConsoleMessageParam, ODConsoleMessageTypes, ODDebugFileManager, ODDebugger, ODError } from "./modules/console"
import { ODCheckerStorage } from "./modules/checker"
import { ODDefaultsManager } from "./modules/defaults"
//DEFAULT MODULES
import { ODVersionManager_Default } from "./defaults/base"
import { ODPluginManager_Default } from "./defaults/plugin"
import { ODEventManager_Default } from "./defaults/event"
import { ODConfigManager_Default} from "./defaults/config"
import { ODDatabaseManager_Default } from "./defaults/database"
import { ODFlagManager_Default } from "./defaults/flag"
import { ODSessionManager_Default } from "./defaults/session"
import { ODLanguageManager_Default } from "./defaults/language"
import { ODCheckerFunctionManager_Default, ODCheckerManager_Default, ODCheckerRenderer_Default, ODCheckerTranslationRegister_Default } from "./defaults/checker"
import { ODClientManager_Default } from "./defaults/client"
import { ODBuilderManager_Default } from "./defaults/builder"
import { ODResponderManager_Default } from "./defaults/responder"
import { ODActionManager_Default } from "./defaults/action"
import { ODPermissionManager_Default } from "./defaults/permission"
import { ODHelpMenuManager_Default } from "./defaults/helpmenu"
import { ODStatsManager_Default } from "./defaults/stat"
import { ODCodeManager_Default } from "./defaults/code"
import { ODCooldownManager_Default } from "./defaults/cooldown"
import { ODPostManager_Default } from "./defaults/post"
import { ODVerifyBarManager_Default } from "./defaults/verifybar"
import { ODProgressBarManager_Default } from "./defaults/progressbar"
import { ODStartScreenManager_Default } from "./defaults/startscreen"
import { ODLiveStatusManager_Default } from "./defaults/console"
//OPEN TICKET MODULES
import { ODOptionManager } from "./openticket/option"
import { ODPanelManager } from "./openticket/panel"
import { ODTicketManager } from "./openticket/ticket"
import { ODQuestionManager } from "./openticket/question"
import { ODBlacklistManager } from "./openticket/blacklist"
import { ODTranscriptManager_Default } from "./openticket/transcript"
import { ODRoleManager } from "./openticket/role"
import { ODPriorityManager_Default } from "./openticket/priority"
/**## ODMain `class`
* This is the main Open Ticket class.
* It contains all managers from the entire bot & has shortcuts to the event & logging system.
*
* This class can't be overwritten or extended & is available as the global variable `openticket`!
*/
export class ODMain {
/**The manager that handles all versions in the bot. */
versions: ODVersionManager_Default
/**The timestamp that the (node.js) process of the bot started. */
processStartupDate: Date = new Date()
/**The timestamp that the bot finished loading and is ready for usage. */
readyStartupDate: Date|null = null
/**The manager responsible for the debug file. (`otdebug.txt`) */
debugfile: ODDebugFileManager
/**The manager responsible for the console system. (logs, errors, etc) */
console: ODConsoleManager
/**The manager responsible for sending debug logs to the debug file. (`otdebug.txt`) */
debug: ODDebugger
/**The manager containing all Open Ticket events. */
events: ODEventManager_Default
/**The manager that handles & executes all plugins in the bot. */
plugins: ODPluginManager_Default
/**The manager that manages & checks all the console flags of the bot. (like `--debug`) */
flags: ODFlagManager_Default
/**The manager responsible for progress bars in the console. */
progressbars: ODProgressBarManager_Default
/**The manager that manages & contains all the config files of the bot. (like `config/general.json`) */
configs: ODConfigManager_Default
/**The manager that manages & contains all the databases of the bot. (like `database/global.json`) */
databases: ODDatabaseManager_Default
/**The manager that manages all the data sessions of the bot. (it's a temporary database) */
sessions: ODSessionManager_Default
/**The manager that manages all languages & translations of the bot. (but not for plugins) */
languages: ODLanguageManager_Default
/**The manager that handles & executes all config checkers in the bot. (the code that checks if you have something wrong in your config) */
checkers: ODCheckerManager_Default
/**The manager that manages all builders in the bot. (e.g. buttons, dropdowns, messages, modals, etc) */
builders: ODBuilderManager_Default
/**The manager that manages all responders in the bot. (e.g. commands, buttons, dropdowns, modals) */
responders: ODResponderManager_Default
/**The manager that manages all actions or procedures in the bot. (e.g. ticket-creation, ticket-deletion, ticket-claiming, etc) */
actions: ODActionManager_Default
/**The manager that manages all verify bars in the bot. (the ✅ ❌ buttons) */
verifybars: ODVerifyBarManager_Default
/**The manager that contains all permissions for commands & actions in the bot. (use it to check if someone has admin perms or not) */
permissions: ODPermissionManager_Default
/**The manager that contains all cooldowns of the bot. (e.g. ticket-cooldowns) */
cooldowns: ODCooldownManager_Default
/**The manager that manages & renders the Open Ticket help menu. (not the embed, but the text) */
helpmenu: ODHelpMenuManager_Default
/**The manager that manages, saves & renders the Open Ticket statistics. (not the embed, but the text & database) */
stats: ODStatsManager_Default
/**This manager is a place where you can put code that executes when the bot almost finishes the setup. (can be used for less important stuff that doesn't require an exact time-order) */
code: ODCodeManager_Default
/**The manager that manages all posts (static discord channels) in the bot. (e.g. (transcript) logs, etc) */
posts: ODPostManager_Default
/**The manager responsible for everything related to the client. (e.g. status, login, slash & text commands, etc) */
client: ODClientManager_Default
/**This manager contains A LOD of booleans. With these switches, you can turn off "default behaviours" from the bot. This is used if you want to replace the default Open Ticket code. */
defaults: ODDefaultsManager
/**This manager manages all the variables in the ENV. It reads from both the `.env` file & the `process.env`. (these 2 will be combined) */
env: ODEnvHelper
/**The manager responsible for the livestatus system. (remote console logs) */
livestatus: ODLiveStatusManager_Default
/**The manager responsible for the livestatus system. (remote console logs) */
startscreen: ODStartScreenManager_Default
//OPEN TICKET
/**The manager that manages all the data of questions in the bot. (these are used in options & tickets) */
questions: ODQuestionManager
/**The manager that manages all the data of options in the bot. (these are used for panels, ticket creation, reaction roles) */
options: ODOptionManager
/**The manager that manages all the data of panels in the bot. (panels contain the options) */
panels: ODPanelManager
/**The manager that manages all tickets in the bot. (here, you can get & edit a lot of data from tickets) */
tickets: ODTicketManager
/**The manager that manages the ticket blacklist. (people who are blacklisted can't create a ticket) */
blacklist: ODBlacklistManager
/**The manager that manages the ticket transcripts. (both the history & compilers) */
transcripts: ODTranscriptManager_Default
/**The manager that manages all reaction roles in the bot. (here, you can add additional data to roles) */
roles: ODRoleManager
/**The manager that manages all priority levels in the bot. (register/edit ticket priority levels) */
priorities: ODPriorityManager_Default
constructor(){
this.versions = new ODVersionManager_Default()
this.versions.add(ODVersion.fromString("opendiscord:version","v4.1.3"))
this.versions.add(ODVersion.fromString("opendiscord:api","v1.0.0"))
this.versions.add(ODVersion.fromString("opendiscord:transcripts","v2.1.0"))
this.versions.add(ODVersion.fromString("opendiscord:livestatus","v2.0.0"))
this.debugfile = new ODDebugFileManager("./","otdebug.txt",5000,this.versions.get("opendiscord:version"))
this.console = new ODConsoleManager(100,this.debugfile)
this.debug = new ODDebugger(this.console)
this.events = new ODEventManager_Default(this.debug)
this.plugins = new ODPluginManager_Default(this.debug)
this.flags = new ODFlagManager_Default(this.debug)
this.progressbars = new ODProgressBarManager_Default(this.debug)
this.configs = new ODConfigManager_Default(this.debug)
this.databases = new ODDatabaseManager_Default(this.debug)
this.sessions = new ODSessionManager_Default(this.debug)
this.languages = new ODLanguageManager_Default(this.debug,false)
this.checkers = new ODCheckerManager_Default(this.debug,new ODCheckerStorage(),new ODCheckerRenderer_Default(),new ODCheckerTranslationRegister_Default(),new ODCheckerFunctionManager_Default(this.debug))
this.builders = new ODBuilderManager_Default(this.debug)
this.client = new ODClientManager_Default(this.debug)
this.responders = new ODResponderManager_Default(this.debug,this.client)
this.actions = new ODActionManager_Default(this.debug)
this.verifybars = new ODVerifyBarManager_Default(this.debug)
this.permissions = new ODPermissionManager_Default(this.debug,this.client)
this.cooldowns = new ODCooldownManager_Default(this.debug)
this.helpmenu = new ODHelpMenuManager_Default(this.debug)
this.stats = new ODStatsManager_Default(this.debug)
this.code = new ODCodeManager_Default(this.debug)
this.posts = new ODPostManager_Default(this.debug)
this.defaults = new ODDefaultsManager()
this.env = new ODEnvHelper()
this.livestatus = new ODLiveStatusManager_Default(this.debug,this)
this.startscreen = new ODStartScreenManager_Default(this.debug,this.livestatus)
//OPEN TICKET
this.questions = new ODQuestionManager(this.debug)
this.options = new ODOptionManager(this.debug)
this.panels = new ODPanelManager(this.debug)
this.tickets = new ODTicketManager(this.debug,this.client)
this.blacklist = new ODBlacklistManager(this.debug)
this.transcripts = new ODTranscriptManager_Default(this.debug,this.tickets,this.client,this.permissions)
this.roles = new ODRoleManager(this.debug)
this.priorities = new ODPriorityManager_Default(this.debug)
}
/**Log a message to the console. But in the Open Ticket style :) */
log(message:ODConsoleMessage): void
log(message:ODError): void
log(message:string, type?:ODConsoleMessageTypes, params?:ODConsoleMessageParam[]): void
log(message:ODConsoleMessage|ODError|string, type?:ODConsoleMessageTypes, params?:ODConsoleMessageParam[]){
if (message instanceof ODConsoleMessage) this.console.log(message)
else if (message instanceof ODError) this.console.log(message)
else if (["string","number","boolean","object"].includes(typeof message)) this.console.log(message,type,params)
}
}
-58
View File
@@ -1,58 +0,0 @@
///////////////////////////////////////
//ACTION MODULE
///////////////////////////////////////
import { ODId, ODManager, ODValidId, ODSystemError, ODManagerData } from "./base"
import { ODWorkerManager, ODWorkerCallback, ODWorker } from "./worker"
import { ODDebugger } from "./console"
/**## ODActionImplementation `class`
* This is an Open Ticket action implementation.
*
* It is a basic implementation of the `ODWorkerManager` used by all `ODAction` classes.
*
* This class can't be used stand-alone & needs to be extended from!
*/
export class ODActionImplementation<Source extends string,Params extends object,Result extends object> extends ODManagerData {
/**The manager that has all workers of this implementation */
workers: ODWorkerManager<object,Source,Params>
constructor(id:ODValidId, callback?:ODWorkerCallback<object,Source,Params>, priority?:number, callbackId?:ODValidId){
super(id)
this.workers = new ODWorkerManager("descending")
if (callback) this.workers.add(new ODWorker(callbackId ? callbackId : id,priority ?? 0,callback))
}
/**Execute all workers & return the result. */
async run(source:Source, params:Params): Promise<Partial<Result>> {
throw new ODSystemError("Tried to build an unimplemented ODResponderImplementation")
}
}
/**## ODActionManager `class`
* This is an Open Ticket action manager.
*
* It contains all Open Ticket actions. You can compare actions with some sort of "procedure".
* It's a complicated task that is divided into multiple functions.
*
* Some examples are `ticket-creation`, `ticket-closing`, `ticket-claiming`, ...
*
* It's recommended to use this system in combination with Open Ticket responders!
*/
export class ODActionManager extends ODManager<ODAction<string,{},{}>> {
constructor(debug:ODDebugger){
super(debug,"action")
}
}
export class ODAction<Source extends string,Params extends object,Result extends object> extends ODActionImplementation<Source,Params,Result> {
/**Run this action */
async run(source:Source, params:Params): Promise<Partial<Result>> {
//create instance
const instance = {}
//wait for workers to finish
await this.workers.executeWorkers(instance,source,params)
//return data generated by workers
return instance
}
}
-763
View File
@@ -1,763 +0,0 @@
///////////////////////////////////////
//BASE MODULE
///////////////////////////////////////
import * as fs from "fs"
import { ODConsoleWarningMessage, ODDebugger } from "./console"
/**## ODPromiseVoid `type`
* This is a simple type to represent a callback return value that could be a promise or not.
*/
export type ODPromiseVoid = void|Promise<void>
/**## ODOptionalPromise `type`
* This is a simple type to represent a type as normal value or a promise value.
*/
export type ODOptionalPromise<T> = T|Promise<T>
/**## ODValidButtonColor `type`
* This is a collection of all the possible button colors.
*/
export type ODValidButtonColor = "gray"|"red"|"green"|"blue"
/**## ODValidId `type`
* This is a valid Open Ticket identifier. It can be an `ODId` or `string`!
*
* You will see this type in many functions from Open Ticket.
*/
export type ODValidId = string|ODId
/**## ODValidJsonType `type`
* This is a collection of all types that can be stored in a JSON file!
*
* list: `string`, `number`, `boolean`, `array`, `object`, `null`
*/
export type ODValidJsonType = string|number|boolean|object|ODValidJsonType[]|null
/**## ODInterfaceWithPartialProperty `type`
* This is a utility type to create an interface where some properties are optional!
*/
export type ODInterfaceWithPartialProperty<Interface,Key extends keyof Interface> = Omit<Interface,Key> & Partial<Pick<Interface,Key>>
/**## ODDiscordIdType `type`
* A list of all available discord ID types. Used in the config checker.
*/
export type ODDiscordIdType = "role"|"server"|"channel"|"category"|"user"|"member"|"interaction"|"message"
/**## ODId `class`
* This is an Open Ticket identifier.
*
* It can only contain the following characters: `a-z`, `A-Z`, `0-9`, `:`, `-` & `_`
*
* You can use this class to assign a unique id when creating configs, databases, languages & more!
*/
export class ODId {
/**The full value of this `ODId` as a `string`. */
#value: string
/**The full value of this `ODId` as a `string`. */
set value(id:string){
this._change(this.#value,id)
this.#value = id
}
get value(){
return this.#value
}
/**The change listener for the parent `ODManager` of this `ODId`. */
#change: ((oldId:string,newId:string) => void)|null = null
constructor(id:ODValidId){
if (typeof id != "string" && !(id instanceof ODId)) throw new ODSystemError("Invalid constructor parameter => id:ODValidId")
if (typeof id == "string"){
//id is string
const result: string[] = []
const charregex = /[a-zA-Z0-9éèçàêâôûî\:\-\_]/
id.split("").forEach((char) => {
if (charregex.test(char)){
result.push(char)
}
})
if (result.length > 0) this.#value = result.join("")
else throw new ODSystemError("invalid ID at 'new ODID(id: "+id+")'")
}else{
//id is ODId
this.#value = id.#value
}
}
/**Returns a string representation of this id. (same as `this.value`) */
toString(){
return this.#value
}
/**The namespace of the id before `:`. (e.g. `openticket` for `openticket:autoclose-enabled`) */
getNamespace(){
const splitted = this.#value.split(":")
if (splitted.length > 1) return splitted[0]
else return ""
}
/**The identifier of the id after `:`. (e.g. `autoclose-enabled` for `openticket:autoclose-enabled`) */
getIdentifier(){
const splitted = this.#value.split(":")
if (splitted.length > 1){
splitted.shift()
return splitted.join(":")
}else return this.#value
}
/**Trigger an `onChange()` event in the parent `ODManager` of this class. */
protected _change(oldId:string,newId:string){
if (this.#change){
try{
this.#change(oldId,newId)
}catch(err){
process.emit("uncaughtException",err)
throw new ODSystemError("Failed to execute _change() callback!")
}
}
}
/****(❌ SYSTEM ONLY!!)** Set the callback executed when a value inside this class changes. */
changed(callback:((oldId:string,newId:string) => void)|null){
this.#change = callback
}
}
/**## ODManagerChangeHelper `class`
* This is an Open Ticket manager change helper.
*
* It is used to let the "onChange" event in the `ODManager` class work.
* You can use this class when extending your own `ODManager`
*/
export class ODManagerChangeHelper {
#change: (() => void)|null = null
/**Trigger an `onChange()` event in the parent `ODManager` of this class. */
protected _change(){
if (this.#change){
try{
this.#change()
}catch(err){
process.emit("uncaughtException",err)
throw new ODSystemError("Failed to execute _change() callback!")
}
}
}
/****(❌ SYSTEM ONLY!!)** Set the callback executed when a value inside this class changes. */
changed(callback:(() => void)|null){
this.#change = callback
}
}
/**## ODManagerData `class`
* This is Open Ticket manager data.
*
* It provides a template for all classes that are used in the `ODManager`.
*
* There is an `id:ODId` property & also some events used in the manager.
*/
export class ODManagerData extends ODManagerChangeHelper {
/**The id of this data. */
id: ODId
constructor(id:ODValidId){
if (typeof id != "string" && !(id instanceof ODId)) throw new ODSystemError("Invalid constructor parameter => id:ODValidId")
super()
this.id = new ODId(id)
}
}
/**## ODManagerCallback `type`
* This is a callback for the `onChange` and `onRemove` events in the `ODManager`
*/
export type ODManagerCallback<DataType extends ODManagerData> = (data:DataType) => void
/**## ODManagerAddCallback `type`
* This is a callback for the `onAdd` event in the `ODManager`
*/
export type ODManagerAddCallback<DataType extends ODManagerData> = (data:DataType, overwritten:boolean) => void
/**## ODManager `class`
* This is an Open Ticket manager.
*
* It can be used to store & manage classes based on their `ODId`.
* It is somewhat the same as the default JS `Map()`.
* You can extend this class when creating your own classes & managers.
*
* This class has many useful functions based on `ODId` (add, get, remove, getAll, getFiltered, exists, loopAll, ...)
*/
export class ODManager<DataType extends ODManagerData> extends ODManagerChangeHelper {
/**Alias to Open Ticket debugger. */
#debug?: ODDebugger
/**The message to send when debugging this manager. */
#debugname?: string
/**The map storing all data classes in this manager. */
#data: Map<string,DataType> = new Map()
/**An array storing all listeners when data is added. */
#addListeners: ODManagerAddCallback<DataType>[] = []
/**An array storing all listeners when data has changed. */
#changeListeners: ODManagerCallback<DataType>[] = []
/**An array storing all listeners when data is removed. */
#removeListeners: ODManagerCallback<DataType>[] = []
constructor(debug?:ODDebugger, debugname?:string){
super()
this.#debug = debug
this.#debugname = debugname
}
/**Add data to the manager. The `ODId` in the data class will be used as identifier! You can optionally select to overwrite existing data!*/
add(data:DataType|DataType[], overwrite?:boolean): boolean {
//repeat same command when data is an array
if (Array.isArray(data)){
data.forEach((arrayData) => {
this.add(arrayData,overwrite)
})
return false
}
//add listener for data id change => transfer data within manager
data.id.changed((oldId,newId) => {
this.#data.delete(oldId)
this.#data.set(newId,data)
})
//add data
let didOverwrite: boolean
if (this.#data.has(data.id.value)){
if (!overwrite) throw new ODSystemError("Id '"+data.id.value+"' already exists in "+this.#debugname+" manager. Use 'overwrite:true' to allow overwriting!")
this.#data.set(data.id.value,data)
didOverwrite = true
if (this.#debug) this.#debug.debug("Added new "+this.#debugname+" to manager",[{key:"id",value:data.id.value},{key:"overwrite",value:"true"}])
}else{
this.#data.set(data.id.value,data)
didOverwrite = false
if (this.#debug) this.#debug.debug("Added new "+this.#debugname+" to manager",[{key:"id",value:data.id.value},{key:"overwrite",value:"false"}])
}
//emit change listeners
data.changed(() => {
//notify change in upper-manager (because data in this manager changed)
this._change()
this.#changeListeners.forEach((cb) => {
try{
cb(data)
}catch(err){
throw new ODSystemError("Failed to run manager onChange() listener.\n"+err)
}
})
})
//emit add listeners
this.#addListeners.forEach((cb) => {
try{
cb(data,didOverwrite)
}catch(err){
throw new ODSystemError("Failed to run manager onAdd() listener.\n"+err)
}
})
//notify change in upper-manager (because data added)
this._change()
return didOverwrite
}
/**Get data that matches the `ODId`. Returns the found data.*/
get(id:ODValidId): DataType|null {
const newId = new ODId(id)
const data = this.#data.get(newId.value)
if (data) return data
else return null
}
/**Remove data that matches the `ODId`. Returns the removed data. */
remove(id:ODValidId): DataType|null {
const newId = new ODId(id)
const data = this.#data.get(newId.value)
if (!data){
if (this.#debug) this.#debug.debug("Removed "+this.#debugname+" from manager",[{key:"id",value:newId.value},{key:"found",value:"false"}])
return null
}else{
this.#data.delete(newId.value)
if (this.#debug) this.#debug.debug("Removed "+this.#debugname+" from manager",[{key:"id",value:newId.value},{key:"found",value:"true"}])
}
//remove all listeners
data.id.changed(null)
data.changed(null)
//emit remove listeners
this.#removeListeners.forEach((cb) => {
try{
cb(data)
}catch(err){
throw new ODSystemError("Failed to run manager onRemove() listener.\n"+err)
}
})
//notify change in upper-manager (because data removed)
this._change()
return data
}
/**Check if data that matches the `ODId` exists. Returns a boolean. */
exists(id:ODValidId): boolean {
const newId = new ODId(id)
if (this.#data.has(newId.value)) return true
else return false
}
/**Get all data inside this manager*/
getAll(): DataType[] {
return Array.from(this.#data.values())
}
/**Get all data that matches inside the filter function*/
getFiltered(predicate:(value:DataType, index:number, array:DataType[]) => unknown): DataType[] {
return Array.from(this.#data.values()).filter(predicate)
}
/**Get all data where the `ODId` matches the provided RegExp. */
getRegex(regex:RegExp): DataType[] {
return Array.from(this.#data.values()).filter((data) => regex.test(data.id.value))
}
/**Get the length/size/amount of the data inside this manager. */
getLength(){
return this.#data.size
}
/**Get a list of all the ids inside this manager*/
getIds(): ODId[] {
const ids = Array.from(this.#data.keys())
return ids.map((id) => new ODId(id))
}
/**Run an iterator over all data in this manager. This method also supports async-await behaviour!*/
async loopAll(cb:(data:DataType,id:ODId) => ODPromiseVoid): Promise<void> {
for (const data of this.getAll()){
await cb(data,data.id)
}
}
/**Use the Open Ticket debugger in this manager for logs*/
useDebug(debug?:ODDebugger, debugname?:string){
this.#debug = debug
this.#debugname = debugname
}
/**Listen for when data is added to this manager. */
onAdd(callback:ODManagerAddCallback<DataType>){
this.#addListeners.push(callback)
}
/**Listen for when data is changed in this manager. */
onChange(callback:ODManagerCallback<DataType>){
this.#changeListeners.push(callback)
}
/**Listen for when data is removed from this manager. */
onRemove(callback:ODManagerCallback<DataType>){
this.#removeListeners.push(callback)
}
}
/**## ODManagerWithSafety `class`
* This is an Open Ticket safe manager.
*
* It functions exactly the same as a normal `ODManager`, but it has 1 function extra!
* The `getSafe()` function will always return data, because when it doesn't find an id, it returns pre-configured backup data.
*/
export class ODManagerWithSafety<DataType extends ODManagerData> extends ODManager<DataType> {
/**The function that creates backup data returned in `getSafe()` when an id is missing in this manager. */
#backupCreator: () => DataType
/** Temporary storage for manager debug name. */
#debugname: string
constructor(backupCreator:() => DataType, debug?:ODDebugger, debugname?:string){
super(debug,debugname)
this.#backupCreator = backupCreator
this.#debugname = debugname ?? "unknown"
}
/**Get data that matches the `ODId`. Returns the backup data when not found.
*
* ### ⚠️ This should only be used when the data doesn't need to be written/edited
*/
getSafe(id:ODValidId): DataType {
const data = super.get(id)
if (!data){
process.emit("uncaughtException",new ODSystemError("ODManagerWithSafety:getSafe(\""+id+"\") => Unknown Id => Used backup data ("+this.#debugname+" manager)"))
return this.#backupCreator()
}
else return data
}
}
/**## ODVersionManager `class`
* A Open Ticket version manager.
*
* It is used to manage different `ODVersion`'s from the bot. You will use it to check which version of the bot is used.
*/
export class ODVersionManager extends ODManager<ODVersion> {
constructor(){
super()
}
}
/**## ODVersion `class`
* This is an Open Ticket version.
*
* It has many features like comparing versions & checking if they are compatible.
*
* You can use it in your own plugin, but most of the time you will use it to check the Open Ticket version!
*/
export class ODVersion extends ODManagerData {
/**The first number of the version (example: `v1.2.3` => `1`) */
primary: number
/**The second number of the version (example: `v1.2.3` => `2`) */
secondary: number
/**The third number of the version (example: `v1.2.3` => `3`) */
tertiary: number
constructor(id:ODValidId, primary:number, secondary:number, tertiary:number){
super(id)
if (typeof primary != "number") throw new ODSystemError("Invalid constructor parameter => primary:number")
if (typeof secondary != "number") throw new ODSystemError("Invalid constructor parameter => secondary:number")
if (typeof tertiary != "number") throw new ODSystemError("Invalid constructor parameter => tertiary:number")
this.primary = primary
this.secondary = secondary
this.tertiary = tertiary
}
/**Get the version from a string (also possible with `v` prefix)
* @example const version = api.ODVersion.fromString("id","v1.2.3") //creates version 1.2.3
*/
static fromString(id:ODValidId, version:string){
if (typeof id != "string" && !(id instanceof ODId)) throw new ODSystemError("Invalid function parameter => id:ODValidId")
if (typeof version != "string") throw new ODSystemError("Invalid function parameter => version:string")
const versionCheck = (version.startsWith("v")) ? version.substring(1) : version
const splittedVersion = versionCheck.split(".")
return new this(id,Number(splittedVersion[0]),Number(splittedVersion[1]),Number(splittedVersion[2]))
}
/**Get the version as a string (`noprefix:true` => with `v` prefix)
* @example
* new api.ODVersion(1,0,0).toString(false) //returns "v1.0.0"
* new api.ODVersion(1,0,0).toString(true) //returns "1.0.0"
*/
toString(noprefix?:boolean){
const prefix = noprefix ? "" : "v"
return prefix+[this.primary,this.secondary,this.tertiary].join(".")
}
/**Compare this version with another version and returns the result: `higher`, `lower` or `equal`
* @example
* new api.ODVersion(1,0,0).compare(new api.ODVersion(1,2,0)) //returns "lower"
* new api.ODVersion(1,3,0).compare(new api.ODVersion(1,2,0)) //returns "higher"
* new api.ODVersion(1,2,0).compare(new api.ODVersion(1,2,0)) //returns "equal"
*/
compare(comparator:ODVersion): "higher"|"lower"|"equal" {
if (!(comparator instanceof ODVersion)) throw new ODSystemError("Invalid function parameter => comparator:ODVersion")
if (this.primary < comparator.primary) return "lower"
else if (this.primary > comparator.primary) return "higher"
else {
if (this.secondary < comparator.secondary) return "lower"
else if (this.secondary > comparator.secondary) return "higher"
else {
if (this.tertiary < comparator.tertiary) return "lower"
else if (this.tertiary > comparator.tertiary) return "higher"
else return "equal"
}
}
}
/**Check if this version is included in the list
* @example
* const list = [
* new api.ODVersion(1,0,0),
* new api.ODVersion(1,0,1),
* new api.ODVersion(1,0,2)
* ]
* new api.ODVersion(1,0,0).compatible(list) //returns true
* new api.ODVersion(1,0,1).compatible(list) //returns true
* new api.ODVersion(1,0,3).compatible(list) //returns false
*/
compatible(list:ODVersion[]): boolean {
if (!Array.isArray(list)) throw new ODSystemError("Invalid function parameter => list:ODVersion[]")
if (!list.every((v) => (v instanceof ODVersion))) throw new ODSystemError("Invalid function parameter => list:ODVersion[]")
return list.some((v) => {
return (v.toString() === this.toString())
})
}
/**Check if this version is higher or equal to the provided `requirement`. */
min(requirement:string|ODVersion){
if (typeof requirement == "string") requirement = ODVersion.fromString("temp",requirement)
//skip when primary version is higher or lower than current one.
if (this.primary < requirement.primary) return false
else if (this.primary > requirement.primary) return true
//skip when secondary version is higher or lower than current one.
if (this.secondary < requirement.secondary) return false
else if (this.secondary > requirement.secondary) return true
//skip when tertiary version is higher or lower than current one.
if (this.tertiary < requirement.tertiary) return false
else if (this.tertiary > requirement.tertiary) return true
return true
}
/**Check if this version is lower or equal to the provided `requirement`. */
max(requirement:string|ODVersion){
if (typeof requirement == "string") requirement = ODVersion.fromString("temp",requirement)
//skip when primary version is higher or lower than current one.
if (this.primary < requirement.primary) return true
else if (this.primary > requirement.primary) return false
//skip when secondary version is higher or lower than current one.
if (this.secondary < requirement.secondary) return true
else if (this.secondary > requirement.secondary) return false
//skip when tertiary version is higher or lower than current one.
if (this.tertiary < requirement.tertiary) return true
else if (this.tertiary > requirement.tertiary) return false
return true
}
/**Check if this version is matches the major version (`vX.X`) of the provided `requirement`. */
major(requirement:string|ODVersion){
if (typeof requirement == "string") requirement = ODVersion.fromString("temp",requirement)
return (this.primary == requirement.primary && this.secondary == requirement.secondary)
}
/**Check if this version is matches the minor version (`vX.X.X`) of the provided `requirement`. */
minor(requirement:string|ODVersion){
if (typeof requirement == "string") requirement = ODVersion.fromString("temp",requirement)
return (this.primary == requirement.primary && this.secondary == requirement.secondary && this.tertiary == requirement.tertiary)
}
}
/**## ODHTTPGetRequest `class`
* This is a class that can help you with creating simple HTTP GET requests.
*
* It works using the native node.js fetch() method. You can configure all options in the constructor!
* @example
* const request = new api.ODHTTPGetRequest("https://www.example.com/abc.txt",false,{})
*
* const result = await request.run()
* result.body //the response body (string)
* result.status //the response code (number)
* result.response //the full response (object)
*/
export class ODHTTPGetRequest {
/**The url used in the request */
url: string
/**The request config for additional options */
config: RequestInit
/**Throw on error OR return http code 500 */
throwOnError: boolean
constructor(url:string,throwOnError:boolean,config?:RequestInit){
if (typeof url != "string") throw new ODSystemError("Invalid constructor parameter => url:string")
if (typeof throwOnError != "boolean") throw new ODSystemError("Invalid constructor parameter => throwOnError:boolean")
if (typeof config != "undefined" && typeof config != "object") throw new ODSystemError("Invalid constructor parameter => config?:RequestInit")
this.url = url
this.throwOnError = throwOnError
const newConfig = config ?? {}
newConfig.method = "GET"
if (newConfig.headers) Object.assign(newConfig.headers,{"User-Agent":"OpenDiscordBots-OpenTicket/4.1.3"})
else newConfig.headers = {"User-Agent":"OpenDiscordBots-OpenTicket/4.1.3"}
this.config = newConfig
}
/**Execute the GET request.*/
run(): Promise<{status:number, body:string, response?:Response}> {
return new Promise(async (resolve,reject) => {
try{
const response = await fetch(this.url,this.config)
resolve({
status:response.status,
body:(await response.text()),
response:response
})
}catch(err){
if (this.throwOnError) return reject("[OPENTICKET ERROR]: ODHTTPGetRequest => Unknown fetch() error: "+err)
else return resolve({
status:500,
body:"Open Ticket Error: Unknown fetch() error: "+err,
})
}
})
}
}
/**## ODHTTPPostRequest `class`
* This is a class that can help you with creating simple HTTP POST requests.
*
* It works using the native node.js fetch() method. You can configure all options in the constructor!
* @example
* const request = new api.ODHTTPPostRequest("https://www.example.com/abc.txt",false,{})
*
* const result = await request.run()
* result.body //the response body (string)
* result.status //the response code (number)
* result.response //the full response (object)
*/
export class ODHTTPPostRequest {
/**The url used in the request */
url: string
/**The request config for additional options */
config: RequestInit
/**Throw on error OR return http code 500 */
throwOnError: boolean
constructor(url:string,throwOnError:boolean,config?:RequestInit){
if (typeof url != "string") throw new ODSystemError("Invalid constructor parameter => url:string")
if (typeof throwOnError != "boolean") throw new ODSystemError("Invalid constructor parameter => throwOnError:boolean")
if (typeof config != "undefined" && typeof config != "object") throw new ODSystemError("Invalid constructor parameter => config?:RequestInit")
this.url = url
this.throwOnError = throwOnError
const newConfig = config ?? {}
newConfig.method = "POST"
if (newConfig.headers) Object.assign(newConfig.headers,{"User-Agent":"OpenDiscordBots-OpenTicket/4.1.3"})
else newConfig.headers = {"User-Agent":"OpenDiscordBots-OpenTicket/4.1.3"}
this.config = newConfig
}
/**Execute the POST request.*/
run(): Promise<{status:number, body:string, response?:Response}> {
return new Promise(async (resolve,reject) => {
try{
const response = await fetch(this.url,this.config)
resolve({
status:response.status,
body:(await response.text()),
response:response
})
}catch(err){
if (this.throwOnError) return reject("[OPENTICKET ERROR]: ODHTTPPostRequest => Unknown fetch() error: "+err)
else return resolve({
status:500,
body:"Open Ticket Error: Unknown fetch() error!",
})
}
})
}
}
/**## ODEnvHelper `class`
* This is a utility class that helps you with reading the ENV.
*
* It has support for the built-in `process.env` & `.env` file
* @example
* const envHelper = new api.ODEnvHelper()
*
* const variableA = envHelper.getVariable("value-a")
* const variableB = envHelper.getVariable("value-b","dotenv") //only get from .env
* const variableA = envHelper.getVariable("value-c","env") //only get from process.env
*/
export class ODEnvHelper {
/**All variables found in the `.env` file */
dotenv: object
/**All variables found in `process.env` */
env: object
constructor(customEnvPath?:string){
if (typeof customEnvPath != "undefined" && typeof customEnvPath != "string") throw new ODSystemError("Invalid constructor parameter => customEnvPath?:string")
const path = customEnvPath ? customEnvPath : ".env"
this.dotenv = fs.existsSync(path) ? this.#readDotEnv(fs.readFileSync(path)) : {}
this.env = process.env
}
/**Get a variable from the env */
getVariable(name:string,source?:"dotenv"|"env"): any|undefined {
if (typeof name != "string") throw new ODSystemError("Invalid function parameter => name:string")
if ((typeof source != "undefined" && typeof source != "string") || (source && !["env","dotenv"].includes(source))) throw new ODSystemError("Invalid function parameter => source:'dotenv'|'env'")
if (source == "dotenv"){
return this.dotenv[name]
}else if (source == "env"){
return this.env[name]
}else{
//when no source specified => .env has priority over process.env
if (this.dotenv[name]) return this.dotenv[name]
else return this.env[name]
}
}
//THIS CODE IS COPIED FROM THE DODENV-LIB
//Repo: https://github.com/motdotla/dotenv
//Source: https://github.com/motdotla/dotenv/blob/master/lib/main.js#L12
#readDotEnv(src:Buffer){
const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg
const obj = {}
// Convert buffer to string
let lines = src.toString()
// Convert line breaks to same format
lines = lines.replace(/\r\n?/mg, '\n')
let match
while ((match = LINE.exec(lines)) != null) {
const key = match[1]
// Default undefined or null to empty string
let value = (match[2] || '')
// Remove whitespace
value = value.trim()
// Check if double quoted
const maybeQuote = value[0]
// Remove surrounding quotes
value = value.replace(/^(['"`])([\s\S]*)\1$/mg, '$2')
// Expand newlines if double quoted
if (maybeQuote === '"') {
value = value.replace(/\\n/g, '\n')
value = value.replace(/\\r/g, '\r')
}
// Add to object
obj[key] = value
}
return obj
}
}
/**## ODSystemError `class`
* A wrapper for the node.js `Error` class that makes the error look better in the console!
*
* This wrapper is made for Open Ticket system errors! **It can only be used by Open Ticket itself!**
*/
export class ODSystemError extends Error {
/**This variable gets detected by the error handling system to know how to render it */
_ODErrorType = "system"
/**Create an `ODSystemError` directly from an `Error` class */
static fromError(err:Error){
err["_ODErrorType"] = "system"
return err as ODSystemError
}
}
/**## ODPluginError `class`
* A wrapper for the node.js `Error` class that makes the error look better in the console!
*
* This wrapper is made for Open Ticket plugin errors! **It can only be used by plugins!**
*/
export class ODPluginError extends Error {
/**This variable gets detected by the error handling system to know how to render it */
_ODErrorType = "plugin"
/**Create an `ODPluginError` directly from an `Error` class */
static fromError(err:Error){
err["_ODErrorType"] = "plugin"
return err as ODPluginError
}
}
/**Oh, what could this be `¯\_(ツ)_/¯` */
export interface ODEasterEggs {
creator:string,
translators:string[]
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-58
View File
@@ -1,58 +0,0 @@
///////////////////////////////////////
//CODE MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODValidId } from "./base"
import { ODDebugger } from "./console"
/**## ODCode `class`
* This is an Open Ticket code runner.
*
* Using this, you're able to execute a function just before the startup screen. (90% of the code is already loaded)
* You can also specify a priority to change the execution order.
* In Open Ticket, this is used for the following processes:
* - Autoclose/delete
* - Database syncronisation (with tickets, stats & used options)
* - Panel auto-update
* - Database Garbage Collection (removing tickets that don't exist anymore)
* - And more!
*/
export class ODCode extends ODManagerData {
/**The priority of this code */
priority: number
/**The main function of this code */
func: () => void|Promise<void>
constructor(id:ODValidId, priority:number, func:() => void|Promise<void>){
super(id)
this.priority = priority
this.func = func
}
}
/**## ODCodeManager `class`
* This is an Open Ticket code manager.
*
* It manages & executes `ODCode`'s in the correct order.
*
* Use this to register a function/code which executes just before the startup screen. (90% is already loaded)
*/
export class ODCodeManager extends ODManager<ODCode> {
constructor(debug:ODDebugger){
super(debug,"code")
}
/**Execute all `ODCode` functions in order of their priority (high to low). */
async execute(){
const derefArray = [...this.getAll()]
const workers = derefArray.sort((a,b) => b.priority-a.priority)
for (const worker of workers){
try {
await worker.func()
}catch(err){
process.emit("uncaughtException",err)
}
}
}
}
-159
View File
@@ -1,159 +0,0 @@
///////////////////////////////////////
//CONFIG MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODPromiseVoid, ODSystemError, ODValidId } from "./base"
import nodepath from "path"
import { ODDebugger } from "./console"
import fs from "fs"
import * as fjs from "formatted-json-stringify"
/**## ODConfigManager `class`
* This is an Open Ticket config manager.
*
* It manages all config files in the bot and allows plugins to access config files from Open Ticket & other plugins!
*
* You can use this class to get/change/add a config file (`ODConfig`) in your plugin!
*/
export class ODConfigManager extends ODManager<ODConfig> {
/**Alias to Open Ticket debugger. */
#debug: ODDebugger
constructor(debug:ODDebugger){
super(debug,"config")
this.#debug = debug
}
add(data:ODConfig|ODConfig[],overwrite?:boolean): boolean {
if (Array.isArray(data)) data.forEach((d) => d.useDebug(this.#debug))
else data.useDebug(this.#debug)
return super.add(data,overwrite)
}
/**Init all config files. */
async init(){
for (const config of this.getAll()){
try{
await config.init()
}catch(err){
process.emit("uncaughtException",new ODSystemError(err))
}
}
}
}
/**## ODConfig `class`
* This is an Open Ticket config helper.
* This class doesn't do anything at all, it just gives a template & basic methods for a config. Use `ODJsonConfig` instead!
*
* You can use this class if you want to create your own config implementation (e.g. `yml`, `xml`,...)!
*/
export class ODConfig extends ODManagerData {
/**The name of the file with extension. */
file: string = ""
/**The path to the file relative to the main directory. */
path: string = ""
/**An object/array of the entire config file! Variables inside it can be edited while the bot is running! */
data: any
/**Is this config already initiated? */
initiated: boolean = false
/**An array of listeners to run when the config gets reloaded. These are not executed on the initial loading. */
protected reloadListeners: Function[] = []
/**Alias to Open Ticket debugger. */
protected debug: ODDebugger|null = null
constructor(id:ODValidId, data:any){
super(id)
this.data = data
}
/**Use the Open Ticket debugger for logs. */
useDebug(debug:ODDebugger|null){
this.debug = debug
}
/**Init the config. */
init(): ODPromiseVoid {
this.initiated = true
if (this.debug) this.debug.debug("Initiated config '"+this.file+"' in ODConfigManager.",[{key:"id",value:this.id.value}])
//please implement this feature in your own config extension & extend this function.
}
/**Reload the config. Be aware that this doesn't update the config data everywhere in the bot! */
reload(): ODPromiseVoid {
if (this.debug) this.debug.debug("Reloaded config '"+this.file+"' in ODConfigManager.",[{key:"id",value:this.id.value}])
//please implement this feature in your own config extension & extend this function.
}
/**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. */
save(): ODPromiseVoid {
if (this.debug) this.debug.debug("Saved config '"+this.file+"' in ODConfigManager.",[{key:"id",value:this.id.value}])
//please implement this feature in your own config extension & extend this function.
}
/**Listen for a reload of this JSON file! */
onReload(cb:Function){
this.reloadListeners.push(cb)
}
/**Remove all reload listeners. Not recommended! */
removeAllReloadListeners(){
this.reloadListeners = []
}
}
/**## ODJsonConfig `class`
* This is an Open Ticket JSON config.
* You can use this class to get & edit variables from the config files or to create your own JSON config!
* @example
* //create a config from: ./config/test.json with the id "some-config"
* const config = new api.ODJsonConfig("some-config","test.json")
*
* //create a config with custom dir: ./plugins/testplugin/test.json
* const config = new api.ODJsonConfig("plugin-config","test.json","./plugins/testplugin/")
*/
export class ODJsonConfig extends ODConfig {
formatter: fjs.custom.BaseFormatter
constructor(id:ODValidId, file:string, customPath?:string, formatter?:fjs.custom.BaseFormatter){
super(id,{})
this.file = (file.endsWith(".json")) ? file : file+".json"
this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./config/",this.file)
this.formatter = formatter ?? new fjs.DefaultFormatter(null,true," ")
}
/**Init the config. */
init(): ODPromiseVoid {
if (!fs.existsSync(this.path)) throw new ODSystemError("Unable to parse config \""+nodepath.join("./",this.path)+"\", the file doesn't exist!")
try{
this.data = JSON.parse(fs.readFileSync(this.path).toString())
super.init()
}catch(err){
process.emit("uncaughtException",err)
throw new ODSystemError("Unable to parse config \""+nodepath.join("./",this.path)+"\"!")
}
}
/**Reload the config. Be aware that this doesn't update the config data everywhere in the bot! */
reload(){
if (!this.initiated) throw new ODSystemError("Unable to reload config \""+nodepath.join("./",this.path)+"\", the file hasn't been initiated yet!")
if (!fs.existsSync(this.path)) throw new ODSystemError("Unable to reload config \""+nodepath.join("./",this.path)+"\", the file doesn't exist!")
try{
this.data = JSON.parse(fs.readFileSync(this.path).toString())
super.reload()
this.reloadListeners.forEach((cb) => {
try{
cb()
}catch(err){
process.emit("uncaughtException",err)
}
})
}catch(err){
process.emit("uncaughtException",err)
throw new ODSystemError("Unable to reload config \""+nodepath.join("./",this.path)+"\"!")
}
}
/**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. */
save(): ODPromiseVoid {
if (!this.initiated) throw new ODSystemError("Unable to save config \""+nodepath.join("./",this.path)+"\", the file hasn't been initiated yet!")
try{
const contents = this.formatter.stringify(this.data)
fs.writeFileSync(this.path,contents)
super.save()
}catch(err){
process.emit("uncaughtException",err)
throw new ODSystemError("Unable to save config \""+nodepath.join("./",this.path)+"\"!")
}
}
}
-665
View File
@@ -1,665 +0,0 @@
///////////////////////////////////////
//CONSOLE MODULE
///////////////////////////////////////
import { ODHTTPGetRequest, ODVersion, ODSystemError, ODPluginError, ODManager, ODManagerData, ODValidId } from "./base"
import { ODMain } from "../main"
import nodepath from "path"
import fs from "fs"
import ansis from "ansis"
/**## ODValidConsoleColor `type`
* This is a collection of all the supported console colors within Open Ticket.
*/
export type ODValidConsoleColor = "white"|"red"|"yellow"|"green"|"blue"|"gray"|"cyan"|"magenta"
/**## ODConsoleMessageParam `type`
* This interface contains all data required for a console log parameter within Open Ticket.
*/
export interface ODConsoleMessageParam {
/**The key of this parameter. */
key:string,
/**The value of this parameter. */
value:string,
/**When enabled, this parameter will only be shown in the debug file. */
hidden?:boolean
}
/**## ODConsoleMessage `class`
* This is an Open Ticket console message.
*
* It is used to create beautiful & styled logs in the console with a prefix, message & parameters.
* It also has full color support using `ansis` and parameters are parsed for you!
*/
export class ODConsoleMessage {
/**The main message sent in the console */
message: string
/**An array of all the parameters in this message */
params: ODConsoleMessageParam[]
/**The prefix of this message (!uppercase recommended!) */
prefix: string
/**The color of the prefix of this message */
color: ODValidConsoleColor
constructor(message:string, prefix:string, color:ODValidConsoleColor, params?:ODConsoleMessageParam[]){
this.message = message
this.params = params ? params : []
this.prefix = prefix
if (["white","red","yellow","green","blue","gray","cyan","magenta"].includes(color)){
this.color = color
}else{
this.color = "white"
}
}
/**Render this message to the console using `console.log`! Returns `false` when something went wrong. */
render(){
try {
const prefixcolor = ansis[this.color]
const paramsstring = " "+this.createParamsString("gray")
const message = prefixcolor("["+this.prefix+"] ")+this.message
console.log(message+paramsstring)
return true
}catch{
return false
}
}
/**Create a more-detailed, non-colored version of this message to store it in the `otdebug.txt` file! */
toDebugString(){
const pstrings: string[] = []
this.params.forEach((p) => {
pstrings.push(p.key+": "+p.value)
})
const pstring = (pstrings.length > 0) ? " ("+pstrings.join(", ")+")" : ""
const date = new Date()
const dstring = `${date.getDate()}/${date.getMonth()+1}/${date.getFullYear()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
return `[${dstring} ${this.prefix}] ${this.message}${pstring}`
}
/**Render the parameters of this message in a specific color. */
createParamsString(color:ODValidConsoleColor){
let validcolor: ODValidConsoleColor = "white"
if (["white","red","yellow","green","blue","gray","cyan","magenta"].includes(color)){
validcolor = color
}
const pstrings: string[] = []
this.params.forEach((p) => {
if (!p.hidden) pstrings.push(p.key+": "+p.value)
})
return (pstrings.length > 0) ? ansis[validcolor](" ("+pstrings.join(", ")+")") : ""
}
/**Set the message */
setMessage(message:string){
this.message = message
return this
}
/**Set the params */
setParams(params:ODConsoleMessageParam[]){
this.params = params
return this
}
/**Set the prefix */
setPrefix(prefix:string){
this.prefix = prefix
return this
}
/**Set the prefix color */
setColor(color:ODValidConsoleColor){
if (["white","red","yellow","green","blue","gray","cyan","magenta"].includes(color)){
this.color = color
}else{
this.color = "white"
}
return this
}
}
/**## ODConsoleInfoMessage `class`
* This is an Open Ticket console info message.
*
* It is the same as a normal `ODConsoleMessage`, but it has a predefined prefix & color scheme for the "INFO" messages!
*/
export class ODConsoleInfoMessage extends ODConsoleMessage {
constructor(message:string,params?:ODConsoleMessageParam[]){
super(message,"INFO","blue",params)
}
}
/**## ODConsoleSystemMessage `class`
* This is an Open Ticket console system message.
*
* It is the same as a normal `ODConsoleMessage`, but it has a predefined prefix & color scheme for the "SYSTEM" messages!
*/
export class ODConsoleSystemMessage extends ODConsoleMessage {
constructor(message:string,params?:ODConsoleMessageParam[]){
super(message,"SYSTEM","green",params)
}
}
/**## ODConsolePluginMessage `class`
* This is an Open Ticket console plugin message.
*
* It is the same as a normal `ODConsoleMessage`, but it has a predefined prefix & color scheme for the "PLUGIN" messages!
*/
export class ODConsolePluginMessage extends ODConsoleMessage {
constructor(message:string,params?:ODConsoleMessageParam[]){
super(message,"PLUGIN","magenta",params)
}
}
/**## ODConsoleDebugMessage `class`
* This is an Open Ticket console debug message.
*
* It is the same as a normal `ODConsoleMessage`, but it has a predefined prefix & color scheme for the "DEBUG" messages!
*/
export class ODConsoleDebugMessage extends ODConsoleMessage {
constructor(message:string,params?:ODConsoleMessageParam[]){
super(message,"DEBUG","cyan",params)
}
}
/**## ODConsoleWarningMessage `class`
* This is an Open Ticket console warning message.
*
* It is the same as a normal `ODConsoleMessage`, but it has a predefined prefix & color scheme for the "WARNING" messages!
*/
export class ODConsoleWarningMessage extends ODConsoleMessage {
constructor(message:string,params?:ODConsoleMessageParam[]){
super(message,"WARNING","yellow",params)
}
}
/**## ODConsoleErrorMessage `class`
* This is an Open Ticket console error message.
*
* It is the same as a normal `ODConsoleMessage`, but it has a predefined prefix & color scheme for the "ERROR" messages!
*/
export class ODConsoleErrorMessage extends ODConsoleMessage {
constructor(message:string,params?:ODConsoleMessageParam[]){
super(message,"ERROR","red",params)
}
}
/**## ODError `class`
* This is an Open Ticket error.
*
* It is used to render and log Node.js errors & crashes in a styled way to the console & `otdebug.txt` file!
*/
export class ODError {
/**The original error that this class wraps around */
error: Error|ODSystemError|ODPluginError
/**The origin of the original error */
origin: NodeJS.UncaughtExceptionOrigin
constructor(error:Error|ODSystemError|ODPluginError, origin:NodeJS.UncaughtExceptionOrigin){
this.error = error
this.origin = origin
}
/**Render this error to the console using `console.log`! Returns `false` when something went wrong. */
render(){
try {
let prefix = (this.error["_ODErrorType"] == "plugin") ? "PLUGIN ERROR" : ((this.error["_ODErrorType"] == "system") ? "OPENTICKET ERROR" : "UNKNOWN ERROR")
//title
console.log(ansis.red("["+prefix+"]: ")+this.error.message+" | origin: "+this.origin)
//stack trace
if (this.error.stack) console.log(ansis.gray(this.error.stack))
//additional message
if (this.error["_ODErrorType"] == "plugin") console.log(ansis.red.bold("\nPlease report this error to the plugin developer and help us create a more stable plugin!"))
else console.log(ansis.red.bold("\nPlease report this error to our discord server and help us create a more stable ticket bot!"))
console.log(ansis.red("Also send the "+ansis.cyan.bold("otdebug.txt")+" file! It would help a lot!\n"))
return true
}catch{
return false
}
}
/**Create a more-detailed, non-colored version of this error to store it in the `otdebug.txt` file! */
toDebugString(){
return "[UNKNOWN OD ERROR]: "+this.error.message+" | origin: "+this.origin+"\n"+this.error.stack
}
}
/**## ODConsoleMessageTypes `type`
* This is a collection of all the default console message types within Open Ticket.
*/
export type ODConsoleMessageTypes = "info"|"system"|"plugin"|"debug"|"warning"|"error"
/**## ODConsoleManager `class`
* This is the Open Ticket console manager.
*
* It handles the entire console system of Open Ticket. It's also the place where you need to log `ODConsoleMessage`'s.
* This manager keeps a short history of messages sent to the console which is configurable by plugins.
*
* The debug file (`otdebug.txt`) is handled in a sub-manager!
*/
export class ODConsoleManager {
/**The history of `ODConsoleMessage`'s and `ODError`'s since startup */
history: (ODConsoleMessage|ODError)[] = []
/**The max length of the history. The oldest messages will be removed when over the limit */
historylength = 100
/**An alias to the debugfile manager. (`otdebug.txt`) */
debugfile: ODDebugFileManager
/**Is silent mode enabled? */
silent: boolean = false
constructor(historylength:number, debugfile:ODDebugFileManager){
this.historylength = historylength
this.debugfile = debugfile
}
/**Log a message to the console ... But in the Open Ticket way :) */
log(message:ODConsoleMessage): void
log(message:ODError): void
log(message:string, type?:ODConsoleMessageTypes, params?:ODConsoleMessageParam[]): void
log(message:ODConsoleMessage|ODError|string, type?:ODConsoleMessageTypes, params?:ODConsoleMessageParam[]){
if (message instanceof ODConsoleMessage){
if (!this.silent) message.render()
if (this.debugfile) this.debugfile.writeConsoleMessage(message)
this.history.push(message)
}else if (message instanceof ODError){
if (!this.silent) message.render()
if (this.debugfile) this.debugfile.writeErrorMessage(message)
this.history.push(message)
}else if (["string","number","boolean","object"].includes(typeof message)){
let newMessage: ODConsoleMessage
if (type == "info") newMessage = new ODConsoleInfoMessage(message,params)
else if (type == "system") newMessage = new ODConsoleSystemMessage(message,params)
else if (type == "plugin") newMessage = new ODConsolePluginMessage(message,params)
else if (type == "debug") newMessage = new ODConsoleDebugMessage(message,params)
else if (type == "warning") newMessage = new ODConsoleWarningMessage(message,params)
else if (type == "error") newMessage = new ODConsoleErrorMessage(message,params)
else newMessage = new ODConsoleSystemMessage(message,params)
if (!this.silent) newMessage.render()
if (this.debugfile) this.debugfile.writeConsoleMessage(newMessage)
this.history.push(newMessage)
}
this.#purgeHistory()
}
/**Shorten the history when it exceeds the max history length! */
#purgeHistory(){
if (this.history.length > this.historylength) this.history.shift()
}
}
/**## ODDebugFileManager `class`
* This is the Open Ticket debug file manager.
*
* It manages the Open Ticket debug file (`otdebug.txt`) which keeps a history of all system logs.
* There are even internal logs that aren't logged to the console which are available in this file!
*
* Using this class, you can change the max length of this file and some other cool things!
*/
export class ODDebugFileManager {
/**The path to the debugfile (`./otdebug.txt` by default) */
path: string
/**The filename of the debugfile (`otdebug.txt` by default) */
filename: string
/**The current version of the bot used in the debug file. */
version: ODVersion
/**The max length of the debug file. */
maxlines: number
constructor(path:string, filename:string, maxlines:number, version:ODVersion){
this.path = nodepath.join(path,filename)
this.filename = filename
this.version = version
this.maxlines = maxlines
this.#writeStartupStats()
}
/**Check if the debug file exists */
#existsDebugFile(){
return fs.existsSync(this.path)
}
/**Read from the debug file */
#readDebugFile(){
if (this.#existsDebugFile()){
try {
return fs.readFileSync(this.path).toString()
}catch{
return false
}
}else{
return false
}
}
/**Write to the debug file and shorten it when needed. */
#writeDebugFile(text:string){
const currenttext = this.#readDebugFile()
if (currenttext){
const splitted = currenttext.split("\n")
if (splitted.length+text.split("\n").length > this.maxlines){
splitted.splice(7,(text.split("\n").length))
}
splitted.push(text)
fs.writeFileSync(this.path,splitted.join("\n"))
}else{
//write new file:
const newtext = this.#createStatsText()+text
fs.writeFileSync(this.path,newtext)
}
}
/**Generate the stats/header of the debug file (containing the version) */
#createStatsText(){
const date = new Date()
const dstring = `${date.getDate()}/${date.getMonth()+1}/${date.getFullYear()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
return [
"=========================",
"OPEN TICKET DEBUG FILE:",
"version: "+this.version.toString(),
"last startup: "+dstring,
"=========================\n\n"
].join("\n")
}
/**Write the stats/header to the debug file on startup */
#writeStartupStats(){
const currenttext = this.#readDebugFile()
if (currenttext){
//edit previous file:
const splitted = currenttext.split("\n")
splitted.splice(0,7)
if (splitted.length+11 > this.maxlines){
splitted.splice(0,((splitted.length+11) - this.maxlines))
}
splitted.unshift(this.#createStatsText())
splitted.push("\n---------------------------------------------------------------------\n---------------------------------------------------------------------\n")
fs.writeFileSync(this.path,splitted.join("\n"))
}else{
//write new file:
const newtext = this.#createStatsText()
fs.writeFileSync(this.path,newtext)
}
}
/**Write an `ODConsoleMessage` to the debug file */
writeConsoleMessage(message:ODConsoleMessage){
this.#writeDebugFile(message.toDebugString())
}
/**Write an `ODError` to the debug file */
writeErrorMessage(error:ODError){
this.#writeDebugFile(error.toDebugString())
}
/**Write custom text to the debug file */
writeText(text:string){
this.#writeDebugFile(text)
}
/**Write a custom note to the debug file (starting with `[NOTE]:`) */
writeNote(text:string){
this.#writeDebugFile("[NOTE]: "+text)
}
}
/**## ODDebugger `class`
* This is the Open Ticket debugger.
*
* It is a simple wrapper around the `ODConsoleManager` to handle debugging (primarily for `ODManagers`).
* Messages created using this debugger are only logged to the debug file unless specified otherwise.
*
* You will probably notice this class being used in the `ODManager` constructor.
*
* Using this system, all additions & removals inside a manager are logged to the debug file. This makes searching for errors a lot easier!
*/
export class ODDebugger {
/**An alias to the Open Ticket console manager. */
console: ODConsoleManager
/**When enabled, debug logs are also shown in the console. */
visible: boolean = false
constructor(console:ODConsoleManager){
this.console = console
}
/**Create a debug message. This will always be logged to `otdebug.txt` & sometimes to the console (when enabled). Returns `true` when visible */
debug(message:string, params?:{key:string,value:string}[]): boolean {
if (this.visible){
this.console.log(new ODConsoleDebugMessage(message,params))
return true
}else{
this.console.debugfile.writeConsoleMessage(new ODConsoleDebugMessage(message,params))
return false
}
}
}
/**## ODLivestatusColor `type`
* This is a collection of all the colors available within the LiveStatus system.
*/
export type ODLiveStatusColor = "normal"|"red"|"green"|"blue"|"yellow"|"white"|"gray"|"magenta"|"cyan"
/**## ODLiveStatusSourceData `interface`
* This is an interface containing all raw data received from the LiveStatus system.
*/
export interface ODLiveStatusSourceData {
/**The message to display */
message:{
/**The title of the message to display */
title:string,
/**The title color of the message to display */
titleColor:ODLiveStatusColor,
/**The description of the message to display */
description:string,
/**The description color of the message to display */
descriptionColor:ODLiveStatusColor
},
/**The message will only be shown when the bot matches all statements */
active:{
/**A list of versions to match */
versions:string[],
/**A list of languages to match */
languages:string[],
/**All languages should match */
allLanguages:boolean,
/**Match when the bot is using plugins */
usingPlugins:boolean,
/**Match when the bot is not using plugins */
notUsingPlugins:boolean,
/**Match when the bot is using slash commands */
usingSlashCommands:boolean,
/**Match when the bot is not using slash commands */
notUsingSlashCommands:boolean,
/**Match when the bot is not using transcripts */
notUsingTranscripts:boolean,
/**Match when the bot is using text transcripts */
usingTextTranscripts:boolean,
/**Match when the bot is using html transcripts */
usingHtmlTranscripts:boolean
}
}
/**## ODLiveStatusSource `class`
* This is the Open Ticket livestatus source.
*
* It is an empty template for a livestatus source.
* By default, you should use `ODLiveStatusUrlSource` or `ODLiveStatusFileSource`,
* unless you want to create one on your own!
*
* This class doesn't do anything on it's own! It's just a template!
*/
export class ODLiveStatusSource extends ODManagerData {
/**The raw data of this source */
data: ODLiveStatusSourceData[]
constructor(id:ODValidId, data:ODLiveStatusSourceData[]){
super(id)
this.data = data
}
/**Change the current data using this method! */
setData(data:ODLiveStatusSourceData[]){
this.data = data
}
/**Get all messages relevant to the bot based on some parameters. */
async getMessages(main:ODMain): Promise<ODLiveStatusSourceData[]> {
const validMessages: ODLiveStatusSourceData[] = []
//parse data from ODMain
const currentVersion: string = main.versions.get("opendiscord:version").toString(true)
const usingSlashCommands: boolean = main.configs.get("opendiscord:general").data.slashCommands
const usingTranscripts: false|"text"|"html" = false as false|"text"|"html" //TODO
const currentLanguage: string = main.languages.getCurrentLanguageId()
const usingPlugins: boolean = (main.plugins.getLength() > 0)
//check data for each message
this.data.forEach((msg) => {
const {active} = msg
const correctVersion = active.versions.includes(currentVersion)
const correctSlashMode = (usingSlashCommands && active.usingSlashCommands) || (!usingSlashCommands && active.notUsingSlashCommands)
const correctTranscriptMode = (usingTranscripts == "text" && active.usingTextTranscripts) || (usingTranscripts == "html" && active.usingHtmlTranscripts) || (!usingTranscripts && active.notUsingTranscripts)
const correctLanguage = active.languages.includes(currentLanguage) || active.allLanguages
const correctPlugins = (usingPlugins && active.usingPlugins) || (!usingPlugins && active.notUsingPlugins)
if (correctVersion && correctLanguage && correctPlugins && correctSlashMode && correctTranscriptMode) validMessages.push(msg)
})
//return the valid messages
return validMessages
}
}
/**## ODLiveStatusFileSource `class`
* This is the Open Ticket livestatus file source.
*
* It is a LiveStatus source that will read the data from a local file.
*
* This can be used for testing/extending the LiveStatus system!
*/
export class ODLiveStatusFileSource extends ODLiveStatusSource {
/**The path to the source file */
path: string
constructor(id:ODValidId, path:string){
if (fs.existsSync(path)){
super(id,JSON.parse(fs.readFileSync(path).toString()))
}else throw new ODSystemError("LiveStatus source file doesn't exist!")
this.path = path
}
}
/**## ODLiveStatusUrlSource `class`
* This is the Open Ticket livestatus url source.
*
* It is a LiveStatus source that will read the data from a http URL (json file).
*
* This is the default way of receiving LiveStatus messages!
*/
export class ODLiveStatusUrlSource extends ODLiveStatusSource {
/**The url used in the request */
url: string
/**The `ODHTTPGetRequest` helper to fetch the url! */
request: ODHTTPGetRequest
constructor(id:ODValidId, url:string){
super(id,[])
this.url = url
this.request = new ODHTTPGetRequest(url,false)
}
async getMessages(main:ODMain): Promise<ODLiveStatusSourceData[]> {
//additional setup
this.request.url = this.url
const rawRes = await this.request.run()
if (rawRes.status != 200) throw new ODSystemError("ODLiveStatusUrlSource => Request Failed!")
try{
this.setData(JSON.parse(rawRes.body))
}catch{
throw new ODSystemError("ODLiveStatusUrlSource => Request Failed!")
}
//default
return super.getMessages(main)
}
}
/**## ODLiveStatusManager `class`
* This is the Open Ticket livestatus manager.
*
* It manages all LiveStatus sources and has the renderer for all LiveStatus messages.
*
* You can use this to customise or add stuff to the LiveStatus system.
* Access it in the global `opendiscord.startscreen.livestatus` variable!
*/
export class ODLiveStatusManager extends ODManager<ODLiveStatusSource> {
/**The class responsible for rendering the livestatus messages. */
renderer: ODLiveStatusRenderer
/**A reference to the ODMain or "openticket" global variable */
#main: ODMain
constructor(debug:ODDebugger, main:ODMain){
super(debug,"livestatus source")
this.renderer = new ODLiveStatusRenderer(main.console)
this.#main = main
}
/**Get the messages from all sources combined! */
async getAllMessages(): Promise<ODLiveStatusSourceData[]> {
const messages: ODLiveStatusSourceData[] = []
for (const source of this.getAll()){
try {
messages.push(...(await source.getMessages(this.#main)))
}catch{}
}
return messages
}
}
/**## ODLiveStatusRenderer `class`
* This is the Open Ticket livestatus renderer.
*
* It's responsible for rendering all LiveStatus messages to the console.
*/
export class ODLiveStatusRenderer {
/**A reference to the ODConsoleManager or "opendiscord.console" global variable */
#console: ODConsoleManager
constructor(console:ODConsoleManager){
this.#console = console
}
/**Render all messages */
render(messages:ODLiveStatusSourceData[]): string {
try {
//process data
const final: string[] = []
messages.forEach((msg) => {
const titleColor = msg.message.titleColor
const title = "["+msg.message.title+"] "
const descriptionColor = msg.message.descriptionColor
const description = msg.message.description.split("\n").map((text,row) => {
//first row row doesn't need prefix
if (row < 1) return text
//other rows do need a prefix
let text2 = text
for (const i of title){
text2 = " "+text2
}
return text2
}).join("\n")
if (!["red","yellow","green","blue","gray","magenta","cyan"].includes(titleColor)) var finalTitle = ansis.white(title)
else var finalTitle = ansis[titleColor](title)
if (!["red","yellow","green","blue","gray","magenta","cyan"].includes(descriptionColor)) var finalDescription = ansis.white(description)
else var finalDescription = ansis[descriptionColor](description)
final.push(finalTitle+finalDescription)
})
//return all messages
return final.join("\n")
}catch{
this.#console.log("Failed to render LiveStatus messages!","error")
return ""
}
}
}
-348
View File
@@ -1,348 +0,0 @@
///////////////////////////////////////
//COOLDOWN MODULE
///////////////////////////////////////
import { ODId, ODValidId, ODManager, ODSystemError, ODManagerData } from "./base"
import { ODDebugger } from "./console"
/**## ODCooldownManager `class`
* This is an Open Ticket cooldown manager.
*
* It is responsible for managing all cooldowns in Open Ticket. An example of this is the ticket creation cooldown.
*
* There are many types of cooldowns available, but you can also create your own!
*/
export class ODCooldownManager extends ODManager<ODCooldown<object>> {
constructor(debug:ODDebugger){
super(debug,"cooldown")
}
/**Initiate all cooldowns in this manager. */
async init(){
for (const cooldown of this.getAll()){
await cooldown.init()
}
}
}
/**## ODCooldownData `class`
* This is Open Ticket cooldown data.
*
* It contains the instance of an active cooldown (e.g. for a user). It is handled by the cooldown itself.
*/
export class ODCooldownData<Data extends object> extends ODManagerData {
/**Is this cooldown active? */
active: boolean
/**Additional data of this cooldown instance. (different for each cooldown type) */
data: Data
constructor(id:ODValidId,active:boolean,data:Data){
super(id)
this.active = active
this.data = data
}
}
/**## ODCooldown `class`
* This is an Open Ticket cooldown.
*
* It doesn't do anything on it's own, but it provides the methods that are used to interact with a cooldown.
* This class can be extended from to create a working cooldown.
*
* There are also premade cooldowns available in the bot!
*/
export class ODCooldown<Data extends object> extends ODManagerData {
data: ODManager<ODCooldownData<Data>> = new ODManager()
/**Is this cooldown already initialized? */
ready: boolean = false
constructor(id:ODValidId){
super(id)
}
/**Check this id and start cooldown when it exeeds the limit! Returns `true` when on cooldown! */
use(id:string): boolean {
throw new ODSystemError("Tried to use an unimplemented ODCooldown!")
}
/**Check this id without starting or updating the cooldown. Returns `true` when on cooldown! */
check(id:string): boolean {
throw new ODSystemError("Tried to use an unimplemented ODCooldown!")
}
/**Remove the cooldown for an id when available.*/
delete(id:string){
throw new ODSystemError("Tried to use an unimplemented ODCooldown!")
}
/**Initialize the internal systems of this cooldown. */
async init(){
throw new ODSystemError("Tried to use an unimplemented ODCooldown!")
}
}
/**## ODCounterCooldown `class`
* This is an Open Ticket counter cooldown.
*
* It is is a cooldown based on a counter. When the number exceeds the limit, the cooldown is activated.
* The number will automatically be decreased with a set amount & interval.
*/
export class ODCounterCooldown extends ODCooldown<{value:number}> {
/**The cooldown will activate when exceeding this limit. */
activeLimit: number
/**The cooldown will deactivate when below this limit. */
cancelLimit: number
/**The amount to increase the counter with everytime the cooldown is triggered/updated. */
increment: number
/**The amount to decrease the counter over time. */
decrement: number
/**The interval between decrements in milliseconds. */
invervalMs: number
constructor(id:ODValidId, activeLimit:number, cancelLimit:number, increment:number, decrement:number, intervalMs:number){
super(id)
this.activeLimit = activeLimit
this.cancelLimit = cancelLimit
this.increment = increment
this.decrement = decrement
this.invervalMs = intervalMs
}
use(id:string): boolean {
const cooldown = this.data.get(id)
if (cooldown){
//cooldown for this id already exists
if (cooldown.active){
return true
}else if (cooldown.data.value < this.activeLimit){
cooldown.data.value = cooldown.data.value + this.increment
return false
}else{
cooldown.active = true
return false
}
}else{
//cooldown for this id doesn't exist
this.data.add(new ODCooldownData(id,(this.increment >= this.activeLimit),{
value:this.increment
}))
return false
}
}
check(id:string): boolean {
const cooldown = this.data.get(id)
if (cooldown){
//cooldown for this id already exists
return cooldown.active
}else return false
}
delete(id:string): void {
this.data.remove(id)
}
async init(){
if (this.ready) return
setInterval(async () => {
await this.data.loopAll((cooldown) => {
cooldown.data.value = cooldown.data.value - this.decrement
if (cooldown.data.value <= this.cancelLimit){
cooldown.active = false
}
if (cooldown.data.value <= 0){
this.data.remove(cooldown.id)
}
})
},this.invervalMs)
this.ready = true
}
}
/**## ODIncrementalCounterCooldown `class`
* This is an Open Ticket incremental counter cooldown.
*
* It is is a cooldown based on an incremental counter. It is exactly the same as the normal counter,
* with the only difference being that it still increments when the limit is already exeeded.
*/
export class ODIncrementalCounterCooldown extends ODCooldown<{value:number}> {
/**The cooldown will activate when exceeding this limit. */
activeLimit: number
/**The cooldown will deactivate when below this limit. */
cancelLimit: number
/**The amount to increase the counter with everytime the cooldown is triggered/updated. */
increment: number
/**The amount to decrease the counter over time. */
decrement: number
/**The interval between decrements in milliseconds. */
invervalMs: number
constructor(id:ODValidId, activeLimit:number, cancelLimit:number, increment:number, decrement:number, intervalMs:number){
super(id)
this.activeLimit = activeLimit
this.cancelLimit = cancelLimit
this.increment = increment
this.decrement = decrement
this.invervalMs = intervalMs
}
use(id:string): boolean {
const cooldown = this.data.get(id)
if (cooldown){
//cooldown for this id already exists
if (cooldown.active){
cooldown.data.value = cooldown.data.value + this.increment
return true
}else if (cooldown.data.value < this.activeLimit){
cooldown.data.value = cooldown.data.value + this.increment
return false
}else{
cooldown.active = true
return false
}
}else{
//cooldown for this id doesn't exist
this.data.add(new ODCooldownData(id,(this.increment >= this.activeLimit),{
value:this.increment
}))
return false
}
}
check(id:string): boolean {
const cooldown = this.data.get(id)
if (cooldown){
//cooldown for this id already exists
return cooldown.active
}else return false
}
delete(id:string): void {
this.data.remove(id)
}
async init(){
if (this.ready) return
setInterval(async () => {
await this.data.loopAll((cooldown) => {
cooldown.data.value = cooldown.data.value - this.decrement
if (cooldown.data.value <= this.cancelLimit){
cooldown.active = false
}
if (cooldown.data.value <= 0){
this.data.remove(cooldown.id)
}
})
},this.invervalMs)
this.ready = true
}
}
/**## ODTimeoutCooldown `class`
* This is an Open Ticket timeout cooldown.
*
* It is a cooldown based on a timer. When triggered/updated, the cooldown is activated for the set amount of time.
* After the timer has timed out, the cooldown will be deleted.
*/
export class ODTimeoutCooldown extends ODCooldown<{date:number}> {
/**The amount of milliseconds before the cooldown times-out */
timeoutMs: number
constructor(id:ODValidId, timeoutMs:number){
super(id)
this.timeoutMs = timeoutMs
}
use(id:string): boolean {
const cooldown = this.data.get(id)
if (cooldown){
//cooldown for this id already exists
if ((new Date().getTime() - cooldown.data.date) > this.timeoutMs){
this.data.remove(id)
return false
}else{
return true
}
}else{
//cooldown for this id doesn't exist
this.data.add(new ODCooldownData(id,true,{
date:new Date().getTime()
}))
return false
}
}
check(id:string): boolean {
const cooldown = this.data.get(id)
if (cooldown){
//cooldown for this id already exists
return true
}else return false
}
delete(id:string): void {
this.data.remove(id)
}
/**Get the remaining amount of milliseconds before the timeout stops. */
remaining(id:string): number|null {
const cooldown = this.data.get(id)
if (!cooldown) return null
const rawResult = this.timeoutMs - (new Date().getTime() - cooldown.data.date)
return (rawResult > 0) ? rawResult : 0
}
async init(){
if (this.ready) return
this.ready = true
}
}
/**## ODIncrementalTimeoutCooldown `class`
* This is an Open Ticket incremental timeout cooldown.
*
* It is is a cooldown based on an incremental timer. It is exactly the same as the normal timer,
* with the only difference being that it adds additional time when triggered/updated while the cooldown is already active.
*/
export class ODIncrementalTimeoutCooldown extends ODCooldown<{date:number}> {
/**The amount of milliseconds before the cooldown times-out */
timeoutMs: number
/**The amount of milliseconds to add when triggered/updated while the cooldown is already active. */
incrementMs: number
constructor(id:ODValidId, timeoutMs:number, incrementMs:number){
super(id)
this.timeoutMs = timeoutMs
this.incrementMs = incrementMs
}
use(id:string): boolean {
const cooldown = this.data.get(id)
if (cooldown){
//cooldown for this id already exists
if ((new Date().getTime() - cooldown.data.date) > this.timeoutMs){
this.data.remove(id)
return false
}else{
cooldown.data.date = cooldown.data.date + this.incrementMs
return true
}
}else{
//cooldown for this id doesn't exist
this.data.add(new ODCooldownData(id,true,{
date:new Date().getTime()
}))
return false
}
}
check(id:string): boolean {
const cooldown = this.data.get(id)
if (cooldown){
//cooldown for this id already exists
return true
}else return false
}
delete(id:string): void {
this.data.remove(id)
}
/**Get the remaining amount of milliseconds before the timeout stops. */
remaining(id:string): number|null {
const cooldown = this.data.get(id)
if (!cooldown) return null
const rawResult = this.timeoutMs - (new Date().getTime() - cooldown.data.date)
return (rawResult > 0) ? rawResult : 0
}
async init(){
if (this.ready) return
this.ready = true
}
}
-278
View File
@@ -1,278 +0,0 @@
///////////////////////////////////////
//DATABASE MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODOptionalPromise, ODPromiseVoid, ODSystemError, ODValidId, ODValidJsonType } from "./base"
import fs from "fs"
import nodepath from "path"
import { ODDebugger } from "./console"
import * as fjs from "formatted-json-stringify"
/**## ODDatabaseManager `class`
* This is an Open Ticket database manager.
*
* It manages all databases in the bot and allows to permanently store data from the bot!
*
* You can use this class to get/add a database (`ODDatabase`) in your plugin!
*/
export class ODDatabaseManager extends ODManager<ODDatabase> {
constructor(debug:ODDebugger){
super(debug,"database")
}
/**Init all database files. */
async init(){
for (const database of this.getAll()){
try{
await database.init()
}catch(err){
process.emit("uncaughtException",new ODSystemError(err))
}
}
}
}
/**## ODDatabase `class`
* This is an Open Ticket database template.
* This class doesn't do anything at all, it just gives a template & basic methods for a database. Use `ODJsonDatabase` instead!
*
* You can use this class if you want to create your own database implementation (e.g. `mongodb`, `mysql`,...)!
*/
export class ODDatabase extends ODManagerData {
/**The name of the file with extension. */
file: string = ""
/**The path to the file relative to the main directory. */
path: string = ""
/**Init the database. */
init(): ODPromiseVoid {
//nothing
}
/**Add/Overwrite a specific category & key in the database. Returns `true` when overwritten. */
set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> {
return false
}
/**Get a specific category & key in the database */
get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined> {
return undefined
}
/**Delete a specific category & key in the database */
delete(category:string, key:string): ODOptionalPromise<boolean> {
return false
}
/**Check if a specific category & key exists in the database */
exists(category:string, key:string): ODOptionalPromise<boolean> {
return false
}
/**Get a specific category in the database */
getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> {
return undefined
}
/**Get all values in the database */
getAll(): ODOptionalPromise<ODJsonDatabaseStructure> {
return []
}
}
/**## ODJsonDatabaseStructure `type`
* This is the structure of how a JSON database file!
*/
export type ODJsonDatabaseStructure = {category:string, key:string, value:ODValidJsonType}[]
/**## ODJsonDatabase `class`
* This is an Open Ticket JSON database.
* It stores data in a `json` file as a large `Array` using the `category`, `key`, `value` strategy.
* You can store the following types: `string`, `number`, `boolean`, `array`, `object` & `null`!
*
* You can use this class if you want to add your own database or to use an existing one!
*/
export class ODJsonDatabase extends ODDatabase {
constructor(id:ODValidId, file:string, customPath?:string){
super(id)
this.file = (file.endsWith(".json")) ? file : file+".json"
this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./database/",this.file)
}
/**Init the database. */
init(): ODPromiseVoid {
this.#system.getData()
}
/**Set/overwrite the value of `category` & `key`. Returns `true` when overwritten!
* @example
* const didOverwrite = database.setData("category","key","value") //value can be any of the valid types
* //You need an ODJsonDatabase class named "database" for this example to work!
*/
set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> {
const currentList = this.#system.getData()
const currentData = currentList.find((d) => (d.category === category) && (d.key === key))
//overwrite when already present
if (currentData){
currentList[currentList.indexOf(currentData)].value = value
}else{
currentList.push({category,key,value})
}
this.#system.setData(currentList)
return currentData ? true : false
}
/**Get the value of `category` & `key`. Returns `undefined` when non-existent!
* @example
* const data = database.getData("category","key") //data will be the value
* //You need an ODJsonDatabase class named "database" for this example to work!
*/
get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined> {
const currentList = this.#system.getData()
const tempresult = currentList.find((d) => (d.category === category) && (d.key === key))
return tempresult ? tempresult.value : undefined
}
/**Remove the value of `category` & `key`. Returns `undefined` when non-existent!
* @example
* const didExist = database.deleteData("category","key") //delete this value
* //You need an ODJsonDatabase class named "database" for this example to work!
*/
delete(category:string, key:string): ODOptionalPromise<boolean> {
const currentList = this.#system.getData()
const currentData = currentList.find((d) => (d.category === category) && (d.key === key))
if (currentData) currentList.splice(currentList.indexOf(currentData),1)
this.#system.setData(currentList)
return currentData ? true : false
}
/**Check if a value of `category` & `key` exists. Returns `false` when non-existent! */
exists(category:string, key:string): ODOptionalPromise<boolean> {
const currentList = this.#system.getData()
const tempresult = currentList.find((d) => (d.category === category) && (d.key === key))
return tempresult ? true : false
}
/**Get all values in `category`. Returns `undefined` when non-existent! */
getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> {
const currentList = this.#system.getData()
const tempresult = currentList.filter((d) => (d.category === category))
return tempresult ? tempresult.map((data) => {return {key:data.key,value:data.value}}) : undefined
}
/**Get all values in `category`. */
getAll(): ODOptionalPromise<ODJsonDatabaseStructure> {
return this.#system.getData()
}
#system = {
/**Read parsed data from the json file */
getData: (): ODJsonDatabaseStructure => {
if (fs.existsSync(this.path)){
try{
return JSON.parse(fs.readFileSync(this.path).toString())
}catch(err){
process.emit("uncaughtException",err)
throw new ODSystemError("Unable to read database "+this.path+"! getData() read error. (see error above)")
}
}else{
fs.writeFileSync(this.path,"[]")
return []
}
},
/**Write parsed data to the json file */
setData: (data:ODJsonDatabaseStructure) => {
fs.writeFileSync(this.path,JSON.stringify(data,null,"\t"))
}
}
}
/**## ODFormattedJsonDatabase `class`
* This is an Open Ticket Formatted JSON database.
* It stores data in a `json` file as a large `Array` using the `category`, `key`, `value` strategy.
* You can store the following types: `string`, `number`, `boolean`, `array`, `object` & `null`!
*
* This one is exactly the same as `ODJsonDatabase`, but it has a formatter from the `formatted-json-stringify` package.
* This can help you organise it a little bit better!
*/
export class ODFormattedJsonDatabase extends ODDatabase {
/**The formatter to use on the database array */
formatter: fjs.ArrayFormatter
constructor(id:ODValidId, file:string, formatter:fjs.ArrayFormatter, customPath?:string){
super(id)
this.file = (file.endsWith(".json")) ? file : file+".json"
this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./database/",this.file)
this.formatter = formatter
}
/**Init the database. */
init(): ODPromiseVoid {
this.#system.getData()
}
/**Set/overwrite the value of `category` & `key`. Returns `true` when overwritten!
* @example
* const didOverwrite = database.setData("category","key","value") //value can be any of the valid types
* //You need an ODFormattedJsonDatabase class named "database" for this example to work!
*/
set(category:string, key:string, value:ODValidJsonType): ODOptionalPromise<boolean> {
const currentList = this.#system.getData()
const currentData = currentList.find((d) => (d.category === category) && (d.key === key))
//overwrite when already present
if (currentData){
currentList[currentList.indexOf(currentData)].value = value
}else{
currentList.push({category,key,value})
}
this.#system.setData(currentList)
return currentData ? true : false
}
/**Get the value of `category` & `key`. Returns `undefined` when non-existent!
* @example
* const data = database.getData("category","key") //data will be the value
* //You need an ODFormattedJsonDatabase class named "database" for this example to work!
*/
get(category:string, key:string): ODOptionalPromise<ODValidJsonType|undefined> {
const currentList = this.#system.getData()
const tempresult = currentList.find((d) => (d.category === category) && (d.key === key))
return tempresult ? tempresult.value : undefined
}
/**Remove the value of `category` & `key`. Returns `undefined` when non-existent!
* @example
* const didExist = database.deleteData("category","key") //delete this value
* //You need an ODFormattedJsonDatabase class named "database" for this example to work!
*/
delete(category:string, key:string): ODOptionalPromise<boolean> {
const currentList = this.#system.getData()
const currentData = currentList.find((d) => (d.category === category) && (d.key === key))
if (currentData) currentList.splice(currentList.indexOf(currentData),1)
this.#system.setData(currentList)
return currentData ? true : false
}
/**Check if a value of `category` & `key` exists. Returns `false` when non-existent! */
exists(category:string, key:string): ODOptionalPromise<boolean> {
const currentList = this.#system.getData()
const tempresult = currentList.find((d) => (d.category === category) && (d.key === key))
return tempresult ? true : false
}
/**Get all values in `category`. Returns `undefined` when non-existent! */
getCategory(category:string): ODOptionalPromise<{key:string, value:ODValidJsonType}[]|undefined> {
const currentList = this.#system.getData()
const tempresult = currentList.filter((d) => (d.category === category))
return tempresult ? tempresult.map((data) => {return {key:data.key,value:data.value}}) : undefined
}
/**Get all values in `category`. */
getAll(): ODOptionalPromise<ODJsonDatabaseStructure> {
return this.#system.getData()
}
#system = {
/**Read parsed data from the json file */
getData: (): ODJsonDatabaseStructure => {
if (fs.existsSync(this.path)){
return JSON.parse(fs.readFileSync(this.path).toString())
}else{
fs.writeFileSync(this.path,"[]")
return []
}
},
/**Write parsed data to the json file */
setData: (data:ODJsonDatabaseStructure) => {
fs.writeFileSync(this.path,this.formatter.stringify(data))
}
}
}
-366
View File
@@ -1,366 +0,0 @@
///////////////////////////////////////
//DEFAULTS MODULE
///////////////////////////////////////
/**## ODDefaults `interface`
* This type is a list of all defaults available in the `ODDefaultsManager` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODDefaults {
/**Enable the default error handling system. */
errorHandling:boolean,
/**Crash when there is an unknown bot error. */
crashOnError:boolean,
/**Enable the system responsible for the `--debug` flag. */
debugLoading:boolean,
/**Enable the system responsible for the `--silent` flag. */
silentLoading:boolean,
/**When enabled, you're able to use the "!OPENTICKET:dump" command to send the OT debug file. This is only possible when you're the owner of the bot. */
allowDumpCommand:boolean,
/**Enable loading all Open Ticket plugins, sadly enough is only useful for the system :) */
pluginLoading:boolean,
/**Don't crash the bot when a plugin crashes! */
softPluginLoading:boolean,
/**Load the default Open Ticket plugin classes. */
pluginClassLoading:boolean,
/**Load the default Open Ticket flags. */
flagLoading:boolean,
/**Enable the default initializer for Open Ticket flags. */
flagInitiating:boolean,
/**Load the default Open Ticket progress bar renderers. */
progressBarRendererLoading:boolean,
/**Load the default Open Ticket progress bars. */
progressBarLoading:boolean,
/**Load the default Open Ticket configs. */
configLoading:boolean,
/**Enable the default initializer for Open Ticket config. */
configInitiating:boolean,
/**Load the default Open Ticket databases. */
databaseLoading:boolean,
/**Enable the default initializer for Open Ticket database. */
databaseInitiating:boolean,
/**Load the default Open Ticket sessions. */
sessionLoading:boolean,
/**Load the default Open Ticket languages. */
languageLoading:boolean,
/**Enable the default initializer for Open Ticket languages. */
languageInitiating:boolean,
/**Enable selecting the current language from `config/general.json`. */
languageSelection:boolean,
/**Set the backup language when the primary language is missing a property. */
backupLanguage:string,
/****[NOT FOR PLUGIN TRANSLATIONS]** The full list of available languages (used in the default config checker). */
languageList:string[],
/**Load the default Open Ticket config checker. */
checkerLoading:boolean,
/**Load the default Open Ticket config checker functions. */
checkerFunctionLoading:boolean,
/**Enable the default execution of the config checkers. */
checkerExecution:boolean,
/**Load the default Open Ticket config checker translations. */
checkerTranslationLoading:boolean,
/**Enable the default rendering of the config checkers. */
checkerRendering:boolean,
/**Enable the default quit action when there is an error in the config checker. */
checkerQuit:boolean,
/**Render the checker even when there are no errors & warnings. */
checkerRenderEmpty:boolean,
/**Load the default Open Ticket client configuration. */
clientLoading:boolean,
/**Load the default Open Ticket client initialization. */
clientInitiating:boolean,
/**Load the default Open Ticket client ready actions (status, commands, permissions, ...). */
clientReady:boolean,
/**Create a warning when the bot is present in multiple guilds. */
clientMultiGuildWarning:boolean,
/**Load the default Open Ticket client activity (from `config/general.json`). */
clientActivityLoading:boolean,
/**Load the default Open Ticket client activity initialization (& status refresh). */
clientActivityInitiating:boolean,
/**Load the default Open Ticket priority levels. */
priorityLoading:boolean,
/**Load the default Open Ticket slash commands. */
slashCommandLoading:boolean,
/**Load the default Open Ticket slash command registerer (register slash cmds in discord). */
slashCommandRegistering:boolean,
/**When enabled, the bot is forced to re-register all slash commands in the server. This can be used in case of a auto-update malfunction. */
forceSlashCommandRegistration:boolean,
/**When enabled, the bot is allowed to unregister all slash commands which aren't used in Open Ticket. Disable this if you don't want to use the Open Ticket `ODSlashCommand` classes. */
allowSlashCommandRemoval:boolean,
/**Load the default Open Ticket context menus. */
contextMenuLoading:boolean,
/**Load the default Open Ticket context menu registerer (register menus in discord). */
contextMenuRegistering:boolean,
/**When enabled, the bot is forced to re-register all context menus in the server. This can be used in case of a auto-update malfunction. */
forceContextMenuRegistration:boolean,
/**When enabled, the bot is allowed to unregister all context menus which aren't used in Open Ticket. Disable this if you don't want to use the Open Ticket `ODContextMenu` classes. */
allowContextMenuRemoval:boolean,
/**Load the default Open Ticket text commands. */
textCommandLoading:boolean,
/**Load the default Open Ticket questions (from `config/questions.json`) */
questionLoading:boolean,
/**Load the default Open Ticket options (from `config/options.json`) */
optionLoading:boolean,
/**Load the default Open Ticket panels (from `config/panels.json`) */
panelLoading:boolean,
/**Load the default Open Ticket tickets (from `database/tickets.json`) */
ticketLoading:boolean,
/**Load the default Open Ticket reaction roles (from `config/options.json`) */
roleLoading:boolean,
/**Load the default Open Ticket blacklist (from `database/users.json`) */
blacklistLoading:boolean,
/**Load the default Open Ticket transcript compilers. */
transcriptCompilerLoading:boolean,
/**Load the default Open Ticket transcript history (from `database/transcripts.json`) */
transcriptHistoryLoading:boolean,
/**Load the default Open Ticket button builders. */
buttonBuildersLoading:boolean,
/**Load the default Open Ticket dropdown builders. */
dropdownBuildersLoading:boolean,
/**Load the default Open Ticket file builders. */
fileBuildersLoading:boolean,
/**Load the default Open Ticket embed builders. */
embedBuildersLoading:boolean,
/**Load the default Open Ticket message builders. */
messageBuildersLoading:boolean,
/**Load the default Open Ticket modal builders. */
modalBuildersLoading:boolean,
/**Load the default Open Ticket command responders. */
commandRespondersLoading:boolean,
/**Load the default Open Ticket button responders. */
buttonRespondersLoading:boolean,
/**Load the default Open Ticket dropdown responders. */
dropdownRespondersLoading:boolean,
/**Load the default Open Ticket modal responders. */
modalRespondersLoading:boolean,
/**Load the default Open Ticket context menu responders. */
contextMenuRespondersLoading:boolean,
/**Load the default Open Ticket autocomplete responders. */
autocompleteRespondersLoading:boolean,
/**Set the time (in ms) before Open Ticket sends an error message when no reply is sent in a responder. */
responderTimeoutMs:number,
/**Load the default Open Ticket actions. */
actionsLoading:boolean,
/**Load the default Open Ticket verify bars. */
verifyBarsLoading:boolean,
/**Load the default Open Ticket permissions. */
permissionsLoading:boolean,
/**Load the default Open Ticket posts. */
postsLoading:boolean,
/**Initiate the default Open Ticket posts. */
postsInitiating:boolean,
/**Load the default Open Ticket cooldowns. */
cooldownsLoading:boolean,
/**Initiate the default Open Ticket cooldowns. */
cooldownsInitiating:boolean,
/**Load the default Open Ticket help menu categories. */
helpMenuCategoryLoading:boolean,
/**Load the default Open Ticket help menu components. */
helpMenuComponentLoading:boolean,
/**Load the default Open Ticket stat scopes. */
statScopesLoading:boolean,
/**Load the default Open Ticket stats. */
statLoading:boolean,
/**Initiate the default Open Ticket stats. */
statInitiating:boolean,
/**Load the default Open Ticket code/functions. */
codeLoading:boolean,
/**Execute the default Open Ticket code/functions. */
codeExecution:boolean,
/**Load the default Open Ticket livestatus. */
liveStatusLoading:boolean,
/**Load the default Open Ticket startscreen. */
startScreenLoading:boolean,
/**Render the default Open Ticket startscreen. */
startScreenRendering:boolean,
/**Load the emoji style from the Open Ticket general config. */
emojiTitleStyleLoading:boolean,
/**The emoji style to use in embed & message titles using `utilities.emoijTitle()` */
emojiTitleStyle:"disabled"|"before"|"after"|"double",
/**The emoji divider to use in embed & message titles using `utilities.emoijTitle()` */
emojiTitleDivider:string
/**The interval in milliseconds that are between autoclose timeout checkers. */
autocloseCheckInterval:number
/**The interval in milliseconds that are between autodelete timeout checkers. */
autodeleteCheckInterval:number
}
/**## ODDefaultsBooleans `type`
* This type is a list of boolean defaults available in the `ODDefaultsManager` class.
* It's used to generate typescript declarations for this class.
*/
export type ODDefaultsBooleans = {
[Key in keyof ODDefaults]: ODDefaults[Key] extends boolean ? Key : never
}[keyof ODDefaults]
/**## ODDefaultsStrings `type`
* This type is a list of string defaults available in the `ODDefaultsManager` class.
* It's used to generate typescript declarations for this class.
*/
export type ODDefaultsStrings = {
[Key in keyof ODDefaults]: ODDefaults[Key] extends string ? Key : never
}[keyof ODDefaults]
/**## ODDefaultsNumbers `type`
* This type is a list of number defaults available in the `ODDefaultsManager` class.
* It's used to generate typescript declarations for this class.
*/
export type ODDefaultsNumbers = {
[Key in keyof ODDefaults]: ODDefaults[Key] extends number ? Key : never
}[keyof ODDefaults]
/**## ODDefaultsStringArray `type`
* This type is a list of string[] defaults available in the `ODDefaultsManager` class.
* It's used to generate typescript declarations for this class.
*/
export type ODDefaultsStringArray = {
[Key in keyof ODDefaults]: ODDefaults[Key] extends string[] ? Key : never
}[keyof ODDefaults]
/**## ODDefaultsManager `class`
* This is an Open Ticket defaults manager.
*
* It manages all settings in Open Ticket that are not meant to be in the config.
* Here you can disable certain default features to replace them or to specifically enable them!
*
* You are unable to add your own defaults, you can only edit Open Ticket defaults!
*/
export class ODDefaultsManager {
/**A list of all the defaults */
#defaults: ODDefaults
constructor(){
this.#defaults = {
errorHandling:true,
crashOnError:false,
debugLoading:true,
silentLoading:true,
allowDumpCommand:true,
pluginLoading:true,
softPluginLoading:false,
pluginClassLoading:true,
flagLoading:true,
flagInitiating:true,
progressBarRendererLoading:true,
progressBarLoading:true,
configLoading:true,
configInitiating:true,
databaseLoading:true,
databaseInitiating:true,
sessionLoading:true,
languageLoading:true,
languageInitiating:true,
languageSelection:true,
backupLanguage:"opendiscord:english",
languageList:[],
checkerLoading:true,
checkerFunctionLoading:true,
checkerExecution:true,
checkerTranslationLoading:true,
checkerRendering:true,
checkerQuit:true,
checkerRenderEmpty:false,
clientLoading:true,
clientInitiating:true,
clientReady:true,
clientMultiGuildWarning:true,
clientActivityLoading:true,
clientActivityInitiating:true,
priorityLoading:true,
slashCommandLoading:true,
slashCommandRegistering:true,
forceSlashCommandRegistration:false,
allowSlashCommandRemoval:true,
contextMenuLoading:true,
contextMenuRegistering:true,
forceContextMenuRegistration:false,
allowContextMenuRemoval:true,
textCommandLoading:true,
questionLoading:true,
optionLoading:true,
panelLoading:true,
ticketLoading:true,
roleLoading:true,
blacklistLoading:true,
transcriptCompilerLoading:true,
transcriptHistoryLoading:true,
buttonBuildersLoading:true,
dropdownBuildersLoading:true,
fileBuildersLoading:true,
embedBuildersLoading:true,
messageBuildersLoading:true,
modalBuildersLoading:true,
commandRespondersLoading:true,
buttonRespondersLoading:true,
dropdownRespondersLoading:true,
modalRespondersLoading:true,
contextMenuRespondersLoading:true,
autocompleteRespondersLoading:true,
responderTimeoutMs:2500,
actionsLoading:true,
verifyBarsLoading:true,
permissionsLoading:true,
postsLoading:true,
postsInitiating:true,
cooldownsLoading:true,
cooldownsInitiating:true,
helpMenuCategoryLoading:true,
helpMenuComponentLoading:true,
statScopesLoading:true,
statLoading:true,
statInitiating:true,
codeLoading:true,
codeExecution:true,
liveStatusLoading:true,
startScreenLoading:true,
startScreenRendering:true,
emojiTitleStyleLoading:true,
emojiTitleStyle:"before",
emojiTitleDivider:" ",
autocloseCheckInterval:300000, //5 minutes
autodeleteCheckInterval:300000 //5 minutes
}
}
/**Set a default to a specific value. Remember! All plugins can edit these values, so your value could be overwritten! */
setDefault<DefaultName extends keyof ODDefaults>(key:DefaultName, value:ODDefaults[DefaultName]): void {
this.#defaults[key] = value
}
/**Get a default. Remember! All plugins can edit these values, so this value could be overwritten! */
getDefault<DefaultName extends keyof ODDefaults>(key:DefaultName): ODDefaults[DefaultName] {
return this.#defaults[key]
}
}
-99
View File
@@ -1,99 +0,0 @@
///////////////////////////////////////
//EVENT MODULE
///////////////////////////////////////
import { ODManagerData, ODManager, ODValidId } from "./base"
import { ODConsoleWarningMessage, ODDebugger } from "./console"
/**## ODEvent `class`
* This is an Open Ticket event.
*
* This class is made to work with the `ODEventManager` to handle events.
* The function of this specific class is to manage all listeners for a specifc event!
*/
export class ODEvent extends ODManagerData {
/**Alias to Open Ticket debugger. */
#debug?: ODDebugger
/**The list of permanent listeners. */
listeners: Function[] = []
/**The list of one-time listeners. List is cleared every time the event is emitted. */
oncelisteners: Function[] = []
/**The max listener limit before a possible memory leak will be announced */
listenerLimit: number = 25
/**Use the Open Ticket debugger in this manager for logs*/
useDebug(debug:ODDebugger|null){
this.#debug = debug ?? undefined
}
/**Get a collection of listeners combined from both types. Also clears the one-time listeners array! */
#getCurrentListeners(){
const final: Function[] = []
this.oncelisteners.forEach((l) => final.push(l))
this.listeners.forEach((l) => final.push(l))
this.oncelisteners = []
return final
}
/**Edit the listener limit */
setListenerLimit(limit:number){
this.listenerLimit = limit
}
/**Add a permanent callback to this event. This will stay as long as the bot is running! */
listen(callback:Function){
this.listeners.push(callback)
if (this.listeners.length > this.listenerLimit){
if (this.#debug) this.#debug.console.log(new ODConsoleWarningMessage("Possible event memory leak detected!",[
{key:"event",value:this.id.value},
{key:"listeners",value:this.listeners.length.toString()}
]))
}
}
/**Add a one-time-only callback to this event. This will only trigger the callback once! */
listenOnce(callback:Function){
this.oncelisteners.push(callback)
}
/**Wait until this event is fired! Be carefull with it, because it could block the entire bot when wrongly used! */
async wait(): Promise<any[]> {
return new Promise((resolve,reject) => {
this.oncelisteners.push((...args:any) => {resolve(args)})
})
}
/**Emit this event to all listeners. You are required to provide all parameters of the event! */
async emit(params:any[]): Promise<void> {
for (const listener of this.#getCurrentListeners()){
try{
await listener(...params)
}catch(err){
process.emit("uncaughtException",err)
}
}
}
}
/**## ODEventManager `class`
* This is an Open Ticket event manager.
*
* This class is made to manage all events in the bot. You can compare it with the built-in node.js `EventEmitter`
*
* It's not recommended to create this class yourself. Plugin events should be registered in their `plugin.json` file instead.
* All events are available in the `opendiscord.events` global!
*/
export class ODEventManager extends ODManager<ODEvent> {
/**Reference to the Open Ticket debugger */
#debug: ODDebugger
constructor(debug:ODDebugger){
super(debug,"event")
this.#debug = debug
}
add(data:ODEvent, overwrite?:boolean): boolean {
data.useDebug(this.#debug)
return super.add(data,overwrite)
}
remove(id:ODValidId): ODEvent|null {
const data = super.remove(id)
if (data) data.useDebug(null)
return data
}
}
-73
View File
@@ -1,73 +0,0 @@
///////////////////////////////////////
//FLAG MODULE
///////////////////////////////////////
import { ODId, ODValidId, ODManager, ODManagerData } from "./base"
import { ODDebugger } from "./console"
/**## ODFlag `class`
* This is an Open Ticket flag.
*
* A flag is a boolean that can be specified by a parameter in the console.
* It's useful for small settings that are only required once in a while.
*
* Flags can also be enabled manually by plugins!
*/
export class ODFlag extends ODManagerData {
/**The method that has been used to set the value of this flag. (`null` when not set) */
method: "param"|"manual"|null = null
/**The name of this flag. Visible to the user. */
name: string
/**The description of this flag. Visible to the user. */
description: string
/**The name of the parameter in the console. (e.g. `--test`) */
param: string
/**A list of aliases for the parameter in the console. */
aliases: string[]
/**The value of this flag. */
value: boolean = false
constructor(id:ODValidId, name:string, description:string, param:string, aliases?:string[], initialValue?:boolean){
super(id)
this.name = name
this.description = description
this.param = param
this.aliases = aliases ?? []
this.value = initialValue ?? false
}
/**Set the value of this flag. */
setValue(value:boolean,method?:"param"|"manual"){
this.value = value
this.method = method ?? "manual"
}
/**Detect if the process contains the param or aliases & set the value. Use `force` to overwrite a manually set value. */
detectProcessParams(force?:boolean){
if (force){
const params = [this.param,...this.aliases]
this.setValue(params.some((p) => process.argv.includes(p)),"param")
}else if (this.method != "manual"){
const params = [this.param,...this.aliases]
this.setValue(params.some((p) => process.argv.includes(p)),"param")
}
}
}
/**## ODFlagManager `class`
* This is an Open Ticket flag manager.
*
* This class is responsible for managing & initiating all flags of the bot.
* It also contains a shortcut for initiating all flags.
*/
export class ODFlagManager extends ODManager<ODFlag> {
constructor(debug:ODDebugger){
super(debug,"flag")
}
/**Set all flags to their `process.argv` value. */
async init(){
await this.loopAll((flag) => {
flag.detectProcessParams(false)
})
}
}
-216
View File
@@ -1,216 +0,0 @@
///////////////////////////////////////
//HELP MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODValidId } from "./base"
import { ODDebugger } from "./console"
/**## ODHelpMenuComponentRenderer `type`
* This is the callback of the help menu component renderer. It also contains information about how & where it is rendered.
*/
export type ODHelpMenuComponentRenderer = (page:number, category:number, location:number, mode:"slash"|"text") => string|Promise<string>
/**## ODHelpMenuComponent `class`
* This is an Open Ticket help menu component.
*
* It can render something on the Open Ticket help menu.
*/
export class ODHelpMenuComponent extends ODManagerData {
/**The priority of this component. The higher, the earlier it will appear in the help menu. */
priority: number
/**The render function for this component. */
render: ODHelpMenuComponentRenderer
constructor(id:ODValidId, priority:number, render:ODHelpMenuComponentRenderer){
super(id)
this.priority = priority
this.render = render
}
}
/**## ODHelpMenuTextComponent `class`
* This is an Open Ticket help menu text component.
*
* It can render a static piece of text on the Open Ticket help menu.
*/
export class ODHelpMenuTextComponent extends ODHelpMenuComponent {
constructor(id:ODValidId, priority:number, text:string){
super(id,priority,() => {
return text
})
}
}
/**## ODHelpMenuCommandComponentOption `interface`
* This interface contains a command option for the `ODHelpMenuCommandComponent`.
*/
export interface ODHelpMenuCommandComponentOption {
/**The name of this option. */
name:string,
/**Is this option optional? */
optional:boolean
}
/**## ODHelpMenuCommandComponentSettings `interface`
* This interface contains the settings for the `ODHelpMenuCommandComponent`.
*/
export interface ODHelpMenuCommandComponentSettings {
/**The name of this text command. */
textName?:string,
/**The name of this slash command. */
slashName?:string,
/**Options available in the text command. */
textOptions?:ODHelpMenuCommandComponentOption[],
/**Options available in the slash command. */
slashOptions?:ODHelpMenuCommandComponentOption[],
/**The description for the text command. */
textDescription?:string,
/**The description for the slash command. */
slashDescription?:string
}
/**## ODHelpMenuCommandComponent `class`
* This is an Open Ticket help menu command component.
*
* It contains a useful helper to render a command in the Open Ticket help menu.
*/
export class ODHelpMenuCommandComponent extends ODHelpMenuComponent {
constructor(id:ODValidId, priority:number, settings:ODHelpMenuCommandComponentSettings){
super(id,priority,(page,category,location,mode) => {
if (mode == "slash" && settings.slashName){
return `\`${settings.slashName}${(settings.slashOptions) ? this.#renderOptions(settings.slashOptions) : ""}\` ➜ ${settings.slashDescription ?? ""}`
}else if (mode == "text" && settings.textName){
return `\`${settings.textName}${(settings.textOptions) ? this.#renderOptions(settings.textOptions) : ""}\` ➜ ${settings.textDescription ?? ""}`
}else return ""
})
}
/**Utility function to render all command options. */
#renderOptions(options:ODHelpMenuCommandComponentOption[]){
return " "+options.map((opt) => (opt.optional) ? `[${opt.name}]` : `<${opt.name}>`).join(" ")
}
}
/**## ODHelpMenuCategory `class`
* This is an Open Ticket help menu category.
*
* Every category in the help menu is an embed field by default.
* Try to limit the amount of components per category.
*/
export class ODHelpMenuCategory extends ODManager<ODHelpMenuComponent> {
/**The id of this category. */
id: ODId
/**The priority of this category. The higher, the earlier it will appear in the menu. */
priority: number
/**The name of this category. (can include emoji's) */
name: string
/**When enabled, it automatically starts this category on a new page. */
newPage: boolean
constructor(id:ODValidId, priority:number, name:string, newPage?:boolean){
super()
this.id = new ODId(id)
this.priority = priority
this.name = name
this.newPage = newPage ?? false
}
/**Render this category and it's components. */
async render(page:number, category:number, mode:"slash"|"text"){
//sort from high priority to low
const derefArray = [...this.getAll()]
derefArray.sort((a,b) => {
return b.priority-a.priority
})
const result: string[] = []
let i = 0
for (const component of derefArray){
try {
result.push(await component.render(page,category,i,mode))
}catch(err){
process.emit("uncaughtException",err)
}
i++
}
//only return the non-empty components
return result.filter((component) => component !== "").join("\n\n")
}
}
/**## ODHelpMenuRenderResult `type`
* This is the array returned when the help menu has been rendered successfully.
*
* It contains a list of pages, which contain categories by name & value (content).
*/
export type ODHelpMenuRenderResult = {name:string, value:string}[][]
/**## ODHelpMenuManager `class`
* This is an Open Ticket help menu manager.
*
* It is responsible for rendering the entire help menu content.
* You are also able to configure the amount of categories per page here.
*
* Fewer Categories == More Clean Menu
*/
export class ODHelpMenuManager extends ODManager<ODHelpMenuCategory> {
/**Alias to Open Ticket debugger. */
#debug: ODDebugger
/**The amount of categories per-page. */
categoriesPerPage: number = 3
constructor(debug:ODDebugger){
super(debug,"help menu category")
this.#debug = debug
}
add(data:ODHelpMenuCategory, overwrite?:boolean): boolean {
data.useDebug(this.#debug,"help menu component")
return super.add(data,overwrite)
}
/**Render this entire help menu & return a `ODHelpMenuRenderResult`. */
async render(mode:"slash"|"text"): Promise<ODHelpMenuRenderResult> {
//sort from high priority to low
const derefArray = [...this.getAll()]
derefArray.sort((a,b) => {
return b.priority-a.priority
})
const result: {name:string, value:string}[][] = []
let currentPage: {name:string, value:string}[] = []
for (const category of derefArray){
try {
const renderedCategory = await category.render(result.length,currentPage.length,mode)
if (renderedCategory !== ""){
//create new page when category wants to
if (currentPage.length > 0 && category.newPage){
result.push(currentPage)
currentPage = []
}
currentPage.push({
name:category.name,
value:renderedCategory
})
//create new page when page is full
if (currentPage.length >= this.categoriesPerPage){
result.push(currentPage)
currentPage = []
}
}
}catch(err){
process.emit("uncaughtException",err)
}
}
//push current page when not-empty
if (currentPage.length > 0) result.push(currentPage)
return result
}
}
-201
View File
@@ -1,201 +0,0 @@
///////////////////////////////////////
//LANGUAGE MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODPromiseVoid, ODSystemError, ODValidId } from "./base"
import nodepath from "path"
import { ODDebugger } from "./console"
import fs from "fs"
/**## ODLanguageMetadata `interface`
* This interface contains all metadata available in the language files.
*/
export interface ODLanguageMetadata {
/**The version of Open Ticket this translation is made for. */
otversion:string,
/**The name of the language in english (with capital letter). */
language:string,
/**A list of translators (discord/github username) who've contributed to this language. */
translators:string[],
/**The last date that this translation has been modified (format: DD/MM/YYYY) */
lastedited:string,
/**When `true`, the translator made use of some sort of automation while creating the translation. (e.g. ChatGPT, Google Translate, DeepL, ...) */
automated:boolean
}
/**## ODLanguageManager `class`
* This is an Open Ticket language manager.
*
* It manages all languages in the bot and manages translation for you!
* Get a translation via the `getTranslation()` or `getTranslationWithParams()` methods.
*
* Add new languages using the `ODlanguage` class in your plugin!
*/
export class ODLanguageManager extends ODManager<ODLanguage> {
/**The currently selected language. */
current: ODLanguage|null = null
/**The currently selected backup language. (used when translation missing in current language) */
backup: ODLanguage|null = null
/**An alias to Open Ticket debugger. */
#debug: ODDebugger
constructor(debug:ODDebugger, presets:boolean){
super(debug,"language")
if (presets) this.add(new ODLanguage("english","english.json"))
this.current = presets ? new ODLanguage("english","english.json") : null
this.backup = presets ? new ODLanguage("english","english.json") : null
this.#debug = debug
}
/**Set the current language by providing the ID of a language which is registered in this manager. */
setCurrentLanguage(id:ODValidId){
this.current = this.get(id)
const languageId = this.current?.id.value ?? "<unknown-id>"
const languageAutomated = this.current?.metadata?.automated.toString() ?? "<unknown-metadata>"
this.#debug.debug("Selected current language",[
{key:"id",value:languageId},
{key:"automated",value:languageAutomated},
])
}
/**Get the current language (same as `this.current`) */
getCurrentLanguage(){
return (this.current) ? this.current : null
}
/**Set the backup language by providing the ID of a language which is registered in this manager. */
setBackupLanguage(id:ODValidId){
this.backup = this.get(id)
const languageId = this.backup?.id.value ?? "<unknown-id>"
const languageAutomated = this.backup?.metadata?.automated.toString() ?? "<unknown-metadata>"
this.#debug.debug("Selected backup language",[
{key:"id",value:languageId},
{key:"automated",value:languageAutomated},
])
}
/**Get the backup language (same as `this.backup`) */
getBackupLanguage(){
return (this.backup) ? this.backup : null
}
/**Get the metadata of the current/backup language. */
getLanguageMetadata(frombackup?:boolean): ODLanguageMetadata|null {
if (frombackup) return (this.backup) ? this.backup.metadata : null
return (this.current) ? this.current.metadata : null
}
/**Get the ID (string) of the current language. (Not backup language) */
getCurrentLanguageId(){
return (this.current) ? this.current.id.value : ""
}
/**Get a translation string by JSON location. (e.g. `"checker.system.typeError"`) */
getTranslation(id:string): string|null {
if (!this.current) return this.#getBackupTranslation(id)
const splitted = id.split(".")
let currentObject = this.current.data
let result: string|false = false
splitted.forEach((id) => {
if (typeof currentObject[id] == "object"){
currentObject = currentObject[id]
}else if (typeof currentObject[id] == "string"){
result = currentObject[id]
}
})
if (typeof result == "string") return result
else return this.#getBackupTranslation(id)
}
/**Get a backup translation string by JSON location. (system only) */
#getBackupTranslation(id:string): string|null {
if (!this.backup) return null
const splitted = id.split(".")
let currentObject = this.backup.data
let result: string|false = false
splitted.forEach((id) => {
if (typeof currentObject[id] == "object"){
currentObject = currentObject[id]
}else if (typeof currentObject[id] == "string"){
result = currentObject[id]
}
})
if (typeof result == "string") return result
else return null
}
/**Get a backup translation string by JSON location and replace `{0}`,`{1}`,`{2}`,... with the provided parameters. */
getTranslationWithParams(id:string, params:string[]): string|null {
let translation = this.getTranslation(id)
if (!translation) return translation
params.forEach((value,index) => {
if (!translation) return
translation = translation.replace(`{${index}}`,value)
})
return translation
}
/**Init all language files. */
async init(){
for (const language of this.getAll()){
try{
await language.init()
}catch(err){
process.emit("uncaughtException",new ODSystemError(err))
}
}
}
}
/**## 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 = ""
/**The path to the file relative to the main directory. */
path: string = ""
/**The raw object data of the translation. */
data: any
/**The metadata of the language if available. */
metadata: ODLanguageMetadata|null = null
constructor(id:ODValidId, data:any){
super(id)
this.data = data
}
/**Init the language. */
init(): ODPromiseVoid {
//nothing
}
}
/**## 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,{})
this.file = (file.endsWith(".json")) ? file : file+".json"
this.path = customPath ? nodepath.join("./",customPath,this.file) : nodepath.join("./languages/",this.file)
}
/**Init the langauge. */
init(): ODPromiseVoid {
if (!fs.existsSync(this.path)) throw new ODSystemError("Unable to parse language \""+nodepath.join("./",this.path)+"\", the file doesn't exist!")
try{
this.data = JSON.parse(fs.readFileSync(this.path).toString())
}catch(err){
process.emit("uncaughtException",err)
throw new ODSystemError("Unable to parse language \""+nodepath.join("./",this.path)+"\"!")
}
if (this.data["_TRANSLATION"]) this.metadata = this.data["_TRANSLATION"]
}
}
-340
View File
@@ -1,340 +0,0 @@
///////////////////////////////////////
//PERMISSION MODULE
///////////////////////////////////////
import { ODId, ODValidId, ODManager, ODSystemError, ODManagerData } from "./base"
import * as discord from "discord.js"
import { ODDebugger } from "./console"
import { ODClientManager } from "./client"
/**## 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)
constructor(id:ODValidId, scope:"global-role", permission:ODPermissionType, value:discord.Role)
constructor(id:ODValidId, scope:"channel-user", permission:ODPermissionType, value:discord.User, channel:discord.Channel)
constructor(id:ODValidId, scope:"channel-role", permission:ODPermissionType, value:discord.Role, channel:discord.Channel)
constructor(id:ODValidId, scope:ODPermissionScope, permission:ODPermissionType, value:discord.Role|discord.User, channel?:discord.Channel){
super(id)
this.scope = scope
this.permission = permission
this.value = value
this.channel = channel ?? null
}
}
/**## 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<ODPermissionResult>
/**## ODPermissionCommandResult `type`
* The result of calculating permissions for a command.
*/
export type ODPermissionCommandResult = {
/**Returns `true` when the user has valid permissions. */
hasPerms:false,
reason:"no-perms"|"disabled"|"not-in-server"
}|{
/**Returns `true` when the user has valid permissions. */
hasPerms:true,
/**Is the user a server admin or a normal member? This does not decide if the user has permissions or not. */
isAdmin:boolean
}
/**## 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<ODPermission> {
/**Alias for Open Ticket debugger. */
#debug: ODDebugger
/**The function for calculating permissions in this manager. */
#calculation: ODPermissionCalculationCallback|null
/**An alias to the Open Discord client manager. */
#client: ODClientManager
/**The result which is returned when no other permissions match. (`member` by default) */
defaultResult: ODPermissionResult = {
level:ODPermissionLevel["member"],
scope:"default",
type:"member",
source:null
}
constructor(debug:ODDebugger, client:ODClientManager, useDefaultCalculation?:boolean){
super(debug,"permission")
this.#debug = debug
this.#calculation = useDefaultCalculation ? this.#defaultCalculation : null
this.#client = client
}
/**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<ODPermissionResult> {
try{
if (!this.#calculation) throw new ODSystemError("ODPermissionManager:getPermissions() => missing perms calculation")
return this.#calculation(user,channel,guild,settings)
}catch(err){
process.emit("uncaughtException",err)
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"])
else if (minimum == "moderator") return (data.level >= ODPermissionLevel["moderator"])
else if (minimum == "admin") return (data.level >= ODPermissionLevel["admin"])
else if (minimum == "owner") return (data.level >= ODPermissionLevel["owner"])
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<ODPermissionResult> {
const globalCalc = await this.#defaultGlobalCalculation(user,channel,guild,settings)
const channelCalc = await this.#defaultChannelCalculation(user,channel,guild,settings)
if (globalCalc.level > channelCalc.level) return globalCalc
else return channelCalc
}
/**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<ODPermissionResult> {
const idRegex = (settings && typeof settings.idRegex != "undefined") ? settings.idRegex : null
const allowGlobalUserScope = (settings && typeof settings.allowGlobalUserScope != "undefined") ? settings.allowGlobalUserScope : true
const allowGlobalRoleScope = (settings && typeof settings.allowGlobalRoleScope != "undefined") ? settings.allowGlobalRoleScope : true
//check for global user permissions
if (allowGlobalUserScope){
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)
if (users.length > 0){
//sort all permisions from highest to lowest
users.sort((a,b) => {
const levelA = ODPermissionLevel[a.permission]
const levelB = ODPermissionLevel[b.permission]
if (levelB > levelA) return 1
else if (levelA > levelB) return -1
else return 0
})
return {
type:users[0].permission,
scope:"global-user",
level:ODPermissionLevel[users[0].permission],
source:users[0] ?? null
}
}
}
//check for global role permissions
if (allowGlobalRoleScope){
if (guild){
const member = await this.#client.fetchGuildMember(guild,user.id)
if (member){
const memberRoles = member.roles.cache.map((role) => role.id)
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)
if (roles.length > 0){
//sort all permisions from highest to lowest
roles.sort((a,b) => {
const levelA = ODPermissionLevel[a.permission]
const levelB = ODPermissionLevel[b.permission]
if (levelB > levelA) return 1
else if (levelA > levelB) return -1
else return 0
})
return {
type:roles[0].permission,
scope:"global-role",
level:ODPermissionLevel[roles[0].permission],
source:roles[0] ?? null
}
}
}
}
}
//spread result to prevent accidental referencing
return {...this.defaultResult}
}
/**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<ODPermissionResult> {
const idRegex = (settings && typeof settings.idRegex != "undefined") ? settings.idRegex : null
const allowChannelUserScope = (settings && typeof settings.allowChannelUserScope != "undefined") ? settings.allowChannelUserScope : true
const allowChannelRoleScope = (settings && typeof settings.allowChannelRoleScope != "undefined") ? settings.allowChannelRoleScope : true
if (guild && channel && !channel.isDMBased()){
//check for channel user permissions
if (allowChannelUserScope){
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)
if (users.length > 0){
//sort all permisions from highest to lowest
users.sort((a,b) => {
const levelA = ODPermissionLevel[a.permission]
const levelB = ODPermissionLevel[b.permission]
if (levelB > levelA) return 1
else if (levelA > levelB) return -1
else return 0
})
return {
type:users[0].permission,
scope:"channel-user",
level:ODPermissionLevel[users[0].permission],
source:users[0] ?? null
}
}
}
//check for channel role permissions
if (allowChannelRoleScope){
const member = await this.#client.fetchGuildMember(guild,user.id)
if (member){
const memberRoles = member.roles.cache.map((role) => role.id)
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)
if (roles.length > 0){
//sort all permisions from highest to lowest
roles.sort((a,b) => {
const levelA = ODPermissionLevel[a.permission]
const levelB = ODPermissionLevel[b.permission]
if (levelB > levelA) return 1
else if (levelA > levelB) return -1
else return 0
})
return {
type:roles[0].permission,
scope:"channel-role",
level:ODPermissionLevel[roles[0].permission],
source:roles[0] ?? null
}
}
}
}
}
//spread result to prevent accidental modification because of referencing
return {...this.defaultResult}
}
/**Check the permissions for a certain command of the bot. */
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> {
if (permissionMode === "none"){
return {hasPerms:false,reason:"disabled"}
}else if (permissionMode === "everyone"){
const isAdmin = this.hasPermissions(requiredLevel,await this.getPermissions(user,channel,guild,settings))
return {hasPerms:true,isAdmin}
}else if (permissionMode === "admin"){
const isAdmin = this.hasPermissions(requiredLevel,await this.getPermissions(user,channel,guild,settings))
if (!isAdmin) return {hasPerms:false,reason:"no-perms"}
else return {hasPerms:true,isAdmin}
}else{
if (!guild || !member){
this.#debug.debug("ODPermissionManager.checkCommandPerms(): Permission Error, Not in server! (#1)")
return {hasPerms:false,reason:"not-in-server"}
}
const role = await this.#client.fetchGuildRole(guild,permissionMode)
if (!role){
this.#debug.debug("ODPermissionManager.checkCommandPerms(): Permission Error, Not in server! (#2)")
return {hasPerms:false,reason:"not-in-server"}
}
if (!role.members.has(member.id)) return {hasPerms:false,reason:"no-perms"}
const isAdmin = this.hasPermissions(requiredLevel,await this.getPermissions(user,channel,guild,settings))
return {hasPerms:true,isAdmin}
}
}
}
-242
View File
@@ -1,242 +0,0 @@
///////////////////////////////////////
//PLUGIN MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODSystemError, ODValidId, ODVersion } from "./base"
import nodepath from "path"
import { ODConsolePluginMessage, ODConsoleWarningMessage, ODDebugger } from "./console"
/**## ODUnknownCrashedPlugin `interface`
* Basic details for a plugin that crashed while loading the `plugin.json` file.
*/
export interface ODUnknownCrashedPlugin {
/**The name of the plugin. (path when plugin crashed before `name` was loaded) */
name:string,
/**The description of the plugin. (when found before crashing) */
description:string
}
/**## ODPluginManager `class`
* This is an Open Ticket plugin manager.
*
* It manages all active plugins in the bot!
* It also contains all "plugin classes" which are managers registered by plugins.
* These are accessible via the `opendiscord.plugins.classes` global.
*
* Use `isPluginLoaded()` to check if a plugin has been loaded.
*/
export class ODPluginManager extends ODManager<ODPlugin> {
/**A manager for all custom managers registered by plugins. */
classes: ODPluginClassManager
/**A list of basic details from all plugins that crashed while loading the `plugin.json` file. */
unknownCrashedPlugins: ODUnknownCrashedPlugin[] = []
constructor(debug:ODDebugger){
super(debug,"plugin")
this.classes = new ODPluginClassManager(debug)
}
/**Check if a plugin has been loaded successfully and is available for usage.*/
isPluginLoaded(id:ODValidId): boolean {
const newId = new ODId(id)
const plugin = this.get(newId)
return (plugin !== null && plugin.executed)
}
}
/**## ODPluginData `interface`
* Parsed data from the `plugin.json` file in a plugin.
*/
export interface ODPluginData {
/**The name of this plugin (shown on startup) */
name:string,
/**The id of this plugin. (Must be identical to directory name) */
id:string,
/**The version of this plugin. */
version:string,
/**The location of the start file of the plugin relative to the rootDir of the plugin */
startFile:string,
/**A list of compatible versions. (e.g. `["OTv4.0.x", "OMv1.x.x"]`) (optional, will be required in future version)
* - `OT` --> Open Ticket support
* - `OM` --> Open Moderation support
*/
supportedVersions?:string[],
/**Is this plugin enabled? */
enabled:boolean,
/**The priority of this plugin. Higher priority will load before lower priority. */
priority:number,
/**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! */
events:string[]
/**Npm dependencies which are required for this plugin to work. */
npmDependencies:string[],
/**Plugins which are required for this plugin to work. */
requiredPlugins:string[],
/**Plugins which are incompatible with this plugin. */
incompatiblePlugins:string[],
/**Additional details about this plugin. */
details:ODPluginDetails
}
/**## ODPluginDetails `interface`
* Additional details in the `plugin.json` file from a plugin.
*/
export interface ODPluginDetails {
/**The main author of the plugin. Additional contributors can be specified in `contributors`. */
author:string,
/**A list of plugin contributors. (optional, will be required in future version) */
contributors?:string[],
/**A short description of this plugin. */
shortDescription:string,
/**A large description of this plugin. */
longDescription:string,
/**A URL to a cover image of this plugin. (currently unused) */
imageUrl:string,
/**A URL to the website/project page of this plugin. (currently unused) */
projectUrl:string,
/**A list of tags/categories that this plugin affects. */
tags:string[]
}
/**## ODPlugin `class`
* This is an Open Ticket plugin.
*
* It represents a single plugin in the `./plugins/` directory.
* All plugins are accessible via the `opendiscord.plugins` global.
*
* Don't re-execute plugins which are already enabled! It might break the bot or plugin.
*/
export class ODPlugin extends ODManagerData {
/**The name of the directory of this plugin. (same as id) */
dir: string
/**All plugin data found in the `plugin.json` file. */
data: ODPluginData
/**The name of this plugin. */
name: string
/**The priority of this plugin. */
priority: number
/**The version of this plugin. */
version: ODVersion
/**The additional details of this plugin. */
details: ODPluginDetails
/**Is this plugin enabled? */
enabled: boolean
/**Did this plugin execute successfully?. */
executed: boolean
/**Did this plugin crash? (A reason is available in the `crashReason`) */
crashed: boolean
/**The reason which caused this plugin to crash. */
crashReason: null|"incompatible.plugin"|"missing.plugin"|"missing.dependency"|"incompatible.version"|"executed" = null
constructor(dir:string, jsondata:ODPluginData){
super(jsondata.id)
this.dir = dir
this.data = jsondata
this.name = jsondata.name
this.priority = jsondata.priority
this.version = ODVersion.fromString("plugin",jsondata.version)
this.details = jsondata.details
this.enabled = jsondata.enabled
this.executed = false
this.crashed = false
}
/**Get the startfile location relative to the `./plugins/` directory. (`./dist/plugins/`) when compiled) */
getStartFile(){
const newFile = this.data.startFile.replace(/\.ts$/,".js")
return nodepath.join(this.dir,newFile)
}
/**Execute this plugin. Returns `false` on crash. */
async execute(debug:ODDebugger,force?:boolean): Promise<boolean> {
if ((this.enabled && !this.crashed) || force){
try{
//import relative plugin directory path (works on windows & unix based systems)
const pluginPath = nodepath.join("../../../../plugins/",this.getStartFile()).replaceAll("\\","/")
await import(pluginPath)
debug.console.log("Plugin \""+this.id.value+"\" loaded successfully!","plugin")
this.executed = true
return true
}catch(error){
this.crashed = true
this.crashReason = "executed"
debug.console.log(error.message+", canceling plugin execution...","plugin",[
{key:"path",value:"./plugins/"+this.dir}
])
debug.console.log("You can see more about this error in the ./otdebug.txt file!","info")
debug.console.debugfile.writeText(error.stack)
return false
}
}else return true
}
/**Check if a npm dependency exists. */
#checkDependency(id:string){
try{
require.resolve(id)
return true
}catch{
return false
}
}
/**Get a list of all missing npm dependencies that are required for this plugin. */
dependenciesInstalled(){
const missing: string[] = []
this.data.npmDependencies.forEach((d) => {
if (!this.#checkDependency(d)){
missing.push(d)
}
})
return missing
}
/**Get a list of all missing plugins that are required for this plugin. */
pluginsInstalled(manager:ODPluginManager){
const missing: string[] = []
this.data.requiredPlugins.forEach((p) => {
const plugin = manager.get(p)
if (!plugin || !plugin.enabled){
missing.push(p)
}
})
return missing
}
/**Get a list of all enabled incompatible plugins that interfere with this plugin. */
pluginsIncompatible(manager:ODPluginManager){
const incompatible: string[] = []
this.data.incompatiblePlugins.forEach((p) => {
const plugin = manager.get(p)
if (plugin && plugin.enabled){
incompatible.push(p)
}
})
return incompatible
}
/**Get a list of all authors & contributors of this plugin. */
getAuthors(): string[] {
return [this.details.author,...(this.details.contributors ?? [])]
}
}
/**## ODPluginClassManager `class`
* This is an Open Ticket plugin class manager.
*
* It manages all managers registered by plugins!
* Plugins are able to register their own managers, handlers, functions, classes, ... here.
* By doing this, other plugins are also able to make use of it.
* This can be useful for plugins that want to extend other plugins.
*
* Use `isPluginLoaded()` to check if a plugin has been loaded before trying to access the manager.
*/
export class ODPluginClassManager extends ODManager<ODManagerData> {
constructor(debug:ODDebugger){
super(debug,"plugin class")
}
}
-90
View File
@@ -1,90 +0,0 @@
///////////////////////////////////////
//POST MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODValidId } from "./base"
import { ODMessageBuildResult, ODMessageBuildSentResult } from "./builder"
import { ODDebugger } from "./console"
import * as discord from "discord.js"
/**## ODPostManager `class`
* This is an Open Ticket post manager.
*
* It manages `ODPosts`'s for you.
*
* You can use this to get the logs channel of the bot (or some other static channel/category).
*/
export class ODPostManager extends ODManager<ODPost<discord.GuildBasedChannel>> {
/**A reference to the main server of the bot */
#guild: discord.Guild|null = null
constructor(debug:ODDebugger){
super(debug,"post")
}
add(data:ODPost<discord.GuildBasedChannel>, overwrite?:boolean): boolean {
if (this.#guild) data.useGuild(this.#guild)
return super.add(data,overwrite)
}
/**Initialize the post manager & all posts. */
async init(guild:discord.Guild){
this.#guild = guild
for (const post of this.getAll()){
post.useGuild(guild)
await post.init()
}
}
}
/**## ODPost `class`
* This is an Open Ticket post class.
*
* A post is just a shortcut to a static discord channel or category.
* This can be used to get a specific channel over and over again!
*
* This class also contains utilities for sending messages via the Open Ticket builders.
*/
export class ODPost<ChannelType extends discord.GuildBasedChannel> extends ODManagerData {
/**A reference to the main server of the bot */
#guild: discord.Guild|null = null
/**Is this post already initialized? */
ready: boolean = false
/**The discord.js channel */
channel: ChannelType|null = null
/**The discord channel id */
channelId: string
constructor(id:ODValidId, channelId:string){
super(id)
this.channelId = channelId
}
/**Use a specific guild in this class for fetching the channel*/
useGuild(guild:discord.Guild|null){
this.#guild = guild
}
/**Change the channel id to another channel! */
setChannelId(id:string){
this.channelId = id
}
/**Initialize the discord.js channel of this post. */
async init(){
if (this.ready) return
if (!this.#guild) return this.channel = null
try{
this.channel = await this.#guild.channels.fetch(this.channelId) as ChannelType
}catch{
this.channel = null
}
this.ready = true
}
/**Send a message to this channel using the Open Ticket builder system */
async send(msg:ODMessageBuildResult): Promise<ODMessageBuildSentResult<true>> {
if (!this.channel || !this.channel.isTextBased()) return {success:false,message:null}
try{
const sent = await this.channel.send(msg.message)
return {success:true,message:sent}
}catch{
return {success:false,message:null}
}
}
}
-232
View File
@@ -1,232 +0,0 @@
///////////////////////////////////////
//PROGRESS BAR MODULE
///////////////////////////////////////
import { ODSystemError, ODManager, ODManagerData, ODValidId } from "./base"
import { ODDebugger } from "./console"
import readline from "readline"
/**## ODProgressBarRendererManager `class`
* This is an Open Ticket progress bar renderer manager.
*
* It is responsible for managing all console progress bar renderers in Open Ticket.
*
* A renderer is a function which will try to visualize the progress bar in the console.
*/
export class ODProgressBarRendererManager extends ODManager<ODProgressBarRenderer<{}>> {
constructor(debug:ODDebugger){
super(debug,"progress bar renderer")
}
}
/**## ODProgressBarManager `class`
* This is an Open Ticket progress bar manager.
*
* It is responsible for managing all console progress bars in Open Ticket. An example of this is the slash command registration progress bar.
*
* There are many types of progress bars available, but you can also create your own!
*/
export class ODProgressBarManager extends ODManager<ODProgressBar> {
renderers: ODProgressBarRendererManager
constructor(debug:ODDebugger){
super(debug,"progress bar")
this.renderers = new ODProgressBarRendererManager(debug)
}
}
/**## ODProgressBarRenderFunc `type`
* This is the render function for an Open Ticket console progress bar.
*/
export type ODProgressBarRenderFunc<Settings extends {}> = (settings:Settings,min:number,max:number,value:number,prefix:string|null,suffix:string|null) => string
/**## ODProgressBarRenderer `class`
* This is an Open Ticket console progress bar renderer.
*
* It is used to render a progress bar in the console of the bot.
*
* There are already a lot of default options available if you just want an easy progress bar!
*/
export class ODProgressBarRenderer<Settings extends {}> extends ODManagerData {
settings: Settings
#render: ODProgressBarRenderFunc<Settings>
constructor(id:ODValidId,render:ODProgressBarRenderFunc<Settings>,settings:Settings){
super(id)
this.#render = render
this.settings = settings
}
/**Render a progress bar using this renderer. */
render(min:number,max:number,value:number,prefix:string|null,suffix:string|null){
try {
return this.#render(this.settings,min,max,value,prefix,suffix)
}catch(err){
process.emit("uncaughtException",err)
return "<PROGRESS-BAR-ERROR>"
}
}
withAdditionalSettings(settings:Partial<Settings>): ODProgressBarRenderer<Settings> {
const newSettings: Settings = {...this.settings}
for (const key of Object.keys(settings)){
if (typeof settings[key] != "undefined") newSettings[key] = settings[key]
}
return new ODProgressBarRenderer(this.id,this.#render,newSettings)
}
}
/**## ODProgressBar `class`
* This is an Open Ticket console progress bar.
*
* It is used to create a simple or advanced progress bar in the console of the bot.
* These progress bars are not visible in the `otdebug.txt` file and should only be used as extra visuals.
*
* Use other classes as existing templates or create your own progress bar from scratch using this class.
*/
export class ODProgressBar extends ODManagerData {
/**The renderer of this progress bar. */
renderer: ODProgressBarRenderer<{}>
/**Is this progress bar currently active? */
#active: boolean = false
/**A list of listeners when the progress bar stops. */
#stopListeners: Function[] = []
/**The current value of the progress bar. */
protected value: number
/**The minimum value of the progress bar. */
min: number
/**The maximum value of the progress bar. */
max: number
/**The initial value of the progress bar. */
initialValue: number
/**The prefix displayed in the progress bar. */
prefix:string|null
/**The prefix displayed in the progress bar. */
suffix:string|null
/**Enable automatic stopping when reaching `min` or `max`. */
autoStop: null|"min"|"max"
constructor(id:ODValidId,renderer:ODProgressBarRenderer<{}>,min:number,max:number,value:number,autoStop:null|"min"|"max",prefix:string|null,suffix:string|null){
super(id)
this.renderer = renderer
this.min = min
this.max = max
this.initialValue = this.#parseValue(value)
this.value = this.#parseValue(value)
this.autoStop = autoStop
this.prefix = prefix
this.suffix = suffix
}
/**Parse a value in such a way that it doesn't go below/above the min/max limits. */
#parseValue(value:number){
if (value > this.max) return this.max
else if (value < this.min) return this.min
else return value
}
/**Render progress bar to the console. */
#renderStdout(){
if (!this.#active) return
readline.clearLine(process.stdout,0)
readline.cursorTo(process.stdout,0)
process.stdout.write(this.renderer.render(this.min,this.max,this.value,this.prefix,this.suffix))
}
/**Start showing this progress bar in the console. */
start(): boolean {
if (this.#active) return false
this.value = this.#parseValue(this.initialValue)
this.#active = true
this.#renderStdout()
return true
}
/**Update this progress bar while active. (will automatically update the progress bar in the console) */
protected update(value:number,stop?:boolean): boolean {
if (!this.#active) return false
this.value = this.#parseValue(value)
this.#renderStdout()
if (stop || (this.autoStop == "max" && this.value == this.max) || (this.autoStop == "min" && this.value == this.min)){
process.stdout.write("\n")
this.#active = false
this.#stopListeners.forEach((cb) => cb())
this.#stopListeners = []
}
return true
}
/**Wait for the progress bar to finish. */
finished(): Promise<void> {
return new Promise((resolve) => {
this.#stopListeners.push(resolve)
})
}
}
/**## ODTimedProgressBar `class`
* This is an Open Ticket timed console progress bar.
*
* It is used to create a simple timed progress bar in the console.
* You can set a fixed duration (milliseconds) in the constructor.
*/
export class ODTimedProgressBar extends ODProgressBar {
/**The time in milliseconds. */
time: number
/**The mode of the timer. */
mode: "increasing"|"decreasing"
constructor(id:ODValidId,renderer:ODProgressBarRenderer<{}>,time:number,mode:"increasing"|"decreasing",prefix:string|null,suffix:string|null){
super(id,renderer,0,time,0,(mode == "increasing") ? "max" : "min",prefix,suffix)
this.time = time
this.mode = mode
}
/**The timer which is used. */
async #timer(ms:number): Promise<void> {
return new Promise((resolve) => {
setTimeout(() => {
resolve()
},ms)
})
}
/**Run the timed progress bar. */
async #execute(){
let i = 0
const fragment = this.time/100
while (i < 100){
await this.#timer(fragment)
i++
super.update((this.mode == "increasing") ? (i*fragment) : this.time-(i*fragment))
}
}
start(){
const res = super.start()
if (!res) return false
this.#execute()
return true
}
}
/**## ODManualProgressBar `class`
* This is an Open Ticket manual console progress bar.
*
* It is used to create a simple manual progress bar in the console.
* You can update the progress manually using `update()`.
*/
export class ODManualProgressBar extends ODProgressBar {
constructor(id:ODValidId,renderer:ODProgressBarRenderer<{}>,amount:number,autoStop:null|"min"|"max",prefix:string|null,suffix:string|null){
super(id,renderer,0,amount,0,autoStop,prefix,suffix)
}
/**Set the value of the progress bar. */
set(value:number,stop?:boolean){
super.update(value,stop)
}
/**Get the current value of the progress bar. */
get(){
return this.value
}
/**Increase the value of the progress bar. */
increase(amount:number,stop?:boolean){
super.update(this.value+amount,stop)
}
/**Decrease the value of the progress bar. */
decrease(amount:number,stop?:boolean){
super.update(this.value-amount,stop)
}
}
File diff suppressed because it is too large Load Diff
-155
View File
@@ -1,155 +0,0 @@
///////////////////////////////////////
//SESSION MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODValidId } from "./base"
import { ODDebugger } from "./console"
import * as crypto from "crypto"
/**## ODSessionManager `class`
* This is an Open Ticket session manager.
*
* It contains all sessions in Open Ticket. Sessions are a sort of temporary storage which will be cleared when the bot stops.
* Data in sessions have a randomly generated key which will always be unique.
*
* Visit the `ODSession` class for more info
*/
export class ODSessionManager extends ODManager<ODSession> {
constructor(debug:ODDebugger){
super(debug,"session")
}
}
/**## ODSessionInstance `interface`
* This interface represents a single session instance. It contains an id, data & some dates.
*/
export interface ODSessionInstance {
/**The id of this session instance. */
id:string,
/**The creation date of this session instance. */
creation:number,
/**The custom amount of minutes before this session expires. */
timeout:number|null,
/**This is the data from this session instance */
data:any
}
/**## ODSessionTimeoutCallback `type`
* This is the callback used for session timeout listeners.
*/
export type ODSessionTimeoutCallback = (id:string, timeout:"default"|"custom", data:any, creation:Date) => void
/**## ODSession `class`
* This is an Open Ticket session.
*
* 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.
* You can almost compare it to the PHP session system.
*/
export class ODSession extends ODManagerData {
/**The history of previously generated instance ids. Used to reduce the risk of generating the same id twice. */
#idHistory: string[] = []
/**The max length of the instance id history. */
#maxIdHistoryLength: number = 500
/**An array of all the currently active session instances. */
sessions: ODSessionInstance[] = []
/**The default amount of minutes before a session automatically stops. */
timeoutMinutes: number = 30
/**The id of the auto-timeout session checker interval */
#intervalId: NodeJS.Timeout
/**Listeners for when a session times-out. */
#timeoutListeners: ODSessionTimeoutCallback[] = []
constructor(id:ODValidId, intervalSeconds?:number){
super(id)
//create the auto-timeout session checker
this.#intervalId = setInterval(() => {
const deletableSessions: {instance:ODSessionInstance,reason:"default"|"custom"}[] = []
//collect all deletable sessions
this.sessions.forEach((session) => {
if (session.timeout && (new Date().getTime() - session.creation) > session.timeout*60000){
//stop session => custom timeout
deletableSessions.push({instance:session,reason:"custom"})
}else if (!session.timeout && (new Date().getTime() - session.creation) > this.timeoutMinutes*60000){
//stop session => default timeout
deletableSessions.push({instance:session,reason:"default"})
}
})
//permanently delete sessions
deletableSessions.forEach((session) => {
const index = this.sessions.findIndex((s) => s.id === session.instance.id)
this.sessions.splice(index,1)
//emit timeout listeners
this.#timeoutListeners.forEach((cb) => cb(session.instance.id,session.reason,session.instance.data,new Date(session.instance.creation)))
})
},((intervalSeconds) ? (intervalSeconds * 1000) : 60000))
}
/**Create a unique hex id of 8 characters and add it to the instance id history */
#createUniqueId(): string {
const hex = crypto.randomBytes(4).toString("hex")
if (this.#idHistory.includes(hex)){
return this.#createUniqueId()
}else{
this.#idHistory.push(hex)
if (this.#idHistory.length > this.#maxIdHistoryLength) this.#idHistory.shift()
return hex
}
}
/**Stop the global interval that automatically deletes timed-out sessions. (This action can't be reverted!) */
stopAutoTimeout(){
clearInterval(this.#intervalId)
}
/**Start a session instance with data. Returns the unique id required to access the session. */
start(data?:any): string {
const id = this.#createUniqueId()
this.sessions.push({
id,data,
creation:new Date().getTime(),
timeout:null
})
return id
}
/**Get the data of a session instance. Returns `null` when not found. */
data(id:string): any|null {
const session = this.sessions.find((session) => session.id === id)
if (!session) return null
return session.data
}
/**Stop & delete a session instance. Returns `true` when sucessful. */
stop(id:string): boolean {
const index = this.sessions.findIndex((session) => session.id === id)
if (index < 0) return false
this.sessions.splice(index,1)
return true
}
/**Update the data of a session instance. Returns `true` when sucessful. */
update(id:string, data:any): boolean {
const session = this.sessions.find((session) => session.id === id)
if (!session) return false
session.data = data
return true
}
/**Change the global or session timeout minutes. Returns `true` when sucessful. */
setTimeout(min:number, id?:string): boolean {
if (!id){
//change global timeout minutes
this.timeoutMinutes = min
return true
}else{
//change session instance timeout minutes
const session = this.sessions.find((session) => session.id === id)
if (!session) return false
session.timeout = min
return true
}
}
/**Listen for a session timeout (default or custom) */
onTimeout(callback:ODSessionTimeoutCallback){
this.#timeoutListeners.push(callback)
}
}
-320
View File
@@ -1,320 +0,0 @@
///////////////////////////////////////
//STARTSCREEN MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODValidId } from "./base"
import { ODDebugger, ODError, ODLiveStatusManager } from "./console"
import { ODFlag } from "./flag"
import { ODPlugin, ODUnknownCrashedPlugin } from "./plugin"
import ansis from "ansis"
/**## ODStartScreenComponentRenderCallback `type`
* This is the render function of a startscreen component. It also sends the location of where the component is rendered.
*/
export type ODStartScreenComponentRenderCallback = (location:number) => string|Promise<string>
/**## ODStartScreenManager `class`
* This is an Open Ticket startscreen manager.
*
* This class is responsible for managing & rendering the startscreen of the bot.
* The startscreen is the part you see when the bot has started up successfully. (e.g. the Open Ticket logo, logs, livestatus, flags, ...)
*/
export class ODStartScreenManager extends ODManager<ODStartScreenComponent> {
/**Alias to the Open Ticket debugger. */
#debug: ODDebugger
/**Alias to the livestatus manager. */
livestatus: ODLiveStatusManager
constructor(debug:ODDebugger,livestatus:ODLiveStatusManager){
super(debug,"startscreen component")
this.#debug = debug
this.livestatus = livestatus
}
/**Get all components in sorted order. */
getSortedComponents(priority:"ascending"|"descending"){
return this.getAll().sort((a,b) => {
if (priority == "ascending") return a.priority-b.priority
else return b.priority-a.priority
})
}
/**Render all startscreen components in priority order. */
async renderAllComponents(){
const components = this.getSortedComponents("descending")
let location = 0
for (const component of components){
try {
const renderedText = await component.renderAll(location)
console.log(renderedText)
this.#debug.console.debugfile.writeText("[STARTSCREEN] Component: \""+component.id+"\"\n"+ansis.strip(renderedText))
}catch(e){
this.#debug.console.log("Unable to render \""+component.id+"\" startscreen component!","error")
this.#debug.console.debugfile.writeErrorMessage(new ODError(e,"uncaughtException"))
}
location++
}
}
}
/**## ODStartScreenComponent `class`
* This is an Open Ticket startscreen component.
*
* This component can be rendered to the start screen of the bot.
* An optional priority can be specified to choose the location of the component.
*
* It's recommended to use pre-built components except if you really need a custom one.
*/
export class ODStartScreenComponent extends ODManagerData {
/**The priority of this component. */
priority: number
/**An optional render function which will be inserted before the default renderer. */
renderBefore: ODStartScreenComponentRenderCallback|null = null
/**The render function which will render the contents of this component. */
render: ODStartScreenComponentRenderCallback
/**An optional render function which will be inserted behind the default renderer. */
renderAfter: ODStartScreenComponentRenderCallback|null = null
constructor(id:ODValidId, priority:number, render:ODStartScreenComponentRenderCallback){
super(id)
this.priority = priority
this.render = render
}
/**Render this component and combine it with the `renderBefore` & `renderAfter` contents. */
async renderAll(location:number){
const textBefore = (this.renderBefore) ? await this.renderBefore(location) : ""
const text = await this.render(location)
const textAfter = (this.renderAfter) ? await this.renderAfter(location) : ""
return (textBefore ? textBefore+"\n" : "")+text+(textAfter ? "\n"+textAfter : "")
}
}
/**## ODStartScreenProperty `type`
* This interface contains properties used in a few default templates of the startscreen component.
*/
export interface ODStartScreenProperty {
/**The key or name of this property. */
key:string,
/**The value or contents of this property. */
value:string
}
/**## ODStartScreenLogoComponent `class`
* This is an Open Ticket startscreen logo component.
*
* This component will render an ASCII art logo (from an array) to the startscreen. Every property in the array is another row.
* An optional priority can be specified to choose the location of the component.
*/
export class ODStartScreenLogoComponent extends ODStartScreenComponent {
/**The ASCII logo contents. */
logo: string[]
/**When enabled, the component will add a new line above the logo. */
topPadding: boolean
/**When enabled, the component will add a new line below the logo. */
bottomPadding: boolean
/**The color of the logo in hex format. */
logoHexColor: string
constructor(id:ODValidId, priority:number, logo:string[], topPadding?:boolean, bottomPadding?:boolean, logoHexColor?:string){
super(id,priority,() => {
const renderedTop = (this.topPadding ? "\n" : "")
const renderedLogo = this.logo.join("\n")
const renderedBottom = (this.bottomPadding ? "\n" : "")
return ansis.hex(this.logoHexColor)(renderedTop+renderedLogo+renderedBottom)
})
this.logo = logo
this.topPadding = topPadding ?? false
this.bottomPadding = bottomPadding ?? false
this.logoHexColor = logoHexColor ?? "#f8ba00"
}
}
/**## ODStartScreenHeaderAlignmentSettings `type`
* This interface contains all settings used in the startscreen header component.
*/
export interface ODStartScreenHeaderAlignmentSettings {
/**The alignment settings for this header. */
align:"center"|"left"|"right",
/**The width or component to use when calculating center & right alignment. */
width:number|ODStartScreenComponent
}
/**## ODStartScreenHeaderComponent `class`
* This is an Open Ticket startscreen header component.
*
* This component will render a header to the startscreen. Properties can be aligned left, right or centered.
* An optional priority can be specified to choose the location of the component.
*/
export class ODStartScreenHeaderComponent extends ODStartScreenComponent {
/**All properties of this header component. */
properties: ODStartScreenProperty[]
/**The spacer used between properties. */
spacer: string
/**The alignment settings of this header component. */
align: ODStartScreenHeaderAlignmentSettings|null
constructor(id:ODValidId, priority:number, properties:ODStartScreenProperty[], spacer?:string, align?:ODStartScreenHeaderAlignmentSettings){
super(id,priority,async () => {
const renderedProperties = ansis.bold(this.properties.map((prop) => prop.key+": "+prop.value).join(this.spacer))
if (!this.align || this.align.align == "left"){
return renderedProperties
}else if (this.align.align == "right"){
const width = (typeof this.align.width == "number") ? this.align.width : (
ansis.strip(await this.align.width.renderAll(0)).split("\n").map((row) => row.length).reduce((prev,curr) => {
if (prev < curr) return curr
else return prev
},0)
)
const offset = width - ansis.strip(renderedProperties).length
if (offset < 0) return renderedProperties
else{
return (" ".repeat(offset) + renderedProperties)
}
}else if (this.align.align == "center"){
const width = (typeof this.align.width == "number") ? this.align.width : (
ansis.strip(await this.align.width.renderAll(0)).split("\n").map((row) => row.length).reduce((prev,curr) => {
if (prev < curr) return curr
else return prev
})
)
const offset = Math.round((width - ansis.strip(renderedProperties).length)/2)
if (offset < 0) return renderedProperties
else{
return (" ".repeat(offset) + renderedProperties)
}
}
return renderedProperties
})
this.properties = properties
this.spacer = spacer ?? " - "
this.align = align ?? null
}
}
/**## ODStartScreenCategoryComponent `class`
* This is an Open Ticket startscreen category component.
*
* This component will render a category to the startscreen. This will only render the category name. You'll need to provide your own renderer for the contents.
* An optional priority can be specified to choose the location of the component.
*/
export class ODStartScreenCategoryComponent extends ODStartScreenComponent {
/**The name of this category. */
name: string
/**When enabled, this category will still be rendered when the contents are empty. (enabled by default) */
renderIfEmpty: boolean
constructor(id:ODValidId, priority:number, name:string, render:ODStartScreenComponentRenderCallback, renderIfEmpty?:boolean){
super(id,priority,async (location) => {
const contents = await render(location)
if (contents != "" || this.renderIfEmpty){
return ansis.bold.underline("\n"+name.toUpperCase()+(contents != "" ? ":\n" : ":")) + contents
}else return ""
})
this.name = name
this.renderIfEmpty = renderIfEmpty ?? true
}
}
/**## ODStartScreenPropertiesCategoryComponent `class`
* This is an Open Ticket startscreen properties category component.
*
* This component will render a properties category to the startscreen. This will list the properties in the category.
* An optional priority can be specified to choose the location of the component.
*/
export class ODStartScreenPropertiesCategoryComponent extends ODStartScreenCategoryComponent {
/**The properties of this category component. */
properties: ODStartScreenProperty[]
/**The hex color for the key/name of all the properties. */
propertyHexColor: string
constructor(id:ODValidId, priority:number, name:string, properties:ODStartScreenProperty[], propertyHexColor?:string, renderIfEmpty?:boolean){
super(id,priority,name,() => {
return this.properties.map((prop) => ansis.hex(this.propertyHexColor)(prop.key+": ")+prop.value).join("\n")
},renderIfEmpty)
this.properties = properties
this.propertyHexColor = propertyHexColor ?? "#f8ba00"
}
}
/**## ODStartScreenFlagsCategoryComponent `class`
* This is an Open Ticket startscreen flags category component.
*
* This component will render a flags category to the startscreen. This will list the enabled flags in the category.
* An optional priority can be specified to choose the location of the component.
*/
export class ODStartScreenFlagsCategoryComponent extends ODStartScreenCategoryComponent {
/**A list of all flags to render. */
flags: ODFlag[]
constructor(id:ODValidId, priority:number, flags:ODFlag[]){
super(id,priority,"flags",() => {
return this.flags.filter((flag) => (flag.value == true)).map((flag) => ansis.blue("["+flag.name+"] "+flag.description)).join("\n")
},false)
this.flags = flags
}
}
/**## ODStartScreenPluginsCategoryComponent `class`
* This is an Open Ticket startscreen plugins category component.
*
* This component will render a plugins category to the startscreen. This will list the enabled, disabled & crashed plugins in the category.
* An optional priority can be specified to choose the location of the component.
*/
export class ODStartScreenPluginsCategoryComponent extends ODStartScreenCategoryComponent {
/**A list of all plugins to render. */
plugins: ODPlugin[]
/**A list of all crashed plugins to render. */
unknownCrashedPlugins: ODUnknownCrashedPlugin[]
constructor(id:ODValidId, priority:number, plugins:ODPlugin[], unknownCrashedPlugins:ODUnknownCrashedPlugin[]){
super(id,priority,"plugins",() => {
const disabledPlugins = this.plugins.filter((plugin) => !plugin.enabled)
const renderedActivePlugins = this.plugins.filter((plugin) => plugin.enabled && plugin.executed).sort((a,b) => b.priority-a.priority).map((plugin) => ansis.green("✅ ["+plugin.name+"] "+plugin.details.shortDescription))
const renderedCrashedPlugins = this.plugins.filter((plugin) => plugin.enabled && plugin.crashed).sort((a,b) => b.priority-a.priority).map((plugin) => ansis.red("❌ ["+plugin.name+"] "+plugin.details.shortDescription))
const renderedDisabledPlugins = (disabledPlugins.length > 4) ? [ansis.gray("💤 (+"+disabledPlugins.length+" disabled plugins)")] : disabledPlugins.sort((a,b) => b.priority-a.priority).map((plugin) => ansis.gray("💤 ["+plugin.name+"] "+plugin.details.shortDescription))
const renderedUnknownPlugins = unknownCrashedPlugins.map((plugin) => ansis.red("❌ ["+plugin.name+"] "+plugin.description))
return [
...renderedActivePlugins,
...renderedDisabledPlugins,
...renderedCrashedPlugins,
...renderedUnknownPlugins
].join("\n")
},false)
this.plugins = plugins
this.unknownCrashedPlugins = unknownCrashedPlugins
}
}
/**## ODStartScreenLiveStatusCategoryComponent `class`
* This is an Open Ticket startscreen livestatus category component.
*
* This component will render a livestatus category to the startscreen. This will list the livestatus messages in the category.
* An optional priority can be specified to choose the location of the component.
*/
export class ODStartScreenLiveStatusCategoryComponent extends ODStartScreenCategoryComponent {
/**A reference to the Open Ticket livestatus manager. */
livestatus: ODLiveStatusManager
constructor(id:ODValidId, priority:number, livestatus:ODLiveStatusManager){
super(id,priority,"livestatus",async () => {
const messages = await this.livestatus.getAllMessages()
return this.livestatus.renderer.render(messages)
},false)
this.livestatus = livestatus
}
}
/**## ODStartScreenLogsCategoryComponent `class`
* This is an Open Ticket startscreen logs category component.
*
* This component will render a logs category to the startscreen. This will only render the logs category name.
* An optional priority can be specified to choose the location of the component.
*/
export class ODStartScreenLogCategoryComponent extends ODStartScreenCategoryComponent {
constructor(id:ODValidId, priority:number){
super(id,priority,"logs",() => "",true)
}
}
-313
View File
@@ -1,313 +0,0 @@
///////////////////////////////////////
//STAT MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODSystemError, ODValidId } from "./base"
import { ODDebugger } from "./console"
import { ODDatabase, ODJsonDatabaseStructure } from "./database"
import * as discord from "discord.js"
/**## ODValidStatValue `type`
* These are the only allowed types for a stat value to improve compatibility with different database systems.
*/
export type ODValidStatValue = string|number|boolean
/**## ODStatsManagerInitCallback `type`
* This callback can be used to execute something when the stats have been initiated.
*
* By default this is used to clear stats from users that left the server or tickets which don't exist anymore.
*/
export type ODStatsManagerInitCallback = (database:ODJsonDatabaseStructure, deletables:ODJsonDatabaseStructure) => void|Promise<void>
/**## ODStatScopeSetMode `type`
* This type contains all valid methods for changing the value of a stat.
*/
export type ODStatScopeSetMode = "set"|"increase"|"decrease"
/**## ODStatsManager `class`
* This is an Open Ticket stats manager.
*
* This class is responsible for managing all stats of the bot.
* Stats are categorized in "scopes" which can be accessed in this manager.
*
* Stats can be accessed in the individual scopes.
*/
export class ODStatsManager extends ODManager<ODStatScope> {
/**Alias to Open Ticket debugger. */
#debug: ODDebugger
/**Alias to Open Ticket stats database. */
database: ODDatabase|null = null
/**All the listeners for the init event. */
#initListeners: ODStatsManagerInitCallback[] = []
constructor(debug:ODDebugger){
super(debug,"stat scope")
this.#debug = debug
}
/**Select the database to use to read/write all stats from/to. */
useDatabase(database:ODDatabase){
this.database = database
}
add(data:ODStatScope, overwrite?:boolean): boolean {
data.useDebug(this.#debug,"stat")
if (this.database) data.useDatabase(this.database)
return super.add(data,overwrite)
}
/**Init all stats and run `onInit()` listeners. */
async init(){
if (!this.database) throw new ODSystemError("Unable to initialize stats scopes due to missing database!")
//get all valid categories
const validCategories: string[] = []
for (const scope of this.getAll()){
validCategories.push(...scope.init())
}
//filter out the deletable stats
const deletableStats: ODJsonDatabaseStructure = []
const data = await this.database.getAll()
data.forEach((data) => {
if (!validCategories.includes(data.category)) deletableStats.push(data)
})
//do additional deletion
for (const cb of this.#initListeners){
await cb(data,deletableStats)
}
//delete all deletable stats
for (const data of deletableStats){
if (!this.database) return
await this.database.delete(data.category,data.key)
}
}
/**Reset all stats. (clears the entire database) */
async reset(){
if (!this.database) return
const data = await this.database.getAll()
for (const d of data){
if (!this.database) return
await this.database.delete(d.category,d.key)
}
}
/**Run a function when the stats are initialized. This can be used to clear stats from users that left the server or tickets which don't exist anymore. */
onInit(callback:ODStatsManagerInitCallback){
this.#initListeners.push(callback)
}
}
/**## ODStatScope `class`
* This is an Open Ticket stat scope.
*
* A scope can contain multiple stats. Every scope is seperated from other scopes.
* Here, you can read & write the values of all stats.
*
* The built-in Open Ticket scopes are: `global`, `user`, `ticket`
*/
export class ODStatScope extends ODManager<ODStat> {
/**The id of this statistics scope. */
id: ODId
/**Is this stat scope already initialized? */
ready: boolean = false
/**Alias to Open Ticket stats database. */
database: ODDatabase|null = null
/**The name of this scope (used in embed title) */
name:string
constructor(id:ODValidId, name:string){
super()
this.id = new ODId(id)
this.name = name
}
/**Select the database to use to read/write all stats from/to. (Automatically assigned when used in `ODStatsManager`) */
useDatabase(database:ODDatabase){
this.database = database
}
/**Get the value of a statistic. The `scopeId` is the unique id of the user, channel, role, etc that the stats are related to. */
async getStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null> {
if (!this.database) return null
const newId = new ODId(id)
const data = await this.database.get(this.id.value+"_"+newId.value,scopeId)
if (typeof data == "undefined"){
//set stats to default value & return
return this.resetStat(id,scopeId)
}else if (typeof data == "string" || typeof data == "boolean" || typeof data == "number"){
//return value received from database
return data
}
//return null on error
return null
}
/**Get the value of a statistic for all `scopeId`'s. The `scopeId` is the unique id of the user, channel, role, etc that the stats are related to. */
async getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]> {
if (!this.database) return []
const newId = new ODId(id)
const data = await this.database.getCategory(this.id.value+"_"+newId.value) ?? []
const output: {id:string,value:ODValidStatValue}[] = []
for (const stat of data){
if (typeof stat.value == "string" || typeof stat.value == "boolean" || typeof stat.value == "number"){
//return value received from database
output.push({id:stat.key,value:stat.value})
}
}
//return null on error
return output
}
/**Set, increase or decrease the value of a statistic. The `scopeId` is the unique id of the user, channel, role, etc that the stats are related to. */
async setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean> {
if (!this.database) return false
const stat = this.get(id)
if (!stat) return false
if (mode == "set" || typeof value != "number"){
await this.database.set(this.id.value+"_"+stat.id.value,scopeId,value)
}else if (mode == "increase"){
const currentValue = await this.getStat(id,scopeId)
if (typeof currentValue != "number") await this.database.set(this.id.value+"_"+stat.id.value,scopeId,0+value)
else await this.database.set(this.id.value+"_"+stat.id.value,scopeId,currentValue+value)
}else if (mode == "decrease"){
const currentValue = await this.getStat(id,scopeId)
if (typeof currentValue != "number") await this.database.set(this.id.value+"_"+stat.id.value,scopeId,0-value)
else await this.database.set(this.id.value+"_"+stat.id.value,scopeId,currentValue-value)
}
return true
}
/**Reset the value of a statistic to the initial value. The `scopeId` is the unique id of the user, channel, role, etc that the stats are related to. */
async resetStat(id:ODValidId, scopeId:string): Promise<ODValidStatValue|null> {
if (!this.database) return null
const stat = this.get(id)
if (!stat) return null
if (stat.value != null) await this.database.set(this.id.value+"_"+stat.id.value,scopeId,stat.value)
return stat.value
}
/**Initialize this stat scope & return a list of all statistic ids in the following format: `<scopeid>_<statid>` */
init(): string[] {
//get all valid stats categories
this.ready = true
return this.getAll().map((stat) => this.id.value+"_"+stat.id.value)
}
/**Render all stats in this scope for usage in a discord message/embed. */
async render(scopeId:string, guild:discord.Guild, channel:discord.TextBasedChannel, user:discord.User): Promise<string> {
//sort from high priority to low
const derefArray = [...this.getAll()]
derefArray.sort((a,b) => {
return b.priority-a.priority
})
const result: string[] = []
for (const stat of derefArray){
try {
if (stat instanceof ODDynamicStat){
//dynamic render (without value)
result.push(await stat.render("",scopeId,guild,channel,user))
}else{
//normal render (with value)
const value = await this.getStat(stat.id,scopeId)
if (value != null) result.push(await stat.render(value,scopeId,guild,channel,user))
}
}catch(err){
process.emit("uncaughtException",err)
}
}
return result.filter((stat) => stat !== "").join("\n")
}
}
/**## ODStatGlobalScope `class`
* This is an Open Ticket stat global scope.
*
* A scope can contain multiple stats. Every scope is seperated from other scopes.
* Here, you can read & write the values of all stats.
*
* This scope is made specifically for the global stats of Open Ticket.
*/
export class ODStatGlobalScope extends ODStatScope {
getStat(id:ODValidId): Promise<ODValidStatValue|null> {
return super.getStat(id,"GLOBAL")
}
getAllStats(id:ODValidId): Promise<{id:string,value:ODValidStatValue}[]> {
return super.getAllStats(id)
}
setStat(id:ODValidId, value:ODValidStatValue, mode:ODStatScopeSetMode): Promise<boolean> {
return super.setStat(id,"GLOBAL",value,mode)
}
resetStat(id:ODValidId): Promise<ODValidStatValue|null> {
return super.resetStat(id,"GLOBAL")
}
render(scopeId:"GLOBAL", guild:discord.Guild, channel:discord.TextBasedChannel, user: discord.User): Promise<string> {
return super.render("GLOBAL",guild,channel,user)
}
}
/**## ODStatRenderer `type`
* This callback will render a single statistic for a discord embed/message.
*/
export type ODStatRenderer = (value:ODValidStatValue, scopeId:string, guild:discord.Guild, channel:discord.TextBasedChannel, user:discord.User) => string|Promise<string>
/**## ODStat `class`
* This is an Open Ticket statistic.
*
* This single statistic doesn't do anything except defining the rules of this statistic.
* Use it in a stats scope to register a new statistic. A statistic can also include a priority to choose the render priority.
*
* It's recommended to use the `ODBasicStat` & `ODDynamicStat` classes instead of this one!
*/
export class ODStat extends ODManagerData {
/**The priority of this statistic. */
priority: number
/**The render function of this statistic. */
render: ODStatRenderer
/**The value of this statistic. */
value: ODValidStatValue|null
constructor(id:ODValidId, priority:number, render:ODStatRenderer, value?:ODValidStatValue){
super(id)
this.priority = priority
this.render = render
this.value = value ?? null
}
}
/**## ODBasicStat `class`
* This is an Open Ticket basic statistic.
*
* This single statistic will store a number, boolean or string in the database.
* Use it to create a simple statistic for any stats scope.
*/
export class ODBasicStat extends ODStat {
/**The name of this stat. Rendered in discord embeds/messages. */
name: string
constructor(id:ODValidId, priority:number, name:string, value:ODValidStatValue){
super(id,priority,(value) => {
return ""+name+": `"+value.toString()+"`"
},value)
this.name = name
}
}
/**## ODDynamicStatRenderer `type`
* This callback will render a single dynamic statistic for a discord embed/message.
*/
export type ODDynamicStatRenderer = (scopeId:string, guild:discord.Guild, channel:discord.TextBasedChannel, user:discord.User) => string|Promise<string>
/**## ODDynamicStat `class`
* This is an Open Ticket dynamic statistic.
*
* A dynamic statistic does not store anything in the database! Instead, it will execute a function to return a custom result.
* This can be used to show statistics which are not stored in the database.
*
* This is used in Open Ticket for the live ticket status, participants & system status.
*/
export class ODDynamicStat extends ODStat {
constructor(id:ODValidId, priority:number, render:ODDynamicStatRenderer){
super(id,priority,(value,scopeId,guild,channel,user) => {
return render(scopeId,guild,channel,user)
})
}
}
-61
View File
@@ -1,61 +0,0 @@
///////////////////////////////////////
//VERIFYBAR MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODValidId } from "./base"
import { ODMessage } from "./builder"
import { ODDebugger } from "./console"
import { ODButtonResponderInstance } from "./responder"
import * as discord from "discord.js"
import { ODWorkerManager } from "./worker"
/**## ODVerifyBar `class`
* This is an Open Ticket verifybar.
*
* It is contains 2 sets of workers and a lot of utilities for the (✅ ❌) verifybars in the bot.
*
* It doesn't contain the code which activates or spawns the verifybars!
*/
export class ODVerifyBar extends ODManagerData {
/**All workers that will run when the verifybar is accepted. */
success: ODWorkerManager<ODButtonResponderInstance,"verifybar",{data:string|null,verifybarMessage:discord.Message<boolean>|null}>
/**All workers that will run when the verifybar is stopped. */
failure: ODWorkerManager<ODButtonResponderInstance,"verifybar",{data:string|null,verifybarMessage:discord.Message<boolean>|null}>
/**The message that will be built wen activating this verifybar. */
message: ODMessage<"verifybar",{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>}>
/**When disabled, it will skip the verifybar and instantly fire the `success` workers. */
enabled: boolean
constructor(id:ODValidId, message:ODMessage<"verifybar",{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,originalMessage:discord.Message<boolean>}>, enabled?:boolean){
super(id)
this.success = new ODWorkerManager("descending")
this.failure = new ODWorkerManager("descending")
this.message = message
this.enabled = enabled ?? true
}
/**Build the message and reply to a button with this verifybar. */
async activate(responder:ODButtonResponderInstance){
if (this.enabled){
//show verifybar
const {guild,channel,user,message} = responder
await responder.update(await this.message.build("verifybar",{guild,channel,user,verifybar:this,originalMessage:message}))
}else{
//instant success
if (this.success) await this.success.executeWorkers(responder,"verifybar",{data:null,verifybarMessage:null})
}
}
}
/**## ODVerifyBarManager `class`
* This is an Open Ticket verifybar manager.
*
* It contains all (✅ ❌) verifybars in the bot.
* The `ODVerifyBar` classes contain `ODWorkerManager`'s that will be fired when the continue/stop buttons are pressed.
*
* It doesn't contain the code which activates the verifybars! This should be implemented by your own.
*/
export class ODVerifyBarManager extends ODManager<ODVerifyBar> {
constructor(debug:ODDebugger){
super(debug,"verifybar")
}
}
-93
View File
@@ -1,93 +0,0 @@
///////////////////////////////////////
//WORKER MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODValidId } from "./base"
/**## ODWorkerCallback `type`
* This is the callback used in `ODWorker`!
*/
export type ODWorkerCallback<Instance, Source extends string, Params> = (instance:Instance, params:Params, source:Source, cancel:() => void) => void|Promise<void>
/**## ODWorker `class`
* This is an Open Ticket worker.
*
* You can compare it with a normal javascript callback, but slightly more advanced!
*
* - It has an `id` for identification of the function
* - A `priority` to know when to execute this callback (related to others)
* - It knows who called this callback (`source`)
* - And much more!
*/
export class ODWorker<Instance, Source extends string, Params> extends ODManagerData {
/**The priority of this worker */
priority: number
/**The main callback of this worker */
callback: ODWorkerCallback<Instance,Source,Params>
constructor(id:ODValidId, priority:number, callback:ODWorkerCallback<Instance,Source,Params>){
super(id)
this.priority = priority
this.callback = callback
}
}
/**## ODWorker `class`
* This is an Open Ticket worker manager.
*
* It manages & executes `ODWorker`'s in the correct order.
*
* You can register a custom worker in this class to create a message or button.
*/
export class ODWorkerManager<Instance, Source extends string, Params> extends ODManager<ODWorker<Instance,Source,Params>> {
/**The order of execution for workers inside this manager. */
#priorityOrder: "ascending"|"descending"
/**The backup worker will be executed when one of the workers fails or cancels execution. */
backupWorker: ODWorker<{reason:"error"|"cancel"},Source,Params>|null = null
constructor(priorityOrder:"ascending"|"descending"){
super()
this.#priorityOrder = priorityOrder
}
/**Get all workers in sorted order. */
getSortedWorkers(priority:"ascending"|"descending"){
const derefArray = [...this.getAll()]
return derefArray.sort((a,b) => {
if (priority == "ascending") return a.priority-b.priority
else return b.priority-a.priority
})
}
/**Execute all workers on an instance using the given source & parameters. */
async executeWorkers(instance:Instance, source:Source, params:Params){
const derefParams = {...params}
const workers = this.getSortedWorkers(this.#priorityOrder)
let didCancel = false
let didCrash = false
for (const worker of workers){
if (didCancel) break
try {
await worker.callback(instance,derefParams,source,() => {
didCancel = true
})
}catch(err){
process.emit("uncaughtException",err)
didCrash = true
}
}
if (didCancel && this.backupWorker){
try{
await this.backupWorker.callback({reason:"cancel"},derefParams,source,() => {})
}catch(err){
process.emit("uncaughtException",err)
}
}else if (didCrash && this.backupWorker){
try{
await this.backupWorker.callback({reason:"error"},derefParams,source,() => {})
}catch(err){
process.emit("uncaughtException",err)
}
}
}
}
@@ -1,13 +1,100 @@
///////////////////////////////////////
//OPENTICKET OPTION MODULE
///////////////////////////////////////
import { ODDatabase } from "../modules/database"
import { ODJsonConfig_DefaultOptionEmbedSettingsType, ODJsonConfig_DefaultOptionPingSettingsType } from "../defaults/config"
import { ODId, ODManager, ODValidJsonType, ODValidId, ODVersion, ODValidButtonColor, ODManagerData, ODSystemError } from "../modules/base"
import { ODDebugger } from "../modules/console"
import * as api from "@open-discord-bots/framework/api"
import * as discord from "discord.js"
import * as crypto from "crypto"
import { ODRoleUpdateMode } from "./role"
import { ODOptionsJsonConfig_TicketOptionEmbedSettings, ODOptionsJsonConfig_TicketOptionPingSettings } from "../mappings/config.js"
import { ODRoleUpdateMode } from "./role.js"
/**## ODOptionIdConstraint `type`
* The constraint/layout for id mappings/interfaces of the `ODOption` class.
*/
export type ODOptionIdConstraint = Record<string,ODOptionData<api.ODValidJsonType>>
/**## ODTicketOptionIdMappings `interface`
* A list of all available IDs in the default `ODTicketOption` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODTicketOptionIdMappings extends ODOptionIdConstraint {
"opendiscord:name":ODOptionData<string>,
"opendiscord:description":ODOptionData<string>,
"opendiscord:button-emoji":ODOptionData<string>,
"opendiscord:button-label":ODOptionData<string>,
"opendiscord:button-color":ODOptionData<api.ODValidButtonColor>,
"opendiscord:admins":ODOptionData<string[]>,
"opendiscord:admins-readonly":ODOptionData<string[]>,
"opendiscord:allow-blacklisted-users":ODOptionData<boolean>,
"opendiscord:questions":ODOptionData<string[]>,
"opendiscord:channel-prefix":ODOptionData<string>,
"opendiscord:channel-suffix":ODOptionData<"user-name"|"user-nickname"|"user-id"|"random-number"|"random-hex"|"counter-dynamic"|"counter-fixed">,
"opendiscord:channel-category":ODOptionData<string>,
"opendiscord:channel-topic":ODOptionData<string>,
"opendiscord:dm-message-enabled":ODOptionData<boolean>,
"opendiscord:dm-message-text":ODOptionData<string>,
"opendiscord:dm-message-embed":ODOptionData<ODOptionsJsonConfig_TicketOptionEmbedSettings>,
"opendiscord:ticket-message-enabled":ODOptionData<boolean>,
"opendiscord:ticket-message-text":ODOptionData<string>,
"opendiscord:ticket-message-embed":ODOptionData<ODOptionsJsonConfig_TicketOptionEmbedSettings>,
"opendiscord:ticket-message-ping":ODOptionData<ODOptionsJsonConfig_TicketOptionPingSettings>,
"opendiscord:autoclose-enable-hours":ODOptionData<boolean>,
"opendiscord:autoclose-enable-leave":ODOptionData<boolean>,
"opendiscord:autoclose-disable-claim":ODOptionData<boolean>,
"opendiscord:autoclose-hours":ODOptionData<number>,
"opendiscord:autodelete-enable-days":ODOptionData<boolean>,
"opendiscord:autodelete-enable-leave":ODOptionData<boolean>,
"opendiscord:autodelete-disable-claim":ODOptionData<boolean>,
"opendiscord:autodelete-days":ODOptionData<number>,
"opendiscord:cooldown-enabled":ODOptionData<boolean>,
"opendiscord:cooldown-minutes":ODOptionData<number>,
"opendiscord:limits-enabled":ODOptionData<boolean>,
"opendiscord:limits-maximum-global":ODOptionData<number>,
"opendiscord:limits-maximum-user":ODOptionData<number>
"opendiscord:slowmode-enabled":ODOptionData<boolean>,
"opendiscord:slowmode-seconds":ODOptionData<number>,
}
/**## ODWebsiteOptionIdMappings `interface`
* A list of all available IDs in the default `ODWebsiteOption` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODWebsiteOptionIdMappings extends ODOptionIdConstraint {
"opendiscord:name":ODOptionData<string>,
"opendiscord:description":ODOptionData<string>,
"opendiscord:button-emoji":ODOptionData<string>,
"opendiscord:button-label":ODOptionData<string>,
"opendiscord:url":ODOptionData<string>,
}
/**## ODRoleOptionIdMappings `interface`
* A list of all available IDs in the default `ODRoleOption` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODRoleOptionIdMappings extends ODOptionIdConstraint {
"opendiscord:name":ODOptionData<string>,
"opendiscord:description":ODOptionData<string>,
"opendiscord:button-emoji":ODOptionData<string>,
"opendiscord:button-label":ODOptionData<string>,
"opendiscord:button-color":ODOptionData<api.ODValidButtonColor>,
"opendiscord:roles":ODOptionData<string[]>,
"opendiscord:mode":ODOptionData<ODRoleUpdateMode>,
"opendiscord:remove-roles-on-add":ODOptionData<string[]>,
"opendiscord:add-on-join":ODOptionData<boolean>
}
/**## ODOptionManager `class`
* This is an Open Ticket option manager.
@@ -16,20 +103,17 @@ import { ODRoleUpdateMode } from "./role"
*
* All option types including: tickets, websites & reaction roles are stored here.
*/
export class ODOptionManager extends ODManager<ODOption> {
/**A reference to the Open Ticket debugger. */
#debug: ODDebugger
export class ODOptionManager extends api.ODManager<ODOption> {
/**The option suffix manager used to generate channel suffixes for ticket names. */
suffix: ODOptionSuffixManager
constructor(debug:ODDebugger){
constructor(debug:api.ODDebugger){
super(debug,"option")
this.#debug = debug
this.suffix = new ODOptionSuffixManager(debug)
}
add(data:ODOption, overwrite?:boolean): boolean {
data.useDebug(this.#debug,"option data")
data.useDebug(this.debug,"option data")
return super.add(data,overwrite)
}
}
@@ -41,7 +125,7 @@ export interface ODOptionDataJson {
/**The id of this property. */
id:string,
/**The value of this property. */
value:ODValidJsonType
value:api.ODValidJsonType
}
/**## ODOptionDataJson `interface`
@@ -65,15 +149,15 @@ export interface ODOptionJson {
*
* It's recommended to use `ODTicketOption`, `ODWebsiteOption` or `ODRoleOption` instead!
*/
export class ODOption extends ODManager<ODOptionData<ODValidJsonType>> {
export class ODOption extends api.ODManager<ODOptionData<api.ODValidJsonType>> {
/**The id of this option. (from the config) */
id:ODId
id:api.ODId
/**The type of this option. (e.g. `opendiscord:ticket`, `opendiscord:website`, `opendiscord:role`) */
type: string
constructor(id:ODValidId, type:string, data:ODOptionData<ODValidJsonType>[]){
constructor(id:api.ODValidId, type:string, data:ODOptionData<api.ODValidJsonType>[]){
super()
this.id = new ODId(id)
this.id = new api.ODId(id)
this.type = type
data.forEach((data) => {
this.add(data)
@@ -81,7 +165,7 @@ export class ODOption extends ODManager<ODOptionData<ODValidJsonType>> {
}
/**Convert this option to a JSON object for storing this option in the database. */
toJson(version:ODVersion): ODOptionJson {
toJson(version:api.ODVersion): ODOptionJson {
const data = this.getAll().map((data) => {
return {
id:data.id.toString(),
@@ -110,22 +194,22 @@ export class ODOption extends ODManager<ODOptionData<ODValidJsonType>> {
*
* When this property is edited, the database will be updated automatically.
*/
export class ODOptionData<DataType extends ODValidJsonType> extends ODManagerData {
export class ODOptionData<DataType extends api.ODValidJsonType> extends api.ODManagerData {
/**The value of this property. */
#value: DataType
private rawValue: DataType
constructor(id:ODValidId, value:DataType){
constructor(id:api.ODValidId, value:DataType){
super(id)
this.#value = value
this.rawValue = value
}
/**The value of this property. */
set value(value:DataType){
this.#value = value
this.rawValue = value
this._change()
}
get value(): DataType {
return this.#value
return this.rawValue
}
/**Refresh the database. Is only required to be used when updating `ODOptionData` with an object/array as value. */
refreshDatabase(){
@@ -133,61 +217,6 @@ export class ODOptionData<DataType extends ODValidJsonType> extends ODManagerDat
}
}
/**## ODTicketOptionIds `type`
* This interface is a list of ids available in the `ODTicketOption` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODTicketOptionIds {
"opendiscord:name":ODOptionData<string>,
"opendiscord:description":ODOptionData<string>,
"opendiscord:button-emoji":ODOptionData<string>,
"opendiscord:button-label":ODOptionData<string>,
"opendiscord:button-color":ODOptionData<ODValidButtonColor>,
"opendiscord:admins":ODOptionData<string[]>,
"opendiscord:admins-readonly":ODOptionData<string[]>,
"opendiscord:allow-blacklisted-users":ODOptionData<boolean>,
"opendiscord:questions":ODOptionData<string[]>,
"opendiscord:channel-prefix":ODOptionData<string>,
"opendiscord:channel-suffix":ODOptionData<"user-name"|"user-nickname"|"user-id"|"random-number"|"random-hex"|"counter-dynamic"|"counter-fixed">,
"opendiscord:channel-category":ODOptionData<string>,
"opendiscord:channel-category-closed":ODOptionData<string>,
"opendiscord:channel-category-backup":ODOptionData<string>,
"opendiscord:channel-categories-claimed":ODOptionData<{user:string,category:string}[]>,
"opendiscord:channel-topic":ODOptionData<string>,
"opendiscord:dm-message-enabled":ODOptionData<boolean>,
"opendiscord:dm-message-text":ODOptionData<string>,
"opendiscord:dm-message-embed":ODOptionData<ODJsonConfig_DefaultOptionEmbedSettingsType>,
"opendiscord:ticket-message-enabled":ODOptionData<boolean>,
"opendiscord:ticket-message-text":ODOptionData<string>,
"opendiscord:ticket-message-embed":ODOptionData<ODJsonConfig_DefaultOptionEmbedSettingsType>,
"opendiscord:ticket-message-ping":ODOptionData<ODJsonConfig_DefaultOptionPingSettingsType>,
"opendiscord:autoclose-enable-hours":ODOptionData<boolean>,
"opendiscord:autoclose-enable-leave":ODOptionData<boolean>,
"opendiscord:autoclose-disable-claim":ODOptionData<boolean>,
"opendiscord:autoclose-hours":ODOptionData<number>,
"opendiscord:autodelete-enable-days":ODOptionData<boolean>,
"opendiscord:autodelete-enable-leave":ODOptionData<boolean>,
"opendiscord:autodelete-disable-claim":ODOptionData<boolean>,
"opendiscord:autodelete-days":ODOptionData<number>,
"opendiscord:cooldown-enabled":ODOptionData<boolean>,
"opendiscord:cooldown-minutes":ODOptionData<number>,
"opendiscord:limits-enabled":ODOptionData<boolean>,
"opendiscord:limits-maximum-global":ODOptionData<number>,
"opendiscord:limits-maximum-user":ODOptionData<number>
"opendiscord:slowmode-enabled":ODOptionData<boolean>,
"opendiscord:slowmode-seconds":ODOptionData<number>,
}
/**## ODTicketOption `class`
* This is an Open Ticket ticket option.
*
@@ -198,28 +227,28 @@ export interface ODTicketOptionIds {
export class ODTicketOption extends ODOption {
type: "opendiscord:ticket" = "opendiscord:ticket"
constructor(id:ODValidId, data:ODOptionData<ODValidJsonType>[]){
constructor(id:api.ODValidId, data:ODOptionData<api.ODValidJsonType>[]){
super(id,"opendiscord:ticket",data)
}
get<OptionId extends keyof ODTicketOptionIds>(id:OptionId): ODTicketOptionIds[OptionId]
get(id:ODValidId): ODOptionData<ODValidJsonType>|null
get<OptionId extends keyof api.ODNoGeneric<ODTicketOptionIdMappings>>(id:OptionId): ODTicketOptionIdMappings[OptionId]
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
get(id:ODValidId): ODOptionData<ODValidJsonType>|null {
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
return super.get(id)
}
remove<OptionId extends keyof ODTicketOptionIds>(id:OptionId): ODTicketOptionIds[OptionId]
remove(id:ODValidId): ODOptionData<ODValidJsonType>|null
remove<OptionId extends keyof api.ODNoGeneric<ODTicketOptionIdMappings>>(id:OptionId): ODTicketOptionIdMappings[OptionId]
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
remove(id:ODValidId): ODOptionData<ODValidJsonType>|null {
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODTicketOptionIds): boolean
exists(id:ODValidId): boolean
exists(id:keyof api.ODNoGeneric<ODTicketOptionIdMappings>): boolean
exists(id:api.ODValidId): boolean
exists(id:ODValidId): boolean {
exists(id:api.ODValidId): boolean {
return super.exists(id)
}
@@ -228,20 +257,6 @@ export class ODTicketOption extends ODOption {
}
}
/**## ODWebsiteOptionIds `type`
* This interface is a list of ids available in the `ODWebsiteOption` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODWebsiteOptionIds {
"opendiscord:name":ODOptionData<string>,
"opendiscord:description":ODOptionData<string>,
"opendiscord:button-emoji":ODOptionData<string>,
"opendiscord:button-label":ODOptionData<string>,
"opendiscord:url":ODOptionData<string>,
}
/**## ODWebsiteOption `class`
* This is an Open Ticket website option.
*
@@ -252,28 +267,28 @@ export interface ODWebsiteOptionIds {
export class ODWebsiteOption extends ODOption {
type: "opendiscord:website" = "opendiscord:website"
constructor(id:ODValidId, data:ODOptionData<ODValidJsonType>[]){
constructor(id:api.ODValidId, data:ODOptionData<api.ODValidJsonType>[]){
super(id,"opendiscord:website",data)
}
get<OptionId extends keyof ODWebsiteOptionIds>(id:OptionId): ODWebsiteOptionIds[OptionId]
get(id:ODValidId): ODOptionData<ODValidJsonType>|null
get<OptionId extends keyof api.ODNoGeneric<ODWebsiteOptionIdMappings>>(id:OptionId): ODWebsiteOptionIdMappings[OptionId]
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
get(id:ODValidId): ODOptionData<ODValidJsonType>|null {
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
return super.get(id)
}
remove<OptionId extends keyof ODWebsiteOptionIds>(id:OptionId): ODWebsiteOptionIds[OptionId]
remove(id:ODValidId): ODOptionData<ODValidJsonType>|null
remove<OptionId extends keyof api.ODNoGeneric<ODWebsiteOptionIdMappings>>(id:OptionId): ODWebsiteOptionIdMappings[OptionId]
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
remove(id:ODValidId): ODOptionData<ODValidJsonType>|null {
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODWebsiteOptionIds): boolean
exists(id:ODValidId): boolean
exists(id:keyof api.ODNoGeneric<ODWebsiteOptionIdMappings>): boolean
exists(id:api.ODValidId): boolean
exists(id:ODValidId): boolean {
exists(id:api.ODValidId): boolean {
return super.exists(id)
}
@@ -282,24 +297,6 @@ export class ODWebsiteOption extends ODOption {
}
}
/**## ODRoleOptionIds `type`
* This interface is a list of ids available in the `ODRoleOption` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODRoleOptionIds {
"opendiscord:name":ODOptionData<string>,
"opendiscord:description":ODOptionData<string>,
"opendiscord:button-emoji":ODOptionData<string>,
"opendiscord:button-label":ODOptionData<string>,
"opendiscord:button-color":ODOptionData<ODValidButtonColor>,
"opendiscord:roles":ODOptionData<string[]>,
"opendiscord:mode":ODOptionData<ODRoleUpdateMode>,
"opendiscord:remove-roles-on-add":ODOptionData<string[]>,
"opendiscord:add-on-join":ODOptionData<boolean>
}
/**## ODRoleOption `class`
* This is an Open Ticket role option.
*
@@ -310,28 +307,28 @@ export interface ODRoleOptionIds {
export class ODRoleOption extends ODOption {
type: "opendiscord:role" = "opendiscord:role"
constructor(id:ODValidId, data:ODOptionData<ODValidJsonType>[]){
constructor(id:api.ODValidId, data:ODOptionData<api.ODValidJsonType>[]){
super(id,"opendiscord:role",data)
}
get<OptionId extends keyof ODRoleOptionIds>(id:OptionId): ODRoleOptionIds[OptionId]
get(id:ODValidId): ODOptionData<ODValidJsonType>|null
get<OptionId extends keyof api.ODNoGeneric<ODRoleOptionIdMappings>>(id:OptionId): ODRoleOptionIdMappings[OptionId]
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
get(id:ODValidId): ODOptionData<ODValidJsonType>|null {
get(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
return super.get(id)
}
remove<OptionId extends keyof ODRoleOptionIds>(id:OptionId): ODRoleOptionIds[OptionId]
remove(id:ODValidId): ODOptionData<ODValidJsonType>|null
remove<OptionId extends keyof api.ODNoGeneric<ODRoleOptionIdMappings>>(id:OptionId): ODRoleOptionIdMappings[OptionId]
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null
remove(id:ODValidId): ODOptionData<ODValidJsonType>|null {
remove(id:api.ODValidId): ODOptionData<api.ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODRoleOptionIds): boolean
exists(id:ODValidId): boolean
exists(id:keyof api.ODNoGeneric<ODRoleOptionIdMappings>): boolean
exists(id:api.ODValidId): boolean
exists(id:ODValidId): boolean {
exists(id:api.ODValidId): boolean {
return super.exists(id)
}
@@ -347,8 +344,8 @@ export class ODRoleOption extends ODOption {
*
* All ticket options should have a corresponding option suffix class.
*/
export class ODOptionSuffixManager extends ODManager<ODOptionSuffix> {
constructor(debug:ODDebugger){
export class ODOptionSuffixManager extends api.ODManager<ODOptionSuffix> {
constructor(debug:api.ODDebugger){
super(debug,"ticket suffix")
}
@@ -357,7 +354,7 @@ export class ODOptionSuffixManager extends ODManager<ODOptionSuffix> {
const suffix = this.getAll().find((suffix) => suffix.option.id.value == option.id.value)
if (!suffix) return null
try{
const member = await this.#getMember(guild,user)
const member = await this.getMember(guild,user)
if (!member) return null
return await suffix.getSuffix(member)
}catch(err){
@@ -365,7 +362,7 @@ export class ODOptionSuffixManager extends ODManager<ODOptionSuffix> {
return null
}
}
async #getMember(guild:discord.Guild,user:discord.User){
private async getMember(guild:discord.Guild,user:discord.User){
try{
return await guild.members.fetch(user.id)
}catch{
@@ -381,19 +378,17 @@ export class ODOptionSuffixManager extends ODManager<ODOptionSuffix> {
*
* Use `getSuffix()` to get the new suffix!
*/
export class ODOptionSuffix extends ODManagerData {
export abstract class ODOptionSuffix extends api.ODManagerData {
/**The option of this suffix. */
option: ODTicketOption
constructor(id:ODValidId, option:ODTicketOption){
constructor(id:api.ODValidId, option:ODTicketOption){
super(id)
this.option = option
}
/**Get the suffix for a new ticket. */
async getSuffix(member:discord.GuildMember): Promise<string> {
throw new ODSystemError("Tried to use an unimplemented ODOptionSuffix!")
}
abstract getSuffix(member:discord.GuildMember): Promise<string>
}
/**## ODOptionUserNameSuffix `class`
@@ -444,16 +439,16 @@ export class ODOptionUserIdSuffix extends ODOptionSuffix {
*/
export class ODOptionCounterDynamicSuffix extends ODOptionSuffix {
/**The database where the value of this counter is stored. */
database: ODDatabase
database: api.ODDatabase
constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){
constructor(id:api.ODValidId, option:ODTicketOption, database:api.ODDatabase){
super(id,option)
this.database = database
this.#init()
this.init()
}
/**Initialize the database for this suffix. */
async #init(){
private async init(){
if (!await this.database.exists("opendiscord:option-suffix-counter",this.option.id.value)) await this.database.set("opendiscord:option-suffix-counter",this.option.id.value,0)
}
async getSuffix(member:discord.GuildMember): Promise<string> {
@@ -474,16 +469,16 @@ export class ODOptionCounterDynamicSuffix extends ODOptionSuffix {
*/
export class ODOptionCounterFixedSuffix extends ODOptionSuffix {
/**The database where the value of this counter is stored. */
database: ODDatabase
database: api.ODDatabase
constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){
constructor(id:api.ODValidId, option:ODTicketOption, database:api.ODDatabase){
super(id,option)
this.database = database
this.#init()
this.init()
}
/**Initialize the database for this suffix. */
async #init(){
private async init(){
if (!await this.database.exists("opendiscord:option-suffix-counter",this.option.id.value)) await this.database.set("opendiscord:option-suffix-counter",this.option.id.value,0)
}
async getSuffix(member:discord.GuildMember): Promise<string> {
@@ -508,33 +503,33 @@ export class ODOptionCounterFixedSuffix extends ODOptionSuffix {
*/
export class ODOptionRandomNumberSuffix extends ODOptionSuffix {
/**The database where previous random numbers are stored. */
database: ODDatabase
database: api.ODDatabase
constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){
constructor(id:api.ODValidId, option:ODTicketOption, database:api.ODDatabase){
super(id,option)
this.database = database
this.#init()
this.init()
}
/**Initialize the database for this suffix. */
async #init(){
private async init(){
if (!await this.database.exists("opendiscord:option-suffix-history",this.option.id.value)) await this.database.set("opendiscord:option-suffix-history",this.option.id.value,[])
}
/**Get a unique number for this suffix. */
#generateUniqueValue(history:string[]): string {
protected generateUniqueValue(history:string[]): string {
const rawNumber = Math.round(Math.random()*1000).toString()
let number = rawNumber
if (rawNumber.length == 1) number = "000"+rawNumber
else if (rawNumber.length == 2) number = "00"+rawNumber
else if (rawNumber.length == 3) number = "0"+rawNumber
if (history.includes(number)) return this.#generateUniqueValue(history)
if (history.includes(number)) return this.generateUniqueValue(history)
else return number
}
async getSuffix(member:discord.GuildMember): Promise<string> {
const rawCurrentValues = await this.database.get("opendiscord:option-suffix-history",this.option.id.value)
const currentValues = ((Array.isArray(rawCurrentValues)) ? rawCurrentValues : []) as string[]
const newValue = this.#generateUniqueValue(currentValues)
const newValue = this.generateUniqueValue(currentValues)
currentValues.push(newValue)
if (currentValues.length > 50) currentValues.shift()
await this.database.set("opendiscord:option-suffix-history",this.option.id.value,currentValues)
@@ -551,28 +546,28 @@ export class ODOptionRandomNumberSuffix extends ODOptionSuffix {
*/
export class ODOptionRandomHexSuffix extends ODOptionSuffix {
/**The database where previous random hexes are stored. */
database: ODDatabase
database: api.ODDatabase
constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){
constructor(id:api.ODValidId, option:ODTicketOption, database:api.ODDatabase){
super(id,option)
this.database = database
this.#init()
this.init()
}
/**Initialize the database for this suffix. */
async #init(){
private async init(){
if (!await this.database.exists("opendiscord:option-suffix-history",this.option.id.value)) await this.database.set("opendiscord:option-suffix-history",this.option.id.value,[])
}
/**Get a unique hex-string for this suffix. */
#generateUniqueValue(history:string[]): string {
protected generateUniqueValue(history:string[]): string {
const hex = crypto.randomBytes(2).toString("hex")
if (history.includes(hex)) return this.#generateUniqueValue(history)
if (history.includes(hex)) return this.generateUniqueValue(history)
else return hex
}
async getSuffix(member:discord.GuildMember): Promise<string> {
const rawCurrentValues = await this.database.get("opendiscord:option-suffix-history",this.option.id.value)
const currentValues = ((Array.isArray(rawCurrentValues)) ? rawCurrentValues : []) as string[]
const newValue = this.#generateUniqueValue(currentValues)
const newValue = this.generateUniqueValue(currentValues)
currentValues.push(newValue)
if (currentValues.length > 50) currentValues.shift()
await this.database.set("opendiscord:option-suffix-history",this.option.id.value,currentValues)
@@ -1,9 +1,38 @@
///////////////////////////////////////
//OPENTICKET PANEL MODULE
///////////////////////////////////////
import { ODJsonConfig_DefaultPanelEmbedSettingsType } from "../defaults/config"
import { ODId, ODManager, ODValidJsonType, ODValidId, ODVersion, ODValidButtonColor, ODManagerData } from "../modules/base"
import { ODDebugger } from "../modules/console"
import * as api from "@open-discord-bots/framework/api"
import { ODPanelsJsonConfig_PanelEmbedSettings } from "../mappings/config.js"
/**## ODPanelIdConstraint `type`
* The constraint/layout for id mappings/interfaces of the `ODPanel` class.
*/
export type ODPanelIdConstraint = Record<string,ODPanelData<api.ODValidJsonType>>
/**## ODPanelIdMappings `interface`
* A list of all available IDs in the default `ODPanel` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODPanelIdMappings extends ODPanelIdConstraint {
"opendiscord:name":ODPanelData<string>,
"opendiscord:options":ODPanelData<string[]>,
"opendiscord:dropdown":ODPanelData<boolean>,
"opendiscord:text":ODPanelData<string>,
"opendiscord:embed":ODPanelData<ODPanelsJsonConfig_PanelEmbedSettings>,
"opendiscord:dropdown-placeholder":ODPanelData<string>,
"opendiscord:enable-max-tickets-warning-text":ODPanelData<boolean>,
"opendiscord:enable-max-tickets-warning-embed":ODPanelData<boolean>,
"opendiscord:describe-options-layout":ODPanelData<"simple"|"normal"|"detailed">,
"opendiscord:describe-options-custom-title":ODPanelData<string>,
"opendiscord:describe-options-in-text":ODPanelData<boolean>,
"opendiscord:describe-options-in-embed-fields":ODPanelData<boolean>,
"opendiscord:describe-options-in-embed-description":ODPanelData<boolean>
}
/**## ODPanelManager `class`
* This is an Open Ticket panel manager.
@@ -12,17 +41,13 @@ import { ODDebugger } from "../modules/console"
*
* Panels are not stored in the database and will be parsed from the config every startup.
*/
export class ODPanelManager extends ODManager<ODPanel> {
/**A reference to the Open Ticket debugger. */
#debug: ODDebugger
constructor(debug:ODDebugger){
export class ODPanelManager extends api.ODManager<ODPanel> {
constructor(debug:api.ODDebugger){
super(debug,"option")
this.#debug = debug
}
add(data:ODPanel, overwrite?:boolean): boolean {
data.useDebug(this.#debug,"option data")
data.useDebug(this.debug,"option data")
return super.add(data,overwrite)
}
}
@@ -34,7 +59,7 @@ export interface ODPanelDataJson {
/**The id of this property. */
id:string,
/**The value of this property. */
value:ODValidJsonType
value:api.ODValidJsonType
}
/**## ODPanelDataJson `interface`
@@ -49,49 +74,25 @@ export interface ODPanelJson {
data:ODPanelDataJson[]
}
/**## ODPanelIds `type`
* This interface is a list of ids available in the `ODPanel` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODPanelIds {
"opendiscord:name":ODPanelData<string>,
"opendiscord:options":ODPanelData<string[]>,
"opendiscord:dropdown":ODPanelData<boolean>,
"opendiscord:text":ODPanelData<string>,
"opendiscord:embed":ODPanelData<ODJsonConfig_DefaultPanelEmbedSettingsType>,
"opendiscord:dropdown-placeholder":ODPanelData<string>,
"opendiscord:enable-max-tickets-warning-text":ODPanelData<boolean>,
"opendiscord:enable-max-tickets-warning-embed":ODPanelData<boolean>,
"opendiscord:describe-options-layout":ODPanelData<"simple"|"normal"|"detailed">,
"opendiscord:describe-options-custom-title":ODPanelData<string>,
"opendiscord:describe-options-in-text":ODPanelData<boolean>,
"opendiscord:describe-options-in-embed-fields":ODPanelData<boolean>,
"opendiscord:describe-options-in-embed-description":ODPanelData<boolean>
}
/**## ODPanel `class`
* This is an Open Ticket panel.
*
* This class contains all data related to this panel (parsed from the config).
*/
export class ODPanel extends ODManager<ODPanelData<ODValidJsonType>> {
export class ODPanel extends api.ODManager<ODPanelData<api.ODValidJsonType>> {
/**The id of this panel. (from the config) */
id:ODId
id:api.ODId
constructor(id:ODValidId, data:ODPanelData<ODValidJsonType>[]){
constructor(id:api.ODValidId, data:ODPanelData<api.ODValidJsonType>[]){
super()
this.id = new ODId(id)
this.id = new api.ODId(id)
data.forEach((data) => {
this.add(data)
})
}
/**Convert this panel to a JSON object for storing this panel in the database. */
toJson(version:ODVersion): ODPanelJson {
toJson(version:api.ODVersion): ODPanelJson {
const data = this.getAll().map((data) => {
return {
id:data.id.toString(),
@@ -111,24 +112,24 @@ export class ODPanel extends ODManager<ODPanelData<ODValidJsonType>> {
return new ODPanel(json.id,json.data.map((data) => new ODPanelData(data.id,data.value)))
}
get<PanelId extends keyof ODPanelIds>(id:PanelId): ODPanelIds[PanelId]
get(id:ODValidId): ODPanelData<ODValidJsonType>|null
get<PanelId extends keyof api.ODNoGeneric<ODPanelIdMappings>>(id:PanelId): ODPanelIdMappings[PanelId]
get(id:api.ODValidId): ODPanelData<api.ODValidJsonType>|null
get(id:ODValidId): ODPanelData<ODValidJsonType>|null {
get(id:api.ODValidId): ODPanelData<api.ODValidJsonType>|null {
return super.get(id)
}
remove<PanelId extends keyof ODPanelIds>(id:PanelId): ODPanelIds[PanelId]
remove(id:ODValidId): ODPanelData<ODValidJsonType>|null
remove<PanelId extends keyof api.ODNoGeneric<ODPanelIdMappings>>(id:PanelId): ODPanelIdMappings[PanelId]
remove(id:api.ODValidId): ODPanelData<api.ODValidJsonType>|null
remove(id:ODValidId): ODPanelData<ODValidJsonType>|null {
remove(id:api.ODValidId): ODPanelData<api.ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODPanelIds): boolean
exists(id:ODValidId): boolean
exists(id:keyof api.ODNoGeneric<ODPanelIdMappings>): boolean
exists(id:api.ODValidId): boolean
exists(id:ODValidId): boolean {
exists(id:api.ODValidId): boolean {
return super.exists(id)
}
}
@@ -140,22 +141,22 @@ export class ODPanel extends ODManager<ODPanelData<ODValidJsonType>> {
*
* When this property is edited, the database will be updated automatically.
*/
export class ODPanelData<DataType extends ODValidJsonType> extends ODManagerData {
export class ODPanelData<DataType extends api.ODValidJsonType> extends api.ODManagerData {
/**The value of this property. */
#value: DataType
private rawValue: DataType
constructor(id:ODValidId, value:DataType){
constructor(id:api.ODValidId, value:DataType){
super(id)
this.#value = value
this.rawValue = value
}
/**The value of this property. */
set value(value:DataType){
this.#value = value
this.rawValue = value
this._change()
}
get value(): DataType {
return this.#value
return this.rawValue
}
/**Refresh the database. Is only required to be used when updating `ODPanelData` with an object/array as value. */
refreshDatabase(){
@@ -1,9 +1,26 @@
///////////////////////////////////////
//OPENTICKET PRIORITY MODULE
///////////////////////////////////////
import { ODId, ODManager, ODValidJsonType, ODValidId, ODVersion, ODManagerData } from "../modules/base"
import { ODDebugger } from "../modules/console"
import * as discord from "discord.js"
import * as api from "@open-discord-bots/framework/api"
/**## ODPriorityManagerIdConstraint `type`
* The constraint/layout for id mappings/interfaces of the `ODPriorityManager` class.
*/
export type ODPriorityManagerIdConstraint = Record<string,ODPriorityLevel>
/**## ODPriorityManagerIdMappings `interface`
* A list of all available IDs in the default `ODPriorityManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODPriorityManagerIdMappings extends ODPriorityManagerIdConstraint {
"opendiscord:urgent":ODPriorityLevel,
"opendiscord:very-high":ODPriorityLevel,
"opendiscord:high":ODPriorityLevel,
"opendiscord:normal":ODPriorityLevel,
"opendiscord:low":ODPriorityLevel,
"opendiscord:very-low":ODPriorityLevel,
"opendiscord:none":ODPriorityLevel,
}
/**## ODPriorityManager `class`
* This is an Open Ticket priority manager.
@@ -12,13 +29,9 @@ import * as discord from "discord.js"
*
* Priorities levels can be changed/updated/translated by plugins to allow for more customisability.
*/
export class ODPriorityManager extends ODManager<ODPriorityLevel> {
/**A reference to the Open Ticket debugger. */
#debug: ODDebugger
constructor(debug:ODDebugger){
export class ODPriorityManager<IdList extends ODPriorityManagerIdConstraint = ODPriorityManagerIdConstraint> extends api.ODManager<ODPriorityLevel> {
constructor(debug:api.ODDebugger){
super(debug,"priority")
this.#debug = debug
}
/**Get an `ODPriorityLevel` from the priority level value. Returns a dummy value when the level doesn't exist. */
@@ -29,51 +42,34 @@ export class ODPriorityManager extends ODManager<ODPriorityLevel> {
listAvailableLevels(){
return this.getAll().map((lvl) => lvl.priority)
}
}
/**## ODPriorityManagerIds `type`
* This interface is a list of ids available in the `ODPriorityManager` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODPriorityManagerIds {
"opendiscord:urgent":ODPriorityLevel,
"opendiscord:very-high":ODPriorityLevel,
"opendiscord:high":ODPriorityLevel,
"opendiscord:normal":ODPriorityLevel,
"opendiscord:low":ODPriorityLevel,
"opendiscord:very-low":ODPriorityLevel,
"opendiscord:none":ODPriorityLevel,
}
/**## ODPriorityManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODPriorityManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.priorities`!
*/
export class ODPriorityManager_Default extends ODPriorityManager {
get<PriorityId extends keyof ODPriorityManagerIds>(id:PriorityId): ODPriorityManagerIds[PriorityId]
get(id:ODValidId): ODPriorityLevel|null
get<PriorityId extends keyof api.ODNoGeneric<IdList>>(id:PriorityId): IdList[PriorityId]
get(id:api.ODValidId): ODPriorityLevel|null
get(id:ODValidId): ODPriorityLevel|null {
get(id:api.ODValidId): ODPriorityLevel|null {
return super.get(id)
}
remove<PriorityId extends keyof ODPriorityManagerIds>(id:PriorityId): ODPriorityManagerIds[PriorityId]
remove(id:ODValidId): ODPriorityLevel|null
remove<PriorityId extends keyof api.ODNoGeneric<IdList>>(id:PriorityId): IdList[PriorityId]
remove(id:api.ODValidId): ODPriorityLevel|null
remove(id:ODValidId): ODPriorityLevel|null {
remove(id:api.ODValidId): ODPriorityLevel|null {
return super.remove(id)
}
exists(id:keyof ODPriorityManagerIds): boolean
exists(id:ODValidId): boolean
exists(id:keyof api.ODNoGeneric<IdList>): boolean
exists(id:api.ODValidId): boolean
exists(id:ODValidId): boolean {
exists(id:api.ODValidId): boolean {
return super.exists(id)
}
}
/**## ODMappedPriorityManager `class
* A special class with types for the Open Ticket `ODPriorityManager` class.
*/
export class ODMappedPriorityManager extends ODPriorityManager<ODPriorityManagerIdMappings> {}
/**## ODPriorityLevel `class`
* This is an Open Ticket priority level.
*
@@ -83,7 +79,7 @@ export class ODPriorityManager_Default extends ODPriorityManager {
*
* #### 🚨 Negative priorities are treated as `disabled/no-priority`!
*/
export class ODPriorityLevel extends ODManagerData {
export class ODPriorityLevel extends api.ODManagerData {
/**The priority level itself. A negative number (e.g. `-1`) is treated as `disabled/no-priority`. */
priority:number
/**The raw name of the level (used in text/slash command inputs). */
@@ -95,7 +91,7 @@ export class ODPriorityLevel extends ODManagerData {
/**The emoji added to the channel name when the level is applied to a ticket. */
channelEmoji:string|null
constructor(id:ODValidId,priority:number,rawName:string,displayName:string,displayEmoji:string|null,channelEmoji:string|null){
constructor(id:api.ODValidId,priority:number,rawName:string,displayName:string,displayEmoji:string|null,channelEmoji:string|null){
super(id)
this.priority = priority
this.rawName = rawName
@@ -1,8 +1,40 @@
///////////////////////////////////////
//OPENTICKET OPTION MODULE
///////////////////////////////////////
import { ODId, ODManager, ODValidJsonType, ODValidId, ODVersion, ODManagerData } from "../modules/base"
import { ODDebugger } from "../modules/console"
import * as api from "@open-discord-bots/framework/api"
/**## ODQuestionIdConstraint `type`
* The constraint/layout for id mappings/interfaces of the `ODQuestion` class.
*/
export type ODQuestionIdConstraint = Record<string,ODQuestionData<api.ODValidJsonType>>
/**## ODShortQuestionIdMappings `interface`
* A list of all available IDs in the default `ODShortQuestion` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODShortQuestionIdMappings extends ODQuestionIdConstraint {
"opendiscord:name":ODQuestionData<string>,
"opendiscord:required":ODQuestionData<boolean>,
"opendiscord:placeholder":ODQuestionData<string>,
"opendiscord:length-enabled":ODQuestionData<boolean>,
"opendiscord:length-min":ODQuestionData<number>,
"opendiscord:length-max":ODQuestionData<number>
}
/**## ODParagraphQuestionIdMappings `interface`
* A list of all available IDs in the default `ODParagraphQuestion` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODParagraphQuestionIdMappings extends ODQuestionIdConstraint {
"opendiscord:name":ODQuestionData<string>,
"opendiscord:required":ODQuestionData<boolean>,
"opendiscord:placeholder":ODQuestionData<string>,
"opendiscord:length-enabled":ODQuestionData<boolean>,
"opendiscord:length-min":ODQuestionData<number>,
"opendiscord:length-max":ODQuestionData<number>
}
/**## ODQuestionManager `class`
* This is an Open Ticket question manager.
@@ -11,17 +43,13 @@ import { ODDebugger } from "../modules/console"
*
* Questions are not stored in the database and will be parsed from the config every startup.
*/
export class ODQuestionManager extends ODManager<ODQuestion> {
/**A reference to the Open Ticket debugger. */
#debug: ODDebugger
constructor(debug:ODDebugger){
export class ODQuestionManager extends api.ODManager<ODQuestion> {
constructor(debug:api.ODDebugger){
super(debug,"question")
this.#debug = debug
}
add(data:ODQuestion, overwrite?:boolean): boolean {
data.useDebug(this.#debug,"question data")
data.useDebug(this.debug,"question data")
return super.add(data,overwrite)
}
}
@@ -33,7 +61,7 @@ export interface ODQuestionDataJson {
/**The id of this property. */
id:string,
/**The value of this property. */
value:ODValidJsonType
value:api.ODValidJsonType
}
/**## ODQuestionDataJson `interface`
@@ -57,15 +85,15 @@ export interface ODQuestionJson {
*
* Use `ODShortQuestion` or `ODParagraphQuestion` instead!
*/
export class ODQuestion extends ODManager<ODQuestionData<ODValidJsonType>> {
export class ODQuestion extends api.ODManager<ODQuestionData<api.ODValidJsonType>> {
/**The id of this question. (from the config) */
id:ODId
id:api.ODId
/**The type of this question (e.g. `opendiscord:short` or `opendiscord:paragraph`) */
type: string
constructor(id:ODValidId, type:string, data:ODQuestionData<ODValidJsonType>[]){
constructor(id:api.ODValidId, type:string, data:ODQuestionData<api.ODValidJsonType>[]){
super()
this.id = new ODId(id)
this.id = new api.ODId(id)
this.type = type
data.forEach((data) => {
this.add(data)
@@ -73,7 +101,7 @@ export class ODQuestion extends ODManager<ODQuestionData<ODValidJsonType>> {
}
/**Convert this question to a JSON object for storing this question in the database. */
toJson(version:ODVersion): ODQuestionJson {
toJson(version:api.ODVersion): ODQuestionJson {
const data = this.getAll().map((data) => {
return {
id:data.id.toString(),
@@ -102,22 +130,22 @@ export class ODQuestion extends ODManager<ODQuestionData<ODValidJsonType>> {
*
* When this property is edited, the database will be updated automatically.
*/
export class ODQuestionData<DataType extends ODValidJsonType> extends ODManagerData {
export class ODQuestionData<DataType extends api.ODValidJsonType> extends api.ODManagerData {
/**The value of this property. */
#value: DataType
private rawValue: DataType
constructor(id:ODValidId, value:DataType){
constructor(id:api.ODValidId, value:DataType){
super(id)
this.#value = value
this.rawValue = value
}
/**The value of this property. */
set value(value:DataType){
this.#value = value
this.rawValue = value
this._change()
}
get value(): DataType {
return this.#value
return this.rawValue
}
/**Refresh the database. Is only required to be used when updating `ODQuestionData` with an object/array as value. */
refreshDatabase(){
@@ -125,19 +153,6 @@ export class ODQuestionData<DataType extends ODValidJsonType> extends ODManagerD
}
}
/**## ODShortQuestionIds `type`
* This interface is a list of ids available in the `ODShortQuestion` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODShortQuestionIds {
"opendiscord:name":ODQuestionData<string>,
"opendiscord:required":ODQuestionData<boolean>,
"opendiscord:placeholder":ODQuestionData<string>,
"opendiscord:length-enabled":ODQuestionData<boolean>,
"opendiscord:length-min":ODQuestionData<number>,
"opendiscord:length-max":ODQuestionData<number>
}
/**## ODShortQuestion `class`
* This is an Open Ticket short question.
@@ -149,28 +164,28 @@ export interface ODShortQuestionIds {
export class ODShortQuestion extends ODQuestion {
type: "opendiscord:short" = "opendiscord:short"
constructor(id:ODValidId, data:ODQuestionData<ODValidJsonType>[]){
constructor(id:api.ODValidId, data:ODQuestionData<api.ODValidJsonType>[]){
super(id,"opendiscord:short",data)
}
get<QuestionId extends keyof ODShortQuestionIds>(id:QuestionId): ODShortQuestionIds[QuestionId]
get(id:ODValidId): ODQuestionData<ODValidJsonType>|null
get<QuestionId extends keyof api.ODNoGeneric<ODShortQuestionIdMappings>>(id:QuestionId): ODShortQuestionIdMappings[QuestionId]
get(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null
get(id:ODValidId): ODQuestionData<ODValidJsonType>|null {
get(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null {
return super.get(id)
}
remove<QuestionId extends keyof ODShortQuestionIds>(id:QuestionId): ODShortQuestionIds[QuestionId]
remove(id:ODValidId): ODQuestionData<ODValidJsonType>|null
remove<QuestionId extends keyof api.ODNoGeneric<ODShortQuestionIdMappings>>(id:QuestionId): ODShortQuestionIdMappings[QuestionId]
remove(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null
remove(id:ODValidId): ODQuestionData<ODValidJsonType>|null {
remove(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODShortQuestionIds): boolean
exists(id:ODValidId): boolean
exists(id:keyof api.ODNoGeneric<ODShortQuestionIdMappings>): boolean
exists(id:api.ODValidId): boolean
exists(id:ODValidId): boolean {
exists(id:api.ODValidId): boolean {
return super.exists(id)
}
@@ -179,20 +194,6 @@ export class ODShortQuestion extends ODQuestion {
}
}
/**## ODParagraphQuestionIds `type`
* This interface is a list of ids available in the `ODParagraphQuestion` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODParagraphQuestionIds {
"opendiscord:name":ODQuestionData<string>,
"opendiscord:required":ODQuestionData<boolean>,
"opendiscord:placeholder":ODQuestionData<string>,
"opendiscord:length-enabled":ODQuestionData<boolean>,
"opendiscord:length-min":ODQuestionData<number>,
"opendiscord:length-max":ODQuestionData<number>
}
/**## ODParagraphQuestion `class`
* This is an Open Ticket paragraph question.
*
@@ -203,28 +204,28 @@ export interface ODParagraphQuestionIds {
export class ODParagraphQuestion extends ODQuestion {
type: "opendiscord:paragraph" = "opendiscord:paragraph"
constructor(id:ODValidId, data:ODQuestionData<ODValidJsonType>[]){
constructor(id:api.ODValidId, data:ODQuestionData<api.ODValidJsonType>[]){
super(id,"opendiscord:paragraph",data)
}
get<QuestionId extends keyof ODParagraphQuestionIds>(id:QuestionId): ODParagraphQuestionIds[QuestionId]
get(id:ODValidId): ODQuestionData<ODValidJsonType>|null
get<QuestionId extends keyof api.ODNoGeneric<ODParagraphQuestionIdMappings>>(id:QuestionId): ODParagraphQuestionIdMappings[QuestionId]
get(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null
get(id:ODValidId): ODQuestionData<ODValidJsonType>|null {
get(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null {
return super.get(id)
}
remove<QuestionId extends keyof ODParagraphQuestionIds>(id:QuestionId): ODParagraphQuestionIds[QuestionId]
remove(id:ODValidId): ODQuestionData<ODValidJsonType>|null
remove<QuestionId extends keyof api.ODNoGeneric<ODParagraphQuestionIdMappings>>(id:QuestionId): ODParagraphQuestionIdMappings[QuestionId]
remove(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null
remove(id:ODValidId): ODQuestionData<ODValidJsonType>|null {
remove(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODParagraphQuestionIds): boolean
exists(id:ODValidId): boolean
exists(id:keyof api.ODNoGeneric<ODParagraphQuestionIdMappings>): boolean
exists(id:api.ODValidId): boolean
exists(id:ODValidId): boolean {
exists(id:api.ODValidId): boolean {
return super.exists(id)
}
@@ -1,10 +1,25 @@
///////////////////////////////////////
//OPENTICKET ROLE MODULE
///////////////////////////////////////
import { ODId, ODManager, ODValidJsonType, ODValidId, ODVersion, ODManagerData } from "../modules/base"
import { ODDebugger } from "../modules/console"
import * as api from "@open-discord-bots/framework/api"
import * as discord from "discord.js"
/**## ODRoleIdConstraint `type`
* The constraint/layout for id mappings/interfaces of the `ODRole` class.
*/
export type ODRoleIdConstraint = Record<string,ODRoleData<api.ODValidJsonType>>
/**## ODRoleIdMappings `interface`
* A list of all available IDs in the default `ODRole` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODRoleIdMappings extends ODRoleIdConstraint {
"opendiscord:roles":ODRoleData<string[]>,
"opendiscord:mode":ODRoleData<ODRoleUpdateMode>,
"opendiscord:remove-roles-on-add":ODRoleData<string[]>,
"opendiscord:add-on-join":ODRoleData<boolean>
}
/**## ODRoleManager `class`
* This is an Open Ticket role manager.
*
@@ -12,17 +27,13 @@ import * as discord from "discord.js"
*
* Roles are not stored in the database and will be parsed from the config every startup.
*/
export class ODRoleManager extends ODManager<ODRole> {
/**A reference to the Open Ticket debugger. */
#debug: ODDebugger
constructor(debug:ODDebugger){
export class ODRoleManager extends api.ODManager<ODRole> {
constructor(debug:api.ODDebugger){
super(debug,"role")
this.#debug = debug
}
add(data:ODRole, overwrite?:boolean): boolean {
data.useDebug(this.#debug,"role data")
data.useDebug(this.debug,"role data")
return super.add(data,overwrite)
}
}
@@ -34,7 +45,7 @@ export interface ODRoleDataJson {
/**The id of this property. */
id:string,
/**The value of this property. */
value:ODValidJsonType
value:api.ODValidJsonType
}
/**## ODRoleJson `interface`
@@ -49,17 +60,6 @@ export interface ODRoleJson {
data:ODRoleDataJson[]
}
/**## ODRoleIds `type`
* This interface is a list of ids available in the `ODRole` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODRoleIds {
"opendiscord:roles":ODRoleData<string[]>,
"opendiscord:mode":ODRoleData<ODRoleUpdateMode>,
"opendiscord:remove-roles-on-add":ODRoleData<string[]>,
"opendiscord:add-on-join":ODRoleData<boolean>
}
/**## ODRole `class`
* This is an Open Ticket role.
*
@@ -67,20 +67,20 @@ export interface ODRoleIds {
*
* These properties will be used to handle reaction role options.
*/
export class ODRole extends ODManager<ODRoleData<ODValidJsonType>> {
export class ODRole extends api.ODManager<ODRoleData<api.ODValidJsonType>> {
/**The id of this role. (from the config) */
id:ODId
id:api.ODId
constructor(id:ODValidId, data:ODRoleData<ODValidJsonType>[]){
constructor(id:api.ODValidId, data:ODRoleData<api.ODValidJsonType>[]){
super()
this.id = new ODId(id)
this.id = new api.ODId(id)
data.forEach((data) => {
this.add(data)
})
}
/**Convert this role to a JSON object for storing this role in the database. */
toJson(version:ODVersion): ODRoleJson {
toJson(version:api.ODVersion): ODRoleJson {
const data = this.getAll().map((data) => {
return {
id:data.id.toString(),
@@ -100,24 +100,24 @@ export class ODRole extends ODManager<ODRoleData<ODValidJsonType>> {
return new ODRole(json.id,json.data.map((data) => new ODRoleData(data.id,data.value)))
}
get<OptionId extends keyof ODRoleIds>(id:OptionId): ODRoleIds[OptionId]
get(id:ODValidId): ODRoleData<ODValidJsonType>|null
get<OptionId extends keyof api.ODNoGeneric<ODRoleIdMappings>>(id:OptionId): ODRoleIdMappings[OptionId]
get(id:api.ODValidId): ODRoleData<api.ODValidJsonType>|null
get(id:ODValidId): ODRoleData<ODValidJsonType>|null {
get(id:api.ODValidId): ODRoleData<api.ODValidJsonType>|null {
return super.get(id)
}
remove<OptionId extends keyof ODRoleIds>(id:OptionId): ODRoleIds[OptionId]
remove(id:ODValidId): ODRoleData<ODValidJsonType>|null
remove<OptionId extends keyof api.ODNoGeneric<ODRoleIdMappings>>(id:OptionId): ODRoleIdMappings[OptionId]
remove(id:api.ODValidId): ODRoleData<api.ODValidJsonType>|null
remove(id:ODValidId): ODRoleData<ODValidJsonType>|null {
remove(id:api.ODValidId): ODRoleData<api.ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODRoleIds): boolean
exists(id:ODValidId): boolean
exists(id:keyof api.ODNoGeneric<ODRoleIdMappings>): boolean
exists(id:api.ODValidId): boolean
exists(id:ODValidId): boolean {
exists(id:api.ODValidId): boolean {
return super.exists(id)
}
}
@@ -129,22 +129,22 @@ export class ODRole extends ODManager<ODRoleData<ODValidJsonType>> {
*
* When this property is edited, the database will be updated automatically.
*/
export class ODRoleData<DataType extends ODValidJsonType> extends ODManagerData {
export class ODRoleData<DataType extends api.ODValidJsonType> extends api.ODManagerData {
/**The value of this property. */
#value: DataType
private rawValue: DataType
constructor(id:ODValidId, value:DataType){
constructor(id:api.ODValidId, value:DataType){
super(id)
this.#value = value
this.rawValue = value
}
/**The value of this property. */
set value(value:DataType){
this.#value = value
this.rawValue = value
this._change()
}
get value(): DataType {
return this.#value
return this.rawValue
}
/**Refresh the database. Is only required to be used when updating `ODRoleData` with an object/array as value. */
refreshDatabase(){
@@ -1,163 +1,25 @@
///////////////////////////////////////
//OPENTICKET TICKET MODULE
///////////////////////////////////////
import { ODId, ODManager, ODValidJsonType, ODValidId, ODVersion, ODManagerData } from "../modules/base"
import { ODDebugger } from "../modules/console"
import { ODClientManager_Default } from "../defaults/client"
import { ODTicketOption } from "./option"
import * as api from "@open-discord-bots/framework/api"
import { ODTicketOption } from "./option.js"
import * as discord from "discord.js"
/**## ODTicketManager `class`
* This is an Open Ticket ticket manager.
*
* This class manages all currently created tickets in the bot.
*
* All tickets which are added, removed or modified in this manager will be updated automatically in the database.
/**## ODTicketIdConstraint `type`
* The constraint/layout for id mappings/interfaces of the `ODTicket` class.
*/
export class ODTicketManager extends ODManager<ODTicket> {
/**A reference to the main server of the bot */
#guild: discord.Guild|null = null
/**A reference to the Open Ticket client manager. */
#client: ODClientManager_Default
/**A reference to the Open Ticket debugger. */
#debug: ODDebugger
export type ODTicketIdConstraint = Record<string,ODTicketData<api.ODValidJsonType>>
constructor(debug:ODDebugger, client:ODClientManager_Default){
super(debug,"ticket")
this.#debug = debug
this.#client = client
}
add(data:ODTicket, overwrite?:boolean): boolean {
data.useDebug(this.#debug,"ticket data")
return super.add(data,overwrite)
}
/**Use a specific guild in this class for fetching the channel*/
useGuild(guild:discord.Guild|null){
this.#guild = guild
}
/**Get the discord channel for a specific ticket. */
async getTicketChannel(ticket:ODTicket): Promise<discord.GuildTextBasedChannel|null> {
if (!this.#guild) return null
try {
const channel = await this.#guild.channels.fetch(ticket.id.value)
if (!channel || !channel.isTextBased()) return null
return channel
}catch{
return null
}
}
/**Get the main ticket message of a ticket channel when found. */
async getTicketMessage(ticket:ODTicket): Promise<discord.Message<true>|null> {
const msgId = ticket.get("opendiscord:ticket-message").value
if (!this.#guild || !msgId) return null
try {
const channel = await this.getTicketChannel(ticket)
if (!channel) return null
return await channel.messages.fetch(msgId)
}catch{
return null
}
}
/**Shortcut for getting a discord.js user within a ticket. */
async getTicketUser(ticket:ODTicket, user:"creator"|"closer"|"claimer"|"pinner"): Promise<discord.User|null> {
if (!this.#guild) return null
try {
if (user == "creator"){
const creatorId = ticket.get("opendiscord:opened-by").value
if (!creatorId) return null
else return (await this.#guild.client.users.fetch(creatorId))
}else if (user == "closer"){
const closerId = ticket.get("opendiscord:closed-by").value
if (!closerId) return null
else return (await this.#guild.client.users.fetch(closerId))
}else if (user == "claimer"){
const claimerId = ticket.get("opendiscord:claimed-by").value
if (!claimerId) return null
else return (await this.#guild.client.users.fetch(claimerId))
}else if (user == "pinner"){
const pinnerId = ticket.get("opendiscord:pinned-by").value
if (!pinnerId) return null
else return (await this.#guild.client.users.fetch(pinnerId))
}else return null
}catch {return null}
}
/**Shortcut for getting all users that are able to view a ticket. */
async getAllTicketParticipants(ticket:ODTicket): Promise<{user:discord.User,role:"creator"|"participant"|"admin"}[]|null> {
if (!this.#guild) return null
const final: {user:discord.User,role:"creator"|"participant"|"admin"}[] = []
const channel = await this.getTicketChannel(ticket)
if (!channel) return null
//add creator
const creatorId = ticket.get("opendiscord:opened-by").value
if (creatorId){
const creator = await this.#client.fetchUser(creatorId)
if (creator) final.push({user:creator,role:"creator"})
}
//add participants
const participants = ticket.get("opendiscord:participants").value.filter((p) => p.type == "user")
for (const p of participants){
if (!final.find((u) => u.user.id == p.id)){
const participant = await this.#client.fetchUser(p.id)
if (participant) final.push({user:participant,role:"participant"})
}
}
//add admin roles
const roles = ticket.get("opendiscord:participants").value.filter((p) => p.type == "role")
for (const r of roles){
const role = await this.#client.fetchGuildRole(channel.guild,r.id)
if (role){
role.members.forEach((member) => {
if (final.find((u) => u.user.id == member.id)) return
final.push({user:member.user,role:"admin"})
})
}
}
return final
}
}
/**## ODTicketDataJson `interface`
* The JSON representatation from a single ticket property.
*/
export interface ODTicketDataJson {
/**The id of this property. */
id:string,
/**The value of this property. */
value:ODValidJsonType
}
/**## ODTicketDataJson `interface`
* The JSON representatation from a single ticket.
*/
export interface ODTicketJson {
/**The id of this ticket. */
id:string,
/**The option id related to this ticket. */
option:string,
/**The version of Open Ticket used to create this ticket. */
version:string,
/**The full list of properties/variables related to this ticket. */
data:ODTicketDataJson[]
}
/**## ODTicketIds `type`
* This interface is a list of ids available in the `ODTicket` class.
/**## ODTicketIdMappings `interface`
* A list of all available IDs in the default `ODTicket` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODTicketIds {
export interface ODTicketIdMappings extends ODTicketIdConstraint {
"opendiscord:busy":ODTicketData<boolean>,
"opendiscord:ticket-message":ODTicketData<string|null>,
"opendiscord:participants":ODTicketData<{type:"role"|"user",id:string}[]>,
"opendiscord:channel-suffix":ODTicketData<string>,
"opendiscord:channel-renamed":ODTicketData<string|null>,
"opendiscord:previous-creators":ODTicketData<string[]>,
"opendiscord:open":ODTicketData<boolean>,
@@ -178,7 +40,7 @@ export interface ODTicketIds {
"opendiscord:for-deletion":ODTicketData<boolean>,
"opendiscord:category":ODTicketData<string|null>,
"opendiscord:category-mode":ODTicketData<null|"normal"|"closed"|"backup"|"claimed">,
"opendiscord:category-mode":ODTicketData<string|null>,
"opendiscord:autoclose-enabled":ODTicketData<boolean>,
"opendiscord:autoclose-hours":ODTicketData<number>,
@@ -193,6 +55,145 @@ export interface ODTicketIds {
"opendiscord:admin-message-sent":ODTicketData<boolean>,
}
/**## ODTicketManager `class`
* This is an Open Ticket ticket manager.
*
* This class manages all currently created tickets in the bot.
*
* All tickets which are added, removed or modified in this manager will be updated automatically in the database.
*/
export class ODTicketManager extends api.ODManager<ODTicket> {
/**A reference to the main server of the bot */
private guild: discord.Guild|null = null
/**A reference to the Open Ticket client manager. */
private client: api.ODClientManager
constructor(debug:api.ODDebugger, client:api.ODClientManager){
super(debug,"ticket")
this.client = client
}
add(data:ODTicket, overwrite?:boolean): boolean {
data.useDebug(this.debug,"ticket data")
return super.add(data,overwrite)
}
/**Use a specific guild in this class for fetching the channel*/
useGuild(guild:discord.Guild|null){
this.guild = guild
}
/**Get the discord channel for a specific ticket. */
async getTicketChannel(ticket:ODTicket): Promise<discord.GuildTextBasedChannel|null> {
if (!this.guild) return null
try {
const channel = await this.guild.channels.fetch(ticket.id.value)
if (!channel || !channel.isTextBased()) return null
return channel
}catch{
return null
}
}
/**Get the main ticket message of a ticket channel when found. */
async getTicketMessage(ticket:ODTicket): Promise<discord.Message<true>|null> {
const msgId = ticket.get("opendiscord:ticket-message").value
if (!this.guild || !msgId) return null
try {
const channel = await this.getTicketChannel(ticket)
if (!channel) return null
return await channel.messages.fetch(msgId)
}catch{
return null
}
}
/**Shortcut for getting a discord.js user within a ticket. */
async getTicketUser(ticket:ODTicket, user:"creator"|"closer"|"claimer"|"pinner"): Promise<discord.User|null> {
if (!this.guild) return null
try {
if (user == "creator"){
const creatorId = ticket.get("opendiscord:opened-by").value
if (!creatorId) return null
else return (await this.guild.client.users.fetch(creatorId))
}else if (user == "closer"){
const closerId = ticket.get("opendiscord:closed-by").value
if (!closerId) return null
else return (await this.guild.client.users.fetch(closerId))
}else if (user == "claimer"){
const claimerId = ticket.get("opendiscord:claimed-by").value
if (!claimerId) return null
else return (await this.guild.client.users.fetch(claimerId))
}else if (user == "pinner"){
const pinnerId = ticket.get("opendiscord:pinned-by").value
if (!pinnerId) return null
else return (await this.guild.client.users.fetch(pinnerId))
}else return null
}catch {return null}
}
/**Shortcut for getting all users that are able to view a ticket. */
async getAllTicketParticipants(ticket:ODTicket): Promise<{user:discord.User,role:"creator"|"participant"|"admin"}[]|null> {
if (!this.guild) return null
const final: {user:discord.User,role:"creator"|"participant"|"admin"}[] = []
const channel = await this.getTicketChannel(ticket)
if (!channel) return null
//add creator
const creatorId = ticket.get("opendiscord:opened-by").value
if (creatorId){
const creator = await this.client.fetchUser(creatorId)
if (creator) final.push({user:creator,role:"creator"})
}
//add participants
const participants = ticket.get("opendiscord:participants").value.filter((p) => p.type == "user")
for (const p of participants){
if (!final.find((u) => u.user.id == p.id)){
const participant = await this.client.fetchUser(p.id)
if (participant) final.push({user:participant,role:"participant"})
}
}
//add admin roles
const roles = ticket.get("opendiscord:participants").value.filter((p) => p.type == "role")
for (const r of roles){
const role = await this.client.fetchGuildRole(channel.guild,r.id)
if (role){
role.members.forEach((member) => {
if (final.find((u) => u.user.id == member.id)) return
final.push({user:member.user,role:"admin"})
})
}
}
return final
}
}
/**## ODTicketDataJson `interface`
* The JSON representatation from a single ticket property.
*/
export interface ODTicketDataJson {
/**The id of this property. */
id:string,
/**The value of this property. */
value:api.ODValidJsonType
}
/**## ODTicketDataJson `interface`
* The JSON representatation from a single ticket.
*/
export interface ODTicketJson {
/**The id of this ticket. */
id:string,
/**The option id related to this ticket. */
option:string,
/**The version of Open Ticket used to create this ticket. */
version:string,
/**The full list of properties/variables related to this ticket. */
data:ODTicketDataJson[]
}
/**## ODTicket `class`
* This is an Open Ticket ticket.
*
@@ -200,32 +201,32 @@ export interface ODTicketIds {
*
* These properties contain the current state of the ticket & are used by actions like claiming, pinning, closing, ...
*/
export class ODTicket extends ODManager<ODTicketData<ODValidJsonType>> {
export class ODTicket extends api.ODManager<ODTicketData<api.ODValidJsonType>> {
/**The id of this ticket. (discord channel id) */
id:ODId
/**The option related to this ticket. */
#option: ODTicketOption
id:api.ODId
/**The option this ticket is made of. */
private rawOption: ODTicketOption
constructor(id:ODValidId, option:ODTicketOption, data:ODTicketData<ODValidJsonType>[]){
constructor(id:api.ODValidId, option:ODTicketOption, data:ODTicketData<api.ODValidJsonType>[]){
super()
this.id = new ODId(id)
this.#option = option
this.id = new api.ODId(id)
this.rawOption = option
data.forEach((data) => {
this.add(data)
})
}
/**The option related to this ticket. */
/**The option this ticket is made of. */
set option(option:ODTicketOption){
this.#option = option
this.rawOption = option
this._change()
}
get option(){
return this.#option
return this.rawOption
}
/**Convert this ticket to a JSON object for storing this ticket in the database. */
toJson(version:ODVersion): ODTicketJson {
toJson(version:api.ODVersion): ODTicketJson {
const data = this.getAll().map((data) => {
return {
id:data.id.toString(),
@@ -246,24 +247,24 @@ export class ODTicket extends ODManager<ODTicketData<ODValidJsonType>> {
return new ODTicket(json.id,option,json.data.map((data) => new ODTicketData(data.id,data.value)))
}
get<OptionId extends keyof ODTicketIds>(id:OptionId): ODTicketIds[OptionId]
get(id:ODValidId): ODTicketData<ODValidJsonType>|null
get<OptionId extends keyof api.ODNoGeneric<ODTicketIdMappings>>(id:OptionId): ODTicketIdMappings[OptionId]
get(id:api.ODValidId): ODTicketData<api.ODValidJsonType>|null
get(id:ODValidId): ODTicketData<ODValidJsonType>|null {
get(id:api.ODValidId): ODTicketData<api.ODValidJsonType>|null {
return super.get(id)
}
remove<OptionId extends keyof ODTicketIds>(id:OptionId): ODTicketIds[OptionId]
remove(id:ODValidId): ODTicketData<ODValidJsonType>|null
remove<OptionId extends keyof api.ODNoGeneric<ODTicketIdMappings>>(id:OptionId): ODTicketIdMappings[OptionId]
remove(id:api.ODValidId): ODTicketData<api.ODValidJsonType>|null
remove(id:ODValidId): ODTicketData<ODValidJsonType>|null {
remove(id:api.ODValidId): ODTicketData<api.ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODTicketIds): boolean
exists(id:ODValidId): boolean
exists(id:keyof api.ODNoGeneric<ODTicketIdMappings>): boolean
exists(id:api.ODValidId): boolean
exists(id:ODValidId): boolean {
exists(id:api.ODValidId): boolean {
return super.exists(id)
}
}
@@ -275,22 +276,22 @@ export class ODTicket extends ODManager<ODTicketData<ODValidJsonType>> {
*
* When this property is edited, the database will be updated automatically.
*/
export class ODTicketData<DataType extends ODValidJsonType> extends ODManagerData {
export class ODTicketData<DataType extends api.ODValidJsonType> extends api.ODManagerData {
/**The value of this property. */
#value: DataType
private rawValue: DataType
constructor(id:ODValidId, value:DataType){
constructor(id:api.ODValidId, value:DataType){
super(id)
this.#value = value
this.rawValue = value
}
/**The value of this property. */
set value(value:DataType){
this.#value = value
this.rawValue = value
this._change()
}
get value(): DataType {
return this.#value
return this.rawValue
}
/**Refresh the database. Is only required to be used when updating `ODTicketData` with an object/array as value. */
refreshDatabase(){
@@ -1,13 +1,23 @@
///////////////////////////////////////
//OPENTICKET TRANSCRIPT MODULE
///////////////////////////////////////
import { ODId, ODManager, ODValidJsonType, ODValidId, ODManagerData, ODValidButtonColor } from "../modules/base"
import { ODDebugger } from "../modules/console"
import { ODTicket, ODTicketManager } from "./ticket"
import { ODMessageBuildResult } from "../modules/builder"
import { ODClientManager } from "../modules/client"
import * as api from "@open-discord-bots/framework/api"
import { ODTicket, ODTicketManager } from "./ticket.js"
import * as discord from "discord.js"
import { ODPermissionManager_Default } from "#opendiscord-types"
/**## ODTranscriptManagerIdConstraint `type`
* The constraint/layout for id mappings/interfaces of the `ODTranscriptManager` class.
*/
export type ODTranscriptManagerIdConstraint = Record<string,ODTranscriptCompiler<any,null|object>>
/**## ODTranscriptManagerIdMappings `interface`
* A list of all available IDs in the default `ODTranscriptManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODTranscriptManagerIdMappings extends ODTranscriptManagerIdConstraint {
"opendiscord:html-compiler":ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,
"opendiscord:text-compiler":ODTranscriptCompiler<{contents:string},null>,
}
/**## ODTranscriptManager `class`
* This is an Open Ticket transcript manager.
@@ -16,19 +26,45 @@ import { ODPermissionManager_Default } from "#opendiscord-types"
*
* The 2 default built-in transcript generators are: `opendiscord:html-compiler` & `opendiscord:text-compiler`.
*/
export class ODTranscriptManager extends ODManager<ODTranscriptCompiler<any,null|object>> {
export class ODTranscriptManager<IdList extends ODTranscriptManagerIdConstraint = ODTranscriptManagerIdConstraint> extends api.ODManager<ODTranscriptCompiler<any,null|object>> {
/**The manager responsible for collecting all messages in a channel. */
collector: ODTranscriptCollector
/**Alias for the client manager. */
#client: ODClientManager
private client: api.ODClientManager
constructor(debug:ODDebugger, tickets:ODTicketManager, client:ODClientManager, permissions:ODPermissionManager_Default){
constructor(debug:api.ODDebugger, tickets:ODTicketManager, client:api.ODClientManager, permissions:api.ODPermissionManager){
super(debug,"transcript compiler")
this.#client = client
this.client = client
this.collector = new ODTranscriptCollector(tickets,client,permissions)
}
get<CompilerId extends keyof api.ODNoGeneric<IdList>>(id:CompilerId): IdList[CompilerId]
get(id:api.ODValidId): ODTranscriptCompiler<any,null|object>|null
get(id:api.ODValidId): ODTranscriptCompiler<any,null|object>|null {
return super.get(id)
}
remove<CompilerId extends keyof api.ODNoGeneric<IdList>>(id:CompilerId): IdList[CompilerId]
remove(id:api.ODValidId): ODTranscriptCompiler<any,null|object>|null
remove(id:api.ODValidId): ODTranscriptCompiler<any,null|object>|null {
return super.remove(id)
}
exists(id:keyof api.ODNoGeneric<IdList>): boolean
exists(id:api.ODValidId): boolean
exists(id:api.ODValidId): boolean {
return super.exists(id)
}
}
/**## ODMappedTranscriptManager `class
* A special class with types for the Open Ticket `ODTranscriptManager` class.
*/
export class ODMappedTranscriptManager extends ODTranscriptManager<ODTranscriptManagerIdMappings> {}
/**## ODTranscriptCompilerInitFunction `type`
* This function will initiate/prepare the transcript system for an incoming transcript.
*/
@@ -53,7 +89,7 @@ export interface ODTranscriptCompilerInitResult<InitData extends object|null> {
/**When not successfull, what was the reason? This will also be shown to the user. */
errorReason:string|null,
/**An optional message which will be sent while the transcript is being generated. */
pendingMessage:ODMessageBuildResult|null,
pendingMessage:api.ODMessageBuildResult|api.ODMessageComponentBuildResult|null,
/**An optional object containing data from the init() function which can be used in the compiler. */
initData:InitData,
}
@@ -83,15 +119,15 @@ export interface ODTranscriptCompilerCompileResult<Data extends object> {
*/
export interface ODTranscriptCompilerReadyResult {
/**The message to be sent in the specified channel in the server. */
channelMessage?:ODMessageBuildResult,
channelMessage?:api.ODMessageBuildResult|api.ODMessageComponentBuildResult,
/**The message to be sent to the DM of the ticket creator. */
creatorDmMessage?:ODMessageBuildResult,
creatorDmMessage?:api.ODMessageBuildResult|api.ODMessageComponentBuildResult,
/**The message to be sent to the DM of all participants. */
participantDmMessage?:ODMessageBuildResult,
participantDmMessage?:api.ODMessageBuildResult|api.ODMessageComponentBuildResult,
/**The message to be sent to the DM of all admins who actively participated in the ticket. */
activeAdminDmMessage?:ODMessageBuildResult,
activeAdminDmMessage?:api.ODMessageBuildResult|api.ODMessageComponentBuildResult,
/**The message to be sent to the DM of all admins who were assigned to this ticket. */
everyAdminDmMessage?:ODMessageBuildResult
everyAdminDmMessage?:api.ODMessageBuildResult|api.ODMessageComponentBuildResult
}
/**## ODTranscriptCompiler `class`
@@ -101,7 +137,7 @@ export interface ODTranscriptCompilerReadyResult {
*
* These functions should be defined when creating this compiler. Existing compilers already exist for html & text transcripts.
*/
export class ODTranscriptCompiler<Data extends object,InitData extends (object|null)> extends ODManagerData {
export class ODTranscriptCompiler<Data extends object,InitData extends (object|null)> extends api.ODManagerData {
/*Initialise the system every time a transcript is created. Returns optional "pending" message to display while the transcript is being compiled. */
init: ODTranscriptCompilerInitFunction<InitData>|null
/*Compile or create the transcript. Returns data to give to the ready() function for message creation. */
@@ -109,7 +145,7 @@ export class ODTranscriptCompiler<Data extends object,InitData extends (object|n
/*Unload the system & create the final transcript message that will be sent. */
ready: ODTranscriptCompilerReadyFunction<Data>|null
constructor(id:ODValidId, init?:ODTranscriptCompilerInitFunction<InitData>, compile?:ODTranscriptCompilerCompileFunction<Data,InitData>, ready?:ODTranscriptCompilerReadyFunction<Data>|null){
constructor(id:api.ODValidId, init?:ODTranscriptCompilerInitFunction<InitData>, compile?:ODTranscriptCompilerCompileFunction<Data,InitData>, ready?:ODTranscriptCompilerReadyFunction<Data>|null){
super(id)
this.init = init ?? null
this.compile = compile ?? null
@@ -117,44 +153,6 @@ export class ODTranscriptCompiler<Data extends object,InitData extends (object|n
}
}
/**## ODTranscriptCompilerIds `type`
* This interface is a list of ids available in the `ODTranscriptCompiler` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODTranscriptCompilerIds {
"opendiscord:html-compiler":ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,
"opendiscord:text-compiler":ODTranscriptCompiler<{contents:string},null>,
}
/**## ODTranscriptManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODTranscriptManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.transcripts`!
*/
export class ODTranscriptManager_Default extends ODTranscriptManager {
get<CompilerId extends keyof ODTranscriptCompilerIds>(id:CompilerId): ODTranscriptCompilerIds[CompilerId]
get(id:ODValidId): ODTranscriptCompiler<any,null|object>|null
get(id:ODValidId): ODTranscriptCompiler<any,null|object>|null {
return super.get(id)
}
remove<CompilerId extends keyof ODTranscriptCompilerIds>(id:CompilerId): ODTranscriptCompilerIds[CompilerId]
remove(id:ODValidId): ODTranscriptCompiler<any,null|object>|null
remove(id:ODValidId): ODTranscriptCompiler<any,null|object>|null {
return super.remove(id)
}
exists(id:keyof ODTranscriptCompilerIds): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODTranscriptCollector `class`
* This is an Open Ticket transcript collector.
*
@@ -164,22 +162,22 @@ export class ODTranscriptManager_Default extends ODTranscriptManager {
*/
export class ODTranscriptCollector {
/**Alias for the ticket manager. */
#tickets: ODTicketManager
private tickets: ODTicketManager
/**Alias for the client manager. */
#client: ODClientManager
private client: api.ODClientManager
/**Alias for the permissions manager. */
#permissions: ODPermissionManager_Default
private permissions: api.ODPermissionManager
constructor(tickets:ODTicketManager,client:ODClientManager,permissions:ODPermissionManager_Default){
this.#tickets = tickets
this.#client = client
this.#permissions = permissions
constructor(tickets:ODTicketManager,client:api.ODClientManager,permissions:api.ODPermissionManager){
this.tickets = tickets
this.client = client
this.permissions = permissions
}
/**Collect all messages from a given ticket channel. It may not include all messages depending on the ratelimit. */
async collectAllMessages(ticket:ODTicket, include?:ODTranscriptCollectorIncludeSettings): Promise<discord.Message<true>[]|null> {
const newInclude: ODTranscriptCollectorIncludeSettings = include ?? {users:true,bots:true,client:true}
const channel = await this.#tickets.getTicketChannel(ticket)
const channel = await this.tickets.getTicketChannel(ticket)
if (!channel) return null
const final: discord.Message<true>[] = []
@@ -215,7 +213,7 @@ export class ODTranscriptCollector {
const {guild,channel,id,createdTimestamp} = msg
//create message author
const author = this.#handleUserData(msg.author,msg.member)
const author = this.handleUserData(msg.author,msg.member)
//create message type
let type: ODTranscriptMessageType = "default"
@@ -271,8 +269,8 @@ export class ODTranscriptCollector {
disabled:component.disabled,
type:"button",
label:component.label,
emoji:this.#handleComponentEmoji(msg,component.emoji),
color:this.#handleButtonComponentStyle(component.style),
emoji:this.handleComponentEmoji(msg,component.emoji),
color:this.handleButtonComponentStyle(component.style),
mode:(component.style == discord.ButtonStyle.Link) ? "url" : "button",
url:component.url
})
@@ -287,7 +285,7 @@ export class ODTranscriptCollector {
id:option.value,
label:option.label,
description:option.description ?? null,
emoji:this.#handleComponentEmoji(msg,option.emoji ?? null)
emoji:this.handleComponentEmoji(msg,option.emoji ?? null)
}
})
})
@@ -305,7 +303,7 @@ export class ODTranscriptCollector {
if (replyChannel && !replyChannel.isDMBased() && replyChannel.isTextBased()){
const replyMessage = await replyChannel.messages.fetch(msg.reference.messageId)
if (replyMessage){
const replyUser = this.#handleUserData(replyMessage.author,replyMessage.member)
const replyUser = this.handleUserData(replyMessage.author,replyMessage.member)
reply = {
type:"message",
@@ -322,7 +320,7 @@ export class ODTranscriptCollector {
}else if (msg.interactionMetadata){
try{
//get slash command name from undocumented property in discord REST API
const restMsg = await this.#client.rest.get(discord.Routes.channelMessage(msg.channelId,msg.id)) as discord.APIMessage & {interaction_metadata:{name:string}}
const restMsg = await this.client.rest.get(discord.Routes.channelMessage(msg.channelId,msg.id)) as discord.APIMessage & {interaction_metadata:{name:string}}
const commandName = restMsg.interaction_metadata.name ?? "unknown-command"
//slash command reply
let member: discord.GuildMember|null = null
@@ -332,7 +330,7 @@ export class ODTranscriptCollector {
reply = {
type:"interaction",
name:commandName,
user:this.#handleUserData(msg.interactionMetadata.user,member)
user:this.handleUserData(msg.interactionMetadata.user,member)
}
}catch(err){
process.emit("uncaughtException",err)
@@ -397,7 +395,7 @@ export class ODTranscriptCollector {
else return {size:Math.round(bytes/(1024*1024*1024*1024)),unit:"TB"}
}
/**Get the `ODTranscriptEmojiData` from a discord.js component emoji. */
#handleComponentEmoji(message:discord.Message<true>, rawEmoji:discord.APIMessageComponentEmoji|null): ODTranscriptEmojiData|null {
private handleComponentEmoji(message:discord.Message<true>, rawEmoji:discord.APIMessageComponentEmoji|null): ODTranscriptEmojiData|null {
if (!rawEmoji) return null
//return built-in emoji
if (rawEmoji.name) return {
@@ -420,14 +418,14 @@ export class ODTranscriptCollector {
}
}
/**Create the `ODValidButtonColor` from the discord.js button style. */
#handleButtonComponentStyle(style:discord.ButtonStyle): ODValidButtonColor {
private handleButtonComponentStyle(style:discord.ButtonStyle): api.ODValidButtonColor {
if (style == discord.ButtonStyle.Danger) return "red"
else if (style == discord.ButtonStyle.Success) return "green"
else if (style == discord.ButtonStyle.Primary) return "blue"
else return "gray"
}
/**Create the `ODTranscriptUserData` from a discord.js user. */
#handleUserData(user:discord.User, member?:discord.GuildMember|null): ODTranscriptUserData {
private handleUserData(user:discord.User, member?:discord.GuildMember|null): ODTranscriptUserData {
const userData: ODTranscriptUserData = {
id:user.id,
username:user.username,
@@ -452,10 +450,10 @@ export class ODTranscriptCollector {
let adminMessages = 0
for (const msg of parsedMessages){
if (msg.author.tag || msg.author.id == this.#client.client.user.id) continue
const user = await this.#client.fetchUser(msg.author.id)
if (msg.author.tag || msg.author.id == this.client.client.user.id) continue
const user = await this.client.fetchUser(msg.author.id)
if (!user) continue
const isAdmin = this.#permissions.hasPermissions("support",await this.#permissions.getPermissions(user,channel,guild))
const isAdmin = this.permissions.hasPermissions("support",await this.permissions.getPermissions(user,channel,guild))
if (isAdmin) adminMessages++
else userMessages++
}
@@ -622,7 +620,7 @@ export interface ODTranscriptButtonComponentData extends ODTranscriptComponentDa
/**The emoji of this button. */
emoji: ODTranscriptEmojiData|null,
/**The color of this button. */
color: ODValidButtonColor,
color: api.ODValidButtonColor,
/**Is this button a url or button? */
mode: "url"|"button",
/**The url of this button. */
+12 -63
View File
@@ -1,8 +1,7 @@
import {opendiscord, api, utilities} from "../../index"
import {Terminal, terminal} from "terminal-kit"
import ansis from "ansis"
import {opendiscord, api, utilities} from "../../index.js"
import * as cli from "@open-discord-bots/framework/cli"
const logo = [
export const logo = [
" ██████╗ ██████╗ ███████╗███╗ ██╗ ████████╗██╗ ██████╗██╗ ██╗███████╗████████╗ ",
" ██╔═══██╗██╔══██╗██╔════╝████╗ ██║ ╚══██╔══╝██║██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝ ",
" ██║ ██║██████╔╝█████╗ ██╔██╗ ██║ ██║ ██║██║ █████╔╝ █████╗ ██║ ",
@@ -10,66 +9,16 @@ const logo = [
" ╚██████╔╝██║ ███████╗██║ ╚████║ ██║ ██║╚██████╗██║ ██╗███████╗ ██║ ",
" ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═╝ "
]
/**A utility function to center text to a certain width. */
export function centerText(text:string,width:number){
if (width < text.length) return text
let newWidth = width-ansis.strip(text).length+1
let final = " ".repeat(newWidth/2)+text
return final
}
/**A utility function to terminate the interactive CLI. */
export async function terminate(){
terminal.grabInput(false)
terminal.clear()
terminal.green("👋 Exited the Open Ticket Interactive Setup CLI.\n")
process.exit(0)
}
terminal.on("key",(name,matches,data) => {
if (name == "CTRL_C") terminate()
})
/**Render the header of the interactive CLI. */
export function renderHeader(path:(string|number)[]|string){
terminal.grabInput(true)
terminal.clear().moveTo(1,1)
terminal(ansis.hex("#f8ba00")(logo.join("\n")+"\n"))
terminal.bold(centerText("Interactive Setup CLI - Version: "+opendiscord.versions.get("opendiscord:version").toString()+" - Support: https://discord.dj-dj.be\n",88))
if (typeof path == "string") terminal.cyan(centerText(path+"\n\n",88))
else if (path.length < 1) terminal.cyan(centerText("👋 Hi! Welcome to the Open Ticket Interactive Setup CLI! 👋\n\n",88))
else terminal.cyan(centerText("🌐 Current Location: "+path.map((v,i) => {
if (i == 0) return v.toString()
else if (typeof v == "string") return ".\""+v+"\""
else if (typeof v == "number") return "."+v
}).join("")+"\n\n",88))
}
async function renderCliModeSelector(backFn:(() => api.ODPromiseVoid)){
renderHeader([])
terminal(ansis.bold.green("Please select what CLI module you want to use.\n")+ansis.italic.gray("(use arrow keys to navigate, exit using escape)\n"))
const answer = await terminal.singleColumnMenu([
"✏️ Edit Config "+ansis.gray("=> Edit the current config, add/remove new tickets/questions/panels & more!"),
"⏱️ Quick Setup "+ansis.gray("=> A quick and easy way of setting up the bot in your Discord server."),
],{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (answer.canceled) return await backFn()
else if (answer.selectedIndex == 0) await (await import("./editConfig.js")).renderEditConfig(async () => {await renderCliModeSelector(backFn)})
else if (answer.selectedIndex == 1) await (await import("./quickSetup.js")).renderQuickSetup(async () => {await renderCliModeSelector(backFn)})
export const headerOpts: cli.ODCliHeaderOpts = {
logo,
projectColor:"#f8ba00",
projectName:"Open Ticket",
projectVersion:opendiscord.versions.get("opendiscord:version")
}
export async function execute(){
if (terminal.width < 100 || terminal.height < 35){
terminal(ansis.red.bold("\n\nMake sure your console or cmd window has a "+ansis.cyan("minimum width & height")+" of "+ansis.cyan("100x35")+" characters."))
terminal(ansis.red.bold("\nOtherwise the Open Ticket Interactive Setup CLI will be rendered incorrectly."))
terminal(ansis.red.bold("\nThe current terminal dimensions are: "+ansis.cyan(terminal.width+"x"+terminal.height)+"."))
}else await renderCliModeSelector(terminate)
const editConfig = new cli.ODCliEditConfigInstance(headerOpts,opendiscord)
const renderQuickSetup = (await import("./quickSetup.js")).renderQuickSetup
await cli.execute(headerOpts,async (backFn) => {return editConfig.renderEditConfig(backFn)},renderQuickSetup)
}
-933
View File
@@ -1,933 +0,0 @@
import {opendiscord, api, utilities} from "../../index"
import {Terminal, terminal} from "terminal-kit"
import ansis from "ansis"
import {renderHeader} from "./cli"
export async function renderEditConfig(backFn:(() => api.ODPromiseVoid)){
renderHeader([])
terminal(ansis.bold.green("Please select which config you would like to edit.\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
const checkerList = opendiscord.checkers.getAll()
const checkerNameList = checkerList.map((checker) => (checker.options.cliDisplayName ? checker.options.cliDisplayName+" ("+checker.config.file+")" : checker.config.file))
const checkerNameLength = utilities.getLongestLength(checkerNameList)
const finalCheckerNameList = checkerNameList.map((name,index) => name.padEnd(checkerNameLength+5," ")+ansis.gray(checkerList[index].options.cliDisplayDescription ? "=> "+checkerList[index].options.cliDisplayDescription : ""))
const answer = await terminal.singleColumnMenu(finalCheckerNameList,{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (answer.canceled) return await backFn()
const checker = checkerList[answer.selectedIndex]
const configData = checker.config.data as api.ODValidJsonType
await chooseConfigStructure(checker,async () => {await renderEditConfig(backFn)},checker.structure,configData,{},NaN,["("+checker.config.path+")"])
}
async function chooseConfigStructure(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),structure:api.ODCheckerStructure,data:api.ODValidJsonType,parent:object|any[],parentIndex:string|number,path:(string|number)[]){
if (structure instanceof api.ODCheckerObjectStructure && typeof data == "object" && !Array.isArray(data) && data) await renderConfigObjectStructureSelector(checker,backFn,structure,data,parent,parentIndex,path)
else if (structure instanceof api.ODCheckerEnabledObjectStructure && typeof data == "object" && !Array.isArray(data) && data) await renderConfigEnabledObjectStructureSelector(checker,backFn,structure,data,parent,parentIndex,path)
else if (structure instanceof api.ODCheckerObjectSwitchStructure && typeof data == "object" && !Array.isArray(data) && data) await renderConfigObjectSwitchStructureSelector(checker,backFn,structure,data,parent,parentIndex,path)
else if (structure instanceof api.ODCheckerArrayStructure && Array.isArray(data)) await renderConfigArrayStructureSelector(checker,backFn,structure,data,parent,parentIndex,path)
else if (structure instanceof api.ODCheckerBooleanStructure && typeof data == "boolean") await renderConfigBooleanStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)
else if (structure instanceof api.ODCheckerNumberStructure && typeof data == "number") await renderConfigNumberStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)
else if (structure instanceof api.ODCheckerStringStructure && typeof data == "string") await renderConfigStringStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)
else if (structure instanceof api.ODCheckerNullStructure && data === null) await renderConfigNullStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)
else if (structure instanceof api.ODCheckerTypeSwitchStructure) await renderConfigTypeSwitchStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)
else terminal.red.bold("❌ Unable to detect type of variable! Please try to edit this property in the JSON file itself!")
}
async function renderConfigObjectStructureSelector(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),structure:api.ODCheckerObjectStructure,data:object,parent:object,parentIndex:string|number,path:(string|number)[]){
if (typeof data != "object" || Array.isArray(data)) throw new api.ODSystemError("OT CLI => Property is not of the type 'object'. Please check your config for possible errors. (index: "+parentIndex+", path: "+path.join(".")+")")
renderHeader(path)
terminal(ansis.bold.green("Please select which variable you would like to edit.\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
if (!structure.options.children) return await backFn()
if (structure.options.cliDisplayName){
terminal.gray("\nProperty: "+ansis.bold.blue(structure.options.cliDisplayName)+"\n")
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
}
const list = structure.options.children.filter((child) => !child.cliHideInEditMode)
const nameList = list.map((child) => (child.checker.options.cliDisplayName ? child.checker.options.cliDisplayName : child.key))
const nameLength = utilities.getLongestLength(nameList)
const finalnameList = nameList.map((name,index) => name.padEnd(nameLength+5," ")+ansis.gray((!list[index].checker.options.cliHideDescriptionInParent && list[index].checker.options.cliDisplayDescription) ? "=> "+list[index].checker.options.cliDisplayDescription : ""))
const answer = await terminal.singleColumnMenu(finalnameList,{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold.defaultColor,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (answer.canceled) return await backFn()
const subStructure = list[answer.selectedIndex]
const subData = data[subStructure.key]
await chooseConfigStructure(checker,async () => {await renderConfigObjectStructureSelector(checker,backFn,structure,data,parent,parentIndex,path)},subStructure.checker,subData,data,subStructure.key,[...path,subStructure.key])
}
async function renderConfigEnabledObjectStructureSelector(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),structure:api.ODCheckerEnabledObjectStructure,data:object,parent:object,parentIndex:string|number,path:(string|number)[]){
if (typeof data != "object" || Array.isArray(data)) throw new api.ODSystemError("OT CLI => Property is not of the type 'object'. Please check your config for possible errors. (index: "+parentIndex+", path: "+path.join(".")+")")
const enabledProperty = structure.options.property
const subStructure = structure.options.checker
if (!enabledProperty || !subStructure || !subStructure.options.children) return await backFn()
if (!subStructure.options.children.find((child) => child.key === structure.options.property)){
if (typeof structure.options.enabledValue == "string") subStructure.options.children.unshift({key:enabledProperty,optional:false,priority:1,checker:new api.ODCheckerStringStructure("opendiscord:CLI-checker-enabled-object-structure",{})})
else if (typeof structure.options.enabledValue == "number") subStructure.options.children.unshift({key:enabledProperty,optional:false,priority:1,checker:new api.ODCheckerNumberStructure("opendiscord:CLI-checker-enabled-object-structure",{})})
else if (typeof structure.options.enabledValue == "boolean") subStructure.options.children.unshift({key:enabledProperty,optional:false,priority:1,checker:new api.ODCheckerBooleanStructure("opendiscord:CLI-checker-enabled-object-structure",{})})
}
await chooseConfigStructure(checker,backFn,subStructure,data,parent,parentIndex,path)
}
async function renderConfigObjectSwitchStructureSelector(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),structure:api.ODCheckerObjectSwitchStructure,data:object,parent:object,parentIndex:string|number,path:(string|number)[]){
if (typeof data != "object" || Array.isArray(data)) throw new api.ODSystemError("OT CLI => Property is not of the type 'object'. Please check your config for possible errors. (index: "+parentIndex+", path: "+path.join(".")+")")
if (!structure.options.objects) return await backFn()
let didMatch: boolean = false
for (const objectTemplate of structure.options.objects){
if (objectTemplate.properties.every((prop) => data[prop.key] === prop.value)){
//object template matches data
const subStructure = objectTemplate.checker
didMatch = true
await chooseConfigStructure(checker,backFn,subStructure,data,parent,parentIndex,path)
}
}
if (!didMatch) throw new api.ODSystemError("OT CLI => Unable to detect type of object in the object switch. Please check your config for possible errors. (index: "+parentIndex+", path: "+path.join(".")+")")
}
async function renderConfigArrayStructureSelector(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),structure:api.ODCheckerArrayStructure,data:any[],parent:object,parentIndex:string|number,path:(string|number)[]){
if (!Array.isArray(data)) throw new api.ODSystemError("OT CLI => Property is not of the type 'array'. Please check your config for possible errors. (index: "+parentIndex+", path: "+path.join(".")+")")
renderHeader(path)
terminal(ansis.bold.green("Please select what you would like to do.\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
if (!structure.options.propertyChecker) return await backFn()
if (structure.options.cliDisplayName || typeof parentIndex == "string" || !isNaN(parentIndex)){
terminal.gray("\nProperty: "+ansis.bold.blue(structure.options.cliDisplayName ?? parentIndex.toString())+"\n")
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
}
const propertyName = structure.options.cliDisplayPropertyName ?? "index"
const answer = await terminal.singleColumnMenu(data.length < 1 ? ["Add "+propertyName] : [
"Add "+propertyName,
"Edit "+propertyName,
"Move "+propertyName,
"Remove "+propertyName,
"Duplicate "+propertyName
],{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
const backFnFunc = async () => {await renderConfigArrayStructureSelector(checker,backFn,structure,data,parent,parentIndex,path)}
if (answer.canceled) return await backFn()
if (answer.selectedIndex == 0) await chooseAdditionConfigStructure(checker,backFnFunc,async (newData) => {
data[data.length] = newData
await checker.config.save()
await backFnFunc()
},structure.options.propertyChecker,data,data.length,path,[])
else if (answer.selectedIndex == 1) await renderConfigArrayStructureEditSelector(checker,backFnFunc,structure,structure.options.propertyChecker,data,parent,parentIndex,path)
else if (answer.selectedIndex == 2) await renderconfigArrayStructureMoveSelector(checker,backFnFunc,structure,structure.options.propertyChecker,data,parent,parentIndex,path)
else if (answer.selectedIndex == 3) await renderconfigArrayStructureRemoveSelector(checker,backFnFunc,structure,structure.options.propertyChecker,data,parent,parentIndex,path)
else if (answer.selectedIndex == 4) await renderConfigArrayStructureDuplicateSelector(checker,backFnFunc,structure,structure.options.propertyChecker,data,parent,parentIndex,path)
}
async function renderConfigArrayStructureEditSelector(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),arrayStructure:api.ODCheckerArrayStructure,structure:api.ODCheckerStructure,data:any[],parent:object,parentIndex:string|number,path:(string|number)[]){
const propertyName = arrayStructure.options.cliDisplayPropertyName ?? "index"
renderHeader(path)
terminal(ansis.bold.green("Please select the "+propertyName+" you would like to edit.\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
const longestDataListName = Math.max(...data.map((d,i) => getArrayPreviewStructureNameLength(structure,d,data,i)))
const dataList = data.map((d,i) => (i+1)+". "+getArrayPreviewFromStructure(structure,d,data,i,longestDataListName))
const dataAnswer = await terminal.singleColumnMenu(dataList,{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (dataAnswer.canceled) return await backFn()
const subData = data[dataAnswer.selectedIndex]
await chooseConfigStructure(checker,async () => {await renderConfigArrayStructureEditSelector(checker,backFn,arrayStructure,structure,data,parent,parentIndex,path)},structure,subData,data,dataAnswer.selectedIndex,[...path,dataAnswer.selectedIndex])
}
async function renderconfigArrayStructureMoveSelector(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),arrayStructure:api.ODCheckerArrayStructure,structure:api.ODCheckerStructure,data:any[],parent:object,parentIndex:string|number,path:(string|number)[]){
const propertyName = arrayStructure.options.cliDisplayPropertyName ?? "index"
renderHeader(path)
terminal(ansis.bold.green("Please select the "+propertyName+" you would like to move.\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
const longestDataListName = Math.max(...data.map((d,i) => getArrayPreviewStructureNameLength(structure,d,data,i)))
const dataList = data.map((d,i) => (i+1)+". "+getArrayPreviewFromStructure(structure,d,data,i,longestDataListName))
const dataAnswer = await terminal.singleColumnMenu(dataList,{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (dataAnswer.canceled) return await backFn()
renderHeader([...path,dataAnswer.selectedIndex])
terminal(ansis.bold.green("Please select the position you would like to move to.\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
const moveAnswer = await terminal.singleColumnMenu(data.map((d,i) => "Position "+(i+1)),{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (moveAnswer.canceled) return await renderconfigArrayStructureMoveSelector(checker,backFn,arrayStructure,structure,data,parent,parentIndex,path)
const subData = data[dataAnswer.selectedIndex]
const slicedData = [...data.slice(0,dataAnswer.selectedIndex),...data.slice(dataAnswer.selectedIndex+1)]
const insertedData = [...slicedData.slice(0,moveAnswer.selectedIndex),subData,...slicedData.slice(moveAnswer.selectedIndex)]
insertedData.forEach((d,i) => data[i] = d)
await checker.config.save()
terminal.bold.blue("\n\n✅ Property moved succesfully!")
await utilities.timer(400)
await backFn()
}
async function renderconfigArrayStructureRemoveSelector(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),arrayStructure:api.ODCheckerArrayStructure,structure:api.ODCheckerStructure,data:any[],parent:object,parentIndex:string|number,path:(string|number)[]){
const propertyName = arrayStructure.options.cliDisplayPropertyName ?? "index"
renderHeader(path)
terminal(ansis.bold.green("Please select the "+propertyName+" you would like to delete.\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
const longestDataListName = Math.max(...data.map((d,i) => getArrayPreviewStructureNameLength(structure,d,data,i)))
const dataList = data.map((d,i) => (i+1)+". "+getArrayPreviewFromStructure(structure,d,data,i,longestDataListName))
const dataAnswer = await terminal.singleColumnMenu(dataList,{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (dataAnswer.canceled) return await backFn()
data.splice(dataAnswer.selectedIndex,1)
await checker.config.save()
terminal.bold.blue("\n\n✅ Property deleted succesfully!")
await utilities.timer(400)
await backFn()
}
async function renderConfigArrayStructureDuplicateSelector(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),arrayStructure:api.ODCheckerArrayStructure,structure:api.ODCheckerStructure,data:any[],parent:object,parentIndex:string|number,path:(string|number)[]){
const propertyName = arrayStructure.options.cliDisplayPropertyName ?? "index"
renderHeader(path)
terminal(ansis.bold.green("Please select the "+propertyName+" you would like to duplicate.\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
const longestDataListName = Math.max(...data.map((d,i) => getArrayPreviewStructureNameLength(structure,d,data,i)))
const dataList = data.map((d,i) => (i+1)+". "+getArrayPreviewFromStructure(structure,d,data,i,longestDataListName))
const dataAnswer = await terminal.singleColumnMenu(dataList,{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (dataAnswer.canceled) return await backFn()
data.push(JSON.parse(JSON.stringify(data[dataAnswer.selectedIndex])))
await checker.config.save()
terminal.bold.blue("\n\n✅ Property duplicated succesfully!")
await utilities.timer(400)
await backFn()
}
async function renderConfigBooleanStructureEditor(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),structure:api.ODCheckerBooleanStructure,data:boolean,parent:object,parentIndex:string|number,path:(string|number)[]){
if (typeof data != "boolean") throw new api.ODSystemError("OT CLI => Property is not of the type 'boolean'. Please check your config for possible errors. (index: "+parentIndex+", path: "+path.join(".")+")")
renderHeader(path)
terminal(ansis.bold.green("You are now editing "+(typeof parentIndex == "string" ? "the boolean property "+ansis.blue("\""+parentIndex+"\"") : "boolean property "+ansis.blue("#"+(parentIndex+1)))+".\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
terminal.gray("\nCurrent value: "+ansis.bold[data ? "green" : "red"](data.toString())+"\n")
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
const answer = await terminal.singleColumnMenu(["false (Disabled)","true (Enabled)"],{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (answer.canceled) return await backFn()
//run config checker
const newValue = (answer.selectedIndex == 0) ? false : true
const newPath = [...path]
newPath.shift()
checker.messages = [] //manually clear previous messages
const isDataValid = structure.check(checker,newValue,newPath)
if (isDataValid){
parent[parentIndex] = newValue
await checker.config.save()
terminal.bold.blue("\n\n✅ Variable saved succesfully!")
await utilities.timer(400)
await backFn()
}else{
const messages = checker.messages.map((msg) => "=> ["+msg.type.toUpperCase()+"] "+msg.message).join("\n")
terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!")
terminal.gray("\n"+messages)
await utilities.timer(1000+(2000*checker.messages.length))
await renderConfigBooleanStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)
}
}
async function renderConfigNumberStructureEditor(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),structure:api.ODCheckerNumberStructure,data:number,parent:object,parentIndex:string|number,path:(string|number)[],prefillValue?:string){
if (typeof data != "number") throw new api.ODSystemError("OT CLI => Property is not of the type 'number'. Please check your config for possible errors. (index: "+parentIndex+", path: "+path.join(".")+")")
renderHeader(path)
terminal(ansis.bold.green("You are now editing "+(typeof parentIndex == "string" ? "the number property "+ansis.blue("\""+parentIndex+"\"") : "number property "+ansis.blue("#"+(parentIndex+1)))+".\n")+ansis.italic.gray("(insert a new value and press enter, go back using escape)\n"))
terminal.gray("\nCurrent value: "+ansis.bold.blue(data.toString())+"\n")
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
const answer = await terminal.inputField({
default:prefillValue,
style:terminal.cyan,
cancelable:true
}).promise
if (typeof answer != "string") return await backFn()
//run config checker
const newValue = Number(answer.replaceAll(",","."))
const newPath = [...path]
newPath.shift()
checker.messages = [] //manually clear previous messages
const isDataValid = structure.check(checker,newValue,newPath)
if (isDataValid){
parent[parentIndex] = newValue
await checker.config.save()
terminal.bold.blue("\n\n✅ Variable saved succesfully!")
await utilities.timer(400)
await backFn()
}else{
const messages = checker.messages.map((msg) => "=> ["+msg.type.toUpperCase()+"] "+msg.message).join("\n")
terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!")
terminal.red("\n"+messages)
await utilities.timer(1000+(2000*checker.messages.length))
await renderConfigNumberStructureEditor(checker,backFn,structure,data,parent,parentIndex,path,answer)
}
}
async function renderConfigStringStructureEditor(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),structure:api.ODCheckerStringStructure,data:string,parent:object,parentIndex:string|number,path:(string|number)[],prefillValue?:string){
if (typeof data != "string") throw new api.ODSystemError("OT CLI => Property is not of the type 'string'. Please check your config for possible errors. (index: "+parentIndex+", path: "+path.join(".")+")")
renderHeader(path)
terminal(ansis.bold.green("You are now editing "+(typeof parentIndex == "string" ? "the string property "+ansis.blue("\""+parentIndex+"\"") : "string property "+ansis.blue("#"+(parentIndex+1)))+".\n")+ansis.italic.gray("(insert a new value and press enter, go back using escape)\n"))
terminal.gray("\nCurrent value:"+(data.includes("\n") ? "\n" : " \"")+ansis.bold.blue(data)+ansis.gray(!data.includes("\n") ? "\"\n" : "\n"))
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
const customExtraOptions = (structure instanceof api.ODCheckerCustomStructure_DiscordId) ? structure.extraOptions : undefined
const customAutocompleteFunc = structure.options.cliAutocompleteFunc ? await structure.options.cliAutocompleteFunc() : null
const autocompleteList = ((customAutocompleteFunc ?? structure.options.cliAutocompleteList) ?? customExtraOptions) ?? structure.options.choices
const autoCompleteMenuOpts: Terminal.SingleLineMenuOptions = {
style:terminal.white,
selectedStyle:terminal.bgBlue.white
}
const input = terminal.inputField({
default:prefillValue,
style:terminal.cyan,
hintStyle:terminal.gray,
cancelable:false,
autoComplete:autocompleteList,
autoCompleteHint:(!!autocompleteList),
autoCompleteMenu:(autocompleteList) ? autoCompleteMenuOpts as Terminal.Autocompletion : false
})
terminal.on("key",async (name:string,matches:string[],data:object) => {
if (name == "ESCAPE"){
terminal.removeListener("key","cli-render-string-structure-edit")
input.abort()
await backFn()
}
},({id:"cli-render-string-structure-edit"} as any))
const answer = await input.promise
terminal.removeListener("key","cli-render-string-structure-edit")
if (typeof answer != "string") return
//run config checker
const newValue = answer.replaceAll("\\n","\n")
const newPath = [...path]
newPath.shift()
checker.messages = [] //manually clear previous messages
const isDataValid = structure.check(checker,newValue,newPath)
if (isDataValid){
parent[parentIndex] = newValue
await checker.config.save()
terminal.bold.blue("\n\n✅ Variable saved succesfully!")
await utilities.timer(400)
await backFn()
}else{
const messages = checker.messages.map((msg) => "=> ["+msg.type.toUpperCase()+"] "+msg.message).join("\n")
terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!")
terminal.red("\n"+messages)
await utilities.timer(1000+(2000*checker.messages.length))
await renderConfigStringStructureEditor(checker,backFn,structure,data,parent,parentIndex,path,answer)
}
}
async function renderConfigNullStructureEditor(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),structure:api.ODCheckerNullStructure,data:null,parent:object,parentIndex:string|number,path:(string|number)[]){
if (data !== null) throw new api.ODSystemError("OT CLI => Property is not of the type 'null'. Please check your config for possible errors. (index: "+parentIndex+", path: "+path.join(".")+")")
renderHeader(path)
terminal(ansis.bold.green("You are now editing "+(typeof parentIndex == "string" ? "the null property "+ansis.blue("\""+parentIndex+"\"") : "null property "+ansis.blue("#"+(parentIndex+1)))+".\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
terminal.gray("\nCurrent value: "+ansis.bold.blue("null")+"\n")
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
const answer = await terminal.singleColumnMenu(["null"],{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (answer.canceled) return await backFn()
//run config checker
const newValue = null
const newPath = [...path]
newPath.shift()
checker.messages = [] //manually clear previous messages
const isDataValid = structure.check(checker,newValue,newPath)
if (isDataValid){
parent[parentIndex] = newValue
await checker.config.save()
terminal.bold.blue("\n\n✅ Variable saved succesfully!")
await utilities.timer(400)
await backFn()
}else{
const messages = checker.messages.map((msg) => "=> ["+msg.type.toUpperCase()+"] "+msg.message).join("\n")
terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!")
terminal.red("\n"+messages)
await utilities.timer(1000+(2000*checker.messages.length))
await renderConfigNullStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)
}
}
async function renderConfigTypeSwitchStructureEditor(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),structure:api.ODCheckerTypeSwitchStructure,data:any,parent:object,parentIndex:string|number,path:(string|number)[]){
renderHeader(path)
terminal(ansis.bold.green("You are now editing "+(typeof parentIndex == "string" ? "the property "+ansis.blue("\""+parentIndex+"\"") : "property "+ansis.blue("#"+(parentIndex+1)))+".\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
terminal.gray("\nCurrent value: "+ansis.bold.blue(data.toString())+"\n")
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
const actionsList: string[] = []
if (structure.options.boolean) actionsList.push("Edit as boolean")
if (structure.options.string) actionsList.push("Edit as string")
if (structure.options.number) actionsList.push("Edit as number")
if (structure.options.object) actionsList.push("Edit as object")
if (structure.options.array) actionsList.push("Edit as array/list")
if (structure.options.null) actionsList.push("Edit as null")
const answer = await terminal.singleColumnMenu(actionsList,{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (answer.canceled) return await backFn()
//run selected structure editor (untested)
if (answer.selectedText.startsWith("Edit as boolean") && structure.options.boolean) await renderConfigBooleanStructureEditor(checker,async () => {await renderConfigTypeSwitchStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)},structure.options.boolean,false,parent,parentIndex,path)
else if (answer.selectedText.startsWith("Edit as string") && structure.options.string) await renderConfigStringStructureEditor(checker,async () => {await renderConfigTypeSwitchStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)},structure.options.string,data.toString(),parent,parentIndex,path)
else if (answer.selectedText.startsWith("Edit as number") && structure.options.number) await renderConfigNumberStructureEditor(checker,async () => {await renderConfigTypeSwitchStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)},structure.options.number,0,parent,parentIndex,path)
else if (answer.selectedText.startsWith("Edit as object") && structure.options.object) await renderConfigObjectStructureSelector(checker,async () => {await renderConfigTypeSwitchStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)},structure.options.object,data,parent,parentIndex,path)
else if (answer.selectedText.startsWith("Edit as array/list") && structure.options.array) await renderConfigArrayStructureSelector(checker,async () => {await renderConfigTypeSwitchStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)},structure.options.array,data,parent,parentIndex,path)
else if (answer.selectedText.startsWith("Edit as null") && structure.options.null) await renderConfigNullStructureEditor(checker,async () => {await renderConfigTypeSwitchStructureEditor(checker,backFn,structure,data,parent,parentIndex,path)},structure.options.null,null,parent,parentIndex,path)
}
function getArrayPreviewStructureNameLength(structure:api.ODCheckerStructure,data:api.ODValidJsonType,parent:object,parentIndex:string|number): number {
if (structure instanceof api.ODCheckerBooleanStructure && typeof data == "boolean") return data.toString().length
else if (structure instanceof api.ODCheckerNumberStructure && typeof data == "number") return data.toString().length
else if (structure instanceof api.ODCheckerStringStructure && typeof data == "string") return data.length
else if (structure instanceof api.ODCheckerNullStructure && data === null) return "Null".length
else if (structure instanceof api.ODCheckerArrayStructure && Array.isArray(data)) return "Array".length
else if (structure instanceof api.ODCheckerObjectStructure && typeof data == "object" && !Array.isArray(data) && data){
if (!structure.options.cliDisplayKeyInParentArray) return "Object".length
else return data[structure.options.cliDisplayKeyInParentArray].toString().length
}else if (structure instanceof api.ODCheckerEnabledObjectStructure && typeof data == "object" && !Array.isArray(data) && data){
const subStructure = structure.options.checker
if (!subStructure) return "<unknown-property>".length
return getArrayPreviewStructureNameLength(subStructure,data,parent,parentIndex)
}else if (structure instanceof api.ODCheckerObjectSwitchStructure && typeof data == "object" && !Array.isArray(data) && data){
for (const objectTemplate of (structure.options.objects ?? [])){
if (objectTemplate.properties.every((prop) => data[prop.key] === prop.value)){
//object template matches data
const subStructure = objectTemplate.checker
return getArrayPreviewStructureNameLength(subStructure,data,parent,parentIndex)
}
}
return "<unknown-property>".length
}else if (structure instanceof api.ODCheckerTypeSwitchStructure){
if (typeof data == "boolean" && structure.options.boolean) return getArrayPreviewStructureNameLength(structure.options.boolean,data,parent,parentIndex)
else if (typeof data == "number" && structure.options.number) return getArrayPreviewStructureNameLength(structure.options.number,data,parent,parentIndex)
else if (typeof data == "string" && structure.options.string) return getArrayPreviewStructureNameLength(structure.options.string,data,parent,parentIndex)
else if (typeof data == "object" && !Array.isArray(data) && data && structure.options.object) return getArrayPreviewStructureNameLength(structure.options.object,data,parent,parentIndex)
else if (Array.isArray(data) && structure.options.array) return getArrayPreviewStructureNameLength(structure.options.array,data,parent,parentIndex)
else if (data === null && structure.options.null) return getArrayPreviewStructureNameLength(structure.options.null,data,parent,parentIndex)
else return "<unknown-property>".length
}else return "<unknown-property>".length
}
function getArrayPreviewFromStructure(structure:api.ODCheckerStructure,data:api.ODValidJsonType,parent:object,parentIndex:string|number,nameLength:number): string {
if (structure instanceof api.ODCheckerBooleanStructure && typeof data == "boolean") return data.toString()
else if (structure instanceof api.ODCheckerNumberStructure && typeof data == "number") return data.toString()
else if (structure instanceof api.ODCheckerStringStructure && typeof data == "string") return data
else if (structure instanceof api.ODCheckerNullStructure && data === null) return "Null"
else if (structure instanceof api.ODCheckerArrayStructure && Array.isArray(data)) return "Array"
else if (structure instanceof api.ODCheckerObjectStructure && typeof data == "object" && !Array.isArray(data) && data){
const additionalKeys = (structure.options.cliDisplayAdditionalKeysInParentArray ?? []).map((key) => key+": "+data[key].toString()).join(", ")
if (!structure.options.cliDisplayKeyInParentArray) return "Object"
else return data[structure.options.cliDisplayKeyInParentArray].toString().padEnd(nameLength+5," ")+ansis.gray(additionalKeys.length > 0 ? "("+additionalKeys+")" : "")
}else if (structure instanceof api.ODCheckerEnabledObjectStructure && typeof data == "object" && !Array.isArray(data) && data){
const subStructure = structure.options.checker
if (!subStructure) return "<unknown-property>"
return getArrayPreviewFromStructure(subStructure,data,parent,parentIndex,nameLength)
}else if (structure instanceof api.ODCheckerObjectSwitchStructure && typeof data == "object" && !Array.isArray(data) && data){
for (const objectTemplate of (structure.options.objects ?? [])){
if (objectTemplate.properties.every((prop) => data[prop.key] === prop.value)){
//object template matches data
const subStructure = objectTemplate.checker
return getArrayPreviewFromStructure(subStructure,data,parent,parentIndex,nameLength)
}
}
return "<unknown-property>"
}else if (structure instanceof api.ODCheckerTypeSwitchStructure){
if (typeof data == "boolean" && structure.options.boolean) return getArrayPreviewFromStructure(structure.options.boolean,data,parent,parentIndex,nameLength)
else if (typeof data == "number" && structure.options.number) return getArrayPreviewFromStructure(structure.options.number,data,parent,parentIndex,nameLength)
else if (typeof data == "string" && structure.options.string) return getArrayPreviewFromStructure(structure.options.string,data,parent,parentIndex,nameLength)
else if (typeof data == "object" && !Array.isArray(data) && data && structure.options.object) return getArrayPreviewFromStructure(structure.options.object,data,parent,parentIndex,nameLength)
else if (Array.isArray(data) && structure.options.array) return getArrayPreviewFromStructure(structure.options.array,data,parent,parentIndex,nameLength)
else if (data === null && structure.options.null) return getArrayPreviewFromStructure(structure.options.null,data,parent,parentIndex,nameLength)
else return "<unknown-property>"
}else return "<unknown-property>"
}
async function chooseAdditionConfigStructure(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),nextFn:((data:any) => api.ODPromiseVoid),structure:api.ODCheckerStructure,parent:object|any[],parentIndex:string|number,path:(string|number)[],localPath:(string|number)[]){
if (structure instanceof api.ODCheckerObjectStructure) await renderAdditionConfigObjectStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)
else if (structure instanceof api.ODCheckerBooleanStructure) await renderAdditionConfigBooleanStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)
else if (structure instanceof api.ODCheckerNumberStructure) await renderAdditionConfigNumberStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)
else if (structure instanceof api.ODCheckerStringStructure) await renderAdditionConfigStringStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)
else if (structure instanceof api.ODCheckerNullStructure) await renderAdditionConfigNullStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)
else if (structure instanceof api.ODCheckerEnabledObjectStructure) await renderAdditionConfigEnabledObjectStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)
else if (structure instanceof api.ODCheckerObjectSwitchStructure) await renderAdditionConfigObjectSwitchStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)
else if (structure instanceof api.ODCheckerArrayStructure) await renderAdditionConfigArrayStructureSelector(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)
else if (structure instanceof api.ODCheckerTypeSwitchStructure) await renderAdditionConfigTypeSwitchStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)
else await backFn()
}
async function renderAdditionConfigObjectStructure(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),nextFn:((data:any) => api.ODPromiseVoid),structure:api.ODCheckerObjectStructure,parent:object|any[],parentIndex:string|number,path:(string|number)[],localPath:(string|number)[],localData:object={}){
const children = structure.options.children ?? []
const skipKeys = (structure.options.cliInitSkipKeys ?? [])
//add skipped properties
for (const key of skipKeys){
const childStructure = children.find((c) => c.key == key)
if (childStructure){
const defaultValue = childStructure.checker.options.cliInitDefaultValue
if (childStructure.checker instanceof api.ODCheckerBooleanStructure) localData[key] = (typeof defaultValue == "boolean" ? defaultValue : false)
else if (childStructure.checker instanceof api.ODCheckerNumberStructure) localData[key] = (typeof defaultValue == "number" ? defaultValue : 0)
else if (childStructure.checker instanceof api.ODCheckerStringStructure) localData[key] = (typeof defaultValue == "string" ? defaultValue : "")
else if (childStructure.checker instanceof api.ODCheckerNullStructure) localData[key] = (defaultValue === null ? defaultValue : null)
else if (childStructure.checker instanceof api.ODCheckerArrayStructure) localData[key] = (Array.isArray(defaultValue) ? JSON.parse(JSON.stringify(defaultValue)) : [])
else if (childStructure.checker instanceof api.ODCheckerObjectStructure) localData[key] = ((typeof defaultValue == "object" && !Array.isArray(defaultValue) && defaultValue) ? JSON.parse(JSON.stringify(defaultValue)) : {})
else if (childStructure.checker instanceof api.ODCheckerObjectSwitchStructure) localData[key] = ((typeof defaultValue == "object" && !Array.isArray(defaultValue) && defaultValue) ? JSON.parse(JSON.stringify(defaultValue)) : {})
else if (childStructure.checker instanceof api.ODCheckerEnabledObjectStructure) localData[key] = ((typeof defaultValue == "object" && !Array.isArray(defaultValue) && defaultValue) ? JSON.parse(JSON.stringify(defaultValue)) : {})
else if (childStructure.checker instanceof api.ODCheckerTypeSwitchStructure && typeof defaultValue != "undefined") localData[key] = JSON.parse(JSON.stringify(defaultValue))
else throw new api.ODSystemError("OT CLI => Object skip key has an invalid checker structure! key: "+key)
}
}
//add properties that need to be configured
const configChildren = children.filter((c) => !skipKeys.includes(c.key)).map((c) => {return {key:c.key,checker:c.checker}})
await configureAdditionObjectProperties(checker,configChildren,0,localData,[...path,parentIndex],(typeof parentIndex == "number") ? [...localPath] : [...localPath,parentIndex],async () => {
//go back to previous screen
await backFn()
},async () => {
//finish setup
terminal.bold.blue("\n\n✅ Variable saved succesfully!")
await utilities.timer(400)
await nextFn(localData)
})
}
async function configureAdditionObjectProperties(checker:api.ODChecker,children:{key:string,checker:api.ODCheckerStructure}[],currentIndex:number,localData:object,path:(string|number)[],localPath:(string|number)[],backFn:(() => api.ODPromiseVoid),nextFn:(() => api.ODPromiseVoid)){
if (children.length < 1) return await nextFn()
const child = children[currentIndex]
await chooseAdditionConfigStructure(checker,async () => {
if (children[currentIndex-1]) await configureAdditionObjectProperties(checker,children,currentIndex-1,localData,path,localPath,backFn,nextFn)
else await backFn()
},async (data) => {
localData[child.key] = data
if (children[currentIndex+1]) await configureAdditionObjectProperties(checker,children,currentIndex+1,localData,path,localPath,backFn,nextFn)
else await nextFn()
},child.checker,localData,child.key,path,localPath)
}
async function renderAdditionConfigEnabledObjectStructure(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),nextFn:((data:any) => api.ODPromiseVoid),structure:api.ODCheckerEnabledObjectStructure,parent:object|any[],parentIndex:string|number,path:(string|number)[],localPath:(string|number)[]){
const enabledProperty = structure.options.property
const enabledValue = structure.options.enabledValue
const subStructure = structure.options.checker
if (!enabledProperty || !subStructure || !subStructure.options.children) return await backFn()
let propertyStructure: api.ODCheckerBooleanStructure|api.ODCheckerNumberStructure|api.ODCheckerStringStructure
if (typeof enabledValue == "string") propertyStructure = new api.ODCheckerStringStructure("opendiscord:CLI-checker-enabled-object-structure",{})
else if (typeof enabledValue == "number") propertyStructure = new api.ODCheckerNumberStructure("opendiscord:CLI-checker-enabled-object-structure",{})
else if (typeof enabledValue == "boolean") propertyStructure = new api.ODCheckerBooleanStructure("opendiscord:CLI-checker-enabled-object-structure",{})
else throw new Error("OT CLI => enabled object structure has an invalid type of enabledProperty. It must be a primitive boolean/number/string.")
const localData = {}
await chooseAdditionConfigStructure(checker,backFn,async (data) => {
if (data === enabledValue) await renderAdditionConfigObjectStructure(checker,async () => {await renderAdditionConfigEnabledObjectStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)},nextFn,subStructure,parent,parentIndex,path,localPath,localData)
else{
localData[enabledProperty] = data
//copy old object checker to new object checker => all options get de-referenced (this is needed for the new object skip keys are temporary)
const newStructure = new api.ODCheckerObjectStructure(subStructure.id,{children:[]})
//copy all options over to the new checker
newStructure.options.children = [...subStructure.options.children]
newStructure.options.cliInitSkipKeys = subStructure.options.children.map((child) => child.key)
for (const key of Object.keys(subStructure.options)){
if (key != "children" && key != "cliInitSkipKeys") newStructure.options[key] = subStructure.options[key]
}
//adds all properties to object as "skipKeys", then continues to next function
await renderAdditionConfigObjectStructure(checker,async () => {await renderAdditionConfigEnabledObjectStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)},nextFn,newStructure,parent,parentIndex,path,localPath,localData)
await nextFn(localData)
}
},propertyStructure,localData,enabledProperty,[...path,parentIndex],[...localPath,parentIndex])
}
async function renderAdditionConfigObjectSwitchStructure(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),nextFn:((data:any) => api.ODPromiseVoid),structure:api.ODCheckerObjectSwitchStructure,parent:object|any[],parentIndex:string|number,path:(string|number)[],localPath:(string|number)[]){
renderHeader([...path,parentIndex])
terminal(ansis.bold.green("What type of object would you like to add?\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
const answer = await terminal.singleColumnMenu(structure.options.objects.map((obj) => obj.name),{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (answer.canceled) return await backFn()
const objectTemplate = structure.options.objects[answer.selectedIndex]
//copy old object checker to new object checker => all options get de-referenced (this is needed for the new object switch properties which are temporary)
const oldStructure = objectTemplate.checker
const newStructure = new api.ODCheckerObjectStructure(oldStructure.id,{children:[]})
//copy all options over to the new checker
newStructure.options.children = [...oldStructure.options.children]
newStructure.options.cliInitSkipKeys = [...(oldStructure.options.cliInitSkipKeys ?? [])]
for (const key of Object.keys(oldStructure.options)){
if (key != "children" && key != "cliInitSkipKeys") newStructure.options[key] = oldStructure.options[key]
}
//add the keys of the object switch properties to the 'cliInitSkipKeys' because they need to be skipped.
objectTemplate.properties.map((p) => p.key).forEach((p) => {
if (!newStructure.options.cliInitSkipKeys) newStructure.options.cliInitSkipKeys = [p]
else if (!newStructure.options.cliInitSkipKeys.includes(p)) newStructure.options.cliInitSkipKeys.push(p)
})
//add structure checkers for all properties
for (const prop of objectTemplate.properties){
if (!newStructure.options.children.find((child) => child.key === prop.key)){
if (typeof prop.value == "string") newStructure.options.children.unshift({key:prop.key,optional:false,priority:1,checker:new api.ODCheckerStringStructure("opendiscord:CLI-checker-object-switch-structure",{cliInitDefaultValue:prop.value})})
else if (typeof prop.value == "number") newStructure.options.children.unshift({key:prop.key,optional:false,priority:1,checker:new api.ODCheckerNumberStructure("opendiscord:CLI-checker-object-switch-structure",{cliInitDefaultValue:prop.value})})
else if (typeof prop.value == "boolean") newStructure.options.children.unshift({key:prop.key,optional:false,priority:1,checker:new api.ODCheckerBooleanStructure("opendiscord:CLI-checker-object-switch-structure",{cliInitDefaultValue:prop.value})})
}
}
await chooseAdditionConfigStructure(checker,backFn,nextFn,newStructure,parent,parentIndex,path,localPath)
}
async function renderAdditionConfigBooleanStructure(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),nextFn:((data:any) => api.ODPromiseVoid),structure:api.ODCheckerBooleanStructure,parent:object|any[],parentIndex:string|number,path:(string|number)[],localPath:(string|number)[]){
renderHeader([...path,parentIndex])
terminal(ansis.bold.green("You are now creating "+(typeof parentIndex == "string" ? "the boolean property "+ansis.blue("\""+parentIndex+"\"") : "boolean property "+ansis.blue("#"+(parentIndex+1)))+".\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
terminal.gray("\nProperty: "+ansis.bold.blue(structure.options.cliDisplayName ?? [...localPath,parentIndex].join("."))+"\n")
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
const answer = await terminal.singleColumnMenu(["false (Disabled)","true (Enabled)"],{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (answer.canceled) return await backFn()
//run config checker
const newValue = (answer.selectedIndex == 0) ? false : true
const newPath = [...path]
newPath.shift()
checker.messages = [] //manually clear previous messages
const isDataValid = structure.check(checker,newValue,newPath)
if (isDataValid){
terminal.bold.blue("\n\n✅ Variable saved succesfully!")
await utilities.timer(400)
await nextFn(newValue)
}else{
const messages = checker.messages.map((msg) => "=> ["+msg.type.toUpperCase()+"] "+msg.message).join("\n")
terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!")
terminal.gray("\n"+messages)
await utilities.timer(1000+(2000*checker.messages.length))
await renderAdditionConfigBooleanStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)
}
}
async function renderAdditionConfigNumberStructure(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),nextFn:((data:any) => api.ODPromiseVoid),structure:api.ODCheckerNumberStructure,parent:object|any[],parentIndex:string|number,path:(string|number)[],localPath:(string|number)[],prefillValue?:string){
renderHeader([...path,parentIndex])
terminal(ansis.bold.green("You are now creating "+(typeof parentIndex == "string" ? "the number property "+ansis.blue("\""+parentIndex+"\"") : "number property "+ansis.blue("#"+(parentIndex+1)))+".\n")+ansis.italic.gray("(insert a new value and press enter, go back using escape)\n"))
terminal.gray("\nProperty: "+ansis.bold.blue(structure.options.cliDisplayName ?? [...localPath,parentIndex].join("."))+"\n")
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
const answer = await terminal.inputField({
default:prefillValue,
style:terminal.cyan,
cancelable:true
}).promise
if (typeof answer != "string") return await backFn()
//run config checker
const newValue = Number(answer.replaceAll(",","."))
const newPath = [...path]
newPath.shift()
checker.messages = [] //manually clear previous messages
const isDataValid = structure.check(checker,newValue,newPath)
if (isDataValid){
terminal.bold.blue("\n\n✅ Variable saved succesfully!")
await utilities.timer(400)
await nextFn(newValue)
}else{
const messages = checker.messages.map((msg) => "=> ["+msg.type.toUpperCase()+"] "+msg.message).join("\n")
terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!")
terminal.red("\n"+messages)
await utilities.timer(1000+(2000*checker.messages.length))
await renderAdditionConfigNumberStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath,answer)
}
}
async function renderAdditionConfigStringStructure(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),nextFn:((data:any) => api.ODPromiseVoid),structure:api.ODCheckerStringStructure,parent:object|any[],parentIndex:string|number,path:(string|number)[],localPath:(string|number)[],prefillValue?:string){
renderHeader([...path,parentIndex])
terminal(ansis.bold.green("You are now creating "+(typeof parentIndex == "string" ? "the string property "+ansis.blue("\""+parentIndex+"\"") : "string property "+ansis.blue("#"+(parentIndex+1)))+".\n")+ansis.italic.gray("(insert a new value and press enter, go back using escape)\n"))
terminal.gray("\nProperty: "+ansis.bold.blue(structure.options.cliDisplayName ?? [...localPath,parentIndex].join("."))+"\n")
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
const customExtraOptions = (structure instanceof api.ODCheckerCustomStructure_DiscordId) ? structure.extraOptions : undefined
const customAutocompleteFunc = structure.options.cliAutocompleteFunc ? await structure.options.cliAutocompleteFunc() : null
const autocompleteList = ((customAutocompleteFunc ?? structure.options.cliAutocompleteList) ?? customExtraOptions) ?? structure.options.choices
const autoCompleteMenuOpts: Terminal.SingleLineMenuOptions = {
style:terminal.white,
selectedStyle:terminal.bgBlue.white
}
const input = terminal.inputField({
default:prefillValue,
style:terminal.cyan,
hintStyle:terminal.gray,
cancelable:false,
autoComplete:autocompleteList,
autoCompleteHint:(!!autocompleteList),
autoCompleteMenu:(autocompleteList) ? autoCompleteMenuOpts as Terminal.Autocompletion : false
})
terminal.on("key",async (name:string,matches:string[],data:object) => {
if (name == "ESCAPE"){
terminal.removeListener("key","cli-render-string-structure-add")
input.abort()
await backFn()
}
},({id:"cli-render-string-structure-add"} as any))
const answer = await input.promise
terminal.removeListener("key","cli-render-string-structure-add")
if (typeof answer != "string") return
//run config checker
const newValue = answer.replaceAll("\\n","\n")
const newPath = [...path]
newPath.shift()
checker.messages = [] //manually clear previous messages
const isDataValid = structure.check(checker,newValue,newPath)
if (isDataValid){
terminal.bold.blue("\n\n✅ Variable saved succesfully!")
await utilities.timer(400)
await nextFn(newValue)
}else{
const messages = checker.messages.map((msg) => "=> ["+msg.type.toUpperCase()+"] "+msg.message).join("\n")
terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!")
terminal.red("\n"+messages)
await utilities.timer(1000+(2000*checker.messages.length))
await renderAdditionConfigStringStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath,answer)
}
}
async function renderAdditionConfigNullStructure(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),nextFn:((data:any) => api.ODPromiseVoid),structure:api.ODCheckerNullStructure,parent:object|any[],parentIndex:string|number,path:(string|number)[],localPath:(string|number)[]){
renderHeader([...path,parentIndex])
terminal(ansis.bold.green("You are now creating "+(typeof parentIndex == "string" ? "the null property "+ansis.blue("\""+parentIndex+"\"") : "null property "+ansis.blue("#"+(parentIndex+1)))+".\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
terminal.gray("\nProperty: "+ansis.bold.blue(structure.options.cliDisplayName ?? [...localPath,parentIndex].join("."))+"\n")
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
const answer = await terminal.singleColumnMenu(["null"],{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (answer.canceled) return await backFn()
//run config checker
const newValue = null
const newPath = [...path]
newPath.shift()
checker.messages = [] //manually clear previous messages
const isDataValid = structure.check(checker,newValue,newPath)
if (isDataValid){
terminal.bold.blue("\n\n✅ Variable saved succesfully!")
await utilities.timer(400)
await nextFn(newValue)
}else{
const messages = checker.messages.map((msg) => "=> ["+msg.type.toUpperCase()+"] "+msg.message).join("\n")
terminal.bold.blue("\n\n❌ Variable is invalid! Please try again!")
terminal.red("\n"+messages)
await utilities.timer(1000+(2000*checker.messages.length))
await renderAdditionConfigNullStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)
}
}
async function renderAdditionConfigArrayStructureSelector(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),nextFn:((data:any) => api.ODPromiseVoid),structure:api.ODCheckerArrayStructure,parent:object|any[],parentIndex:string|number,path:(string|number)[],localPath:(string|number)[],localData:any[]=[]){
renderHeader([...path,parentIndex])
terminal(ansis.bold.green("Please select what you would like to do with the new array.\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
if (!structure.options.propertyChecker) return await backFn()
terminal.gray("\nProperty: "+ansis.bold.blue(structure.options.cliDisplayName ?? [...localPath,parentIndex].join("."))+"\n")
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
const propertyName = structure.options.cliDisplayPropertyName ?? "index"
const answer = await terminal.singleColumnMenu(localData.length < 1 ? [ansis.magenta("-> Continue to next variable"),"Add "+propertyName] : [
ansis.magenta("-> Continue to next variable"),
"Add "+propertyName,
"Edit "+propertyName,
"Move "+propertyName,
"Remove "+propertyName,
"Duplicate "+propertyName,
],{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
const backFnFunc = async () => {await renderAdditionConfigArrayStructureSelector(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath,localData)}
if (answer.canceled) return await backFn()
if (answer.selectedIndex == 0) await nextFn(localData)
else if (answer.selectedIndex == 1) await chooseAdditionConfigStructure(checker,backFnFunc,async (newData) => {
localData[localData.length] = newData
await backFnFunc()
},structure.options.propertyChecker,localData,localData.length,path,[])
else if (answer.selectedIndex == 2) await renderConfigArrayStructureEditSelector(checker,backFnFunc,structure,structure.options.propertyChecker,localData,parent,parentIndex,path)
else if (answer.selectedIndex == 3) await renderconfigArrayStructureMoveSelector(checker,backFnFunc,structure,structure.options.propertyChecker,localData,parent,parentIndex,path)
else if (answer.selectedIndex == 4) await renderconfigArrayStructureRemoveSelector(checker,backFnFunc,structure,structure.options.propertyChecker,localData,parent,parentIndex,path)
else if (answer.selectedIndex == 5) await renderConfigArrayStructureDuplicateSelector(checker,backFnFunc,structure,structure.options.propertyChecker,localData,parent,parentIndex,path)
}
async function renderAdditionConfigTypeSwitchStructure(checker:api.ODChecker,backFn:(() => api.ODPromiseVoid),nextFn:((data:any) => api.ODPromiseVoid),structure:api.ODCheckerTypeSwitchStructure,parent:object|any[],parentIndex:string|number,path:(string|number)[],localPath:(string|number)[]){
renderHeader(path)
terminal(ansis.bold.green("You are now creating "+(typeof parentIndex == "string" ? "the property "+ansis.blue("\""+parentIndex+"\"") : "property "+ansis.blue("#"+(parentIndex+1)))+".\n")+ansis.italic.gray("(use arrow keys to navigate, go back using escape)\n"))
terminal.gray("\nProperty: "+ansis.bold.blue(structure.options.cliDisplayName ?? [...localPath,parentIndex].join("."))+"\n")
terminal.gray("Description: "+ansis.bold(structure.options.cliDisplayDescription ?? "/")+"\n")
const actionsList: string[] = []
if (structure.options.boolean) actionsList.push("Create as boolean")
if (structure.options.string) actionsList.push("Create as string")
if (structure.options.number) actionsList.push("Create as number")
if (structure.options.object) actionsList.push("Create as object")
if (structure.options.array) actionsList.push("Create as array/list")
if (structure.options.null) actionsList.push("Create as null")
const answer = await terminal.singleColumnMenu(actionsList,{
leftPadding:"> ",
style:terminal.cyan,
selectedStyle:terminal.bgDefaultColor.bold,
submittedStyle:terminal.bgBlue,
extraLines:2,
cancelable:true
}).promise
if (answer.canceled) return await backFn()
//run selected structure editor (untested)
if (answer.selectedText.startsWith("Create as boolean") && structure.options.boolean) await renderAdditionConfigBooleanStructure(checker,async () => {await renderAdditionConfigTypeSwitchStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)},nextFn,structure.options.boolean,parent,parentIndex,path,localPath)
else if (answer.selectedText.startsWith("Create as string") && structure.options.string) await renderAdditionConfigStringStructure(checker,async () => {await renderAdditionConfigTypeSwitchStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)},nextFn,structure.options.string,parent,parentIndex,path,localPath)
else if (answer.selectedText.startsWith("Create as number") && structure.options.number) await renderAdditionConfigNumberStructure(checker,async () => {await renderAdditionConfigTypeSwitchStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)},nextFn,structure.options.number,parent,parentIndex,path,localPath)
else if (answer.selectedText.startsWith("Create as object") && structure.options.object) await renderAdditionConfigObjectStructure(checker,async () => {await renderAdditionConfigTypeSwitchStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)},nextFn,structure.options.object,parent,parentIndex,path,localPath)
else if (answer.selectedText.startsWith("Create as array/list") && structure.options.array) await renderAdditionConfigArrayStructureSelector(checker,async () => {await renderAdditionConfigTypeSwitchStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)},nextFn,structure.options.array,parent,parentIndex,path,localPath)
else if (answer.selectedText.startsWith("Create as null") && structure.options.null) await renderAdditionConfigNullStructure(checker,async () => {await renderAdditionConfigTypeSwitchStructure(checker,backFn,nextFn,structure,parent,parentIndex,path,localPath)},nextFn,structure.options.null,parent,parentIndex,path,localPath)
}
+180 -126
View File
@@ -1,16 +1,11 @@
import {opendiscord, api, utilities} from "../../index"
import {Terminal, terminal} from "terminal-kit"
import {opendiscord, api, utilities} from "../../index.js"
import * as cli from "@open-discord-bots/framework/cli"
import terminalKit from "terminal-kit"
import ansis from "ansis"
import * as discord from "discord.js"
import crypto from "crypto"
import {renderHeader, terminate} from "./cli"
import { headerOpts } from "./cli.js"
function generateUniqueIdFromName(name:string){
//id only allows a-z, 0-9 & dash characters (& replace spaces with dashes)
const filteredChars = name.toLowerCase().replaceAll(" ","-").split("").filter((ch) => /^[a-zA-Z0-9-]{1}$/.test(ch))
const randomSuffix = "-"+crypto.randomBytes(4).toString("hex")
return filteredChars.join("")+randomSuffix
}
const terminal = terminalKit.terminal
interface ODQuickSetupVariables {
client?:api.ODClientManager,
@@ -20,7 +15,7 @@ interface ODQuickSetupVariables {
language?:string,
slashCommands?:boolean,
textCommands?:boolean,
status?:api.ODJsonConfig_DefaultStatusType,
status?:api.ODGeneralJsonConfig_Status,
logChannel?:string|null,
ticketCategory?:string|null,
ticketOptions:({
@@ -30,7 +25,7 @@ interface ODQuickSetupVariables {
buttonColor:api.ODValidButtonColor,
buttonEmoji:string|null,
channelPrefix:string,
channelSuffix:api.ODJsonConfig_DefaultOptionTicketChannelType["suffix"]
channelSuffix:api.ODOptionsJsonConfig_TicketOptionChannelSettings["suffix"]
}|null)[],
optionIdStorage:string[],
autocloseHours?:number|null,
@@ -38,7 +33,7 @@ interface ODQuickSetupVariables {
globalUserLimit?:number|null,
removeParticipantsOnClose?:boolean,
ticketMessageLayout?:"embed"|"text"|null,
emojiStyle?:api.ODJsonConfig_DefaultSystem["emojiStyle"],
emojiStyle?:api.ODGeneralJsonConfig_TicketSystem["emojiStyle"],
panelName?:string,
panelDescription?:string,
panelDropdown?:boolean,
@@ -49,7 +44,7 @@ interface ODQuickSetupVariables {
const stepCount = (count:number) => "(Step "+count+"/24) "
const quickSetupStorage: ODQuickSetupVariables = {ticketOptions:[],optionIdStorage:[]}
const autoCompleteMenuOpts: Terminal.SingleLineMenuOptions = {
const autoCompleteMenuOpts: terminalKit.Terminal.SingleLineMenuOptions = {
style:terminal.white,
selectedStyle:terminal.bgBlue.white
}
@@ -113,7 +108,7 @@ function quickSetupRequiresReset(): boolean {
}
async function renderQuickSetupWarning(backFn:() => api.ODPromiseVoid) {
renderHeader("⏱️ Open Ticket Quick Setup: Warning")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Warning")
terminal.bold(ansis.yellow("WARNING! ")+ansis.red("By using the 'Quick Setup' feature, your current config will be completely resetted!"))
terminal.gray("\nAre you sure you want to continue?\n")
@@ -135,7 +130,7 @@ async function renderQuickSetupWarning(backFn:() => api.ODPromiseVoid) {
}
async function renderQuickSetupWelcome(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Introduction")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Introduction")
terminal.bold.underline.blue("Open Ticket: Quick Setup\n")
terminal.gray([
@@ -165,7 +160,7 @@ async function renderQuickSetupWelcome(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupDevPortal(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Discord Bot & Developer Portal")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Discord Bot & Developer Portal")
terminal.bold.blue(stepCount(1)+"Have you already created a Discord bot you can use for Open Ticket?\n")
@@ -189,7 +184,7 @@ async function renderQuickSetupDevPortal(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupDevPortalGuide(variation:0|1,backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Discord Bot & Developer Portal")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Discord Bot & Developer Portal")
if (variation == 0){
terminal.bold.blue(stepCount(1.1)+"You've mentioned that you don't know how to create a Discord bot.\n\n")
@@ -238,10 +233,10 @@ async function quickSetupLogin(token:string): Promise<api.ODClientManager|null>
}
async function renderQuickSetupBotToken(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Bot Token")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Bot Token")
terminal.bold.blue(stepCount(2)+"Please insert the token of your discord bot.\n")
terminal.gray("This is used to configure the bot and is then stored securely in the './config/general.json' file.\n\n> ")
terminal.gray("This is used to configure the bot and is then stored securely in the './config/general.jsonc' file.\n\n> ")
const answer = await terminal.inputField({
style:terminal.white,
@@ -275,7 +270,7 @@ async function renderQuickSetupServer(backFn:() => api.ODPromiseVoid){
const {client} = quickSetupStorage
if (!client) return
renderHeader("⏱️ Open Ticket Quick Setup: Discord Server")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Discord Server")
terminal.bold.blue(stepCount(3)+"Please select a Discord Server to use.\n")
terminal.gray("The bot will only work in this server.\n\n")
@@ -305,7 +300,7 @@ async function renderQuickSetupAdminRoles(selectedAdmins:string[],backFn:() => a
const {client,guild} = quickSetupStorage
if (!client || !guild) return
renderHeader("⏱️ Open Ticket Quick Setup: Admin Roles")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Admin Roles")
terminal.bold.blue(stepCount(4)+"Please select all 'Global Admins' roles to use.\n")
terminal.gray("Users with one of these roles will be able to access & interact with all tickets.\n\n")
@@ -341,7 +336,7 @@ async function renderQuickSetupColorPicker(backFn:() => api.ODPromiseVoid){
const {client,guild,globalAdmins} = quickSetupStorage
if (!client || !guild || !globalAdmins) return
renderHeader("⏱️ Open Ticket Quick Setup: Main Color")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Main Color")
terminal.bold.blue(stepCount(5)+"Please insert a valid hex-color to use in all embeds.\n")
terminal.gray("You can also choose from existing presets. (e.g. red, green, blue, ...)\n\n> ")
@@ -352,7 +347,7 @@ async function renderQuickSetupColorPicker(backFn:() => api.ODPromiseVoid){
cancelable:true,
autoComplete:Array.from(presetColors.keys()),
autoCompleteHint:true,
autoCompleteMenu:autoCompleteMenuOpts as Terminal.Autocompletion
autoCompleteMenu:autoCompleteMenuOpts as terminalKit.Terminal.Autocompletion
}).promise
if (typeof answer != "string") return await backFn()
@@ -375,7 +370,7 @@ async function renderQuickSetupColorPicker(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupLanguage(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Language")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Language")
terminal.bold.blue(stepCount(6)+"What language would you like to use in the bot?\n")
terminal.gray("View a list of available languages here: https://otgithub.dj-dj.be#-translators\n\n> ")
@@ -384,14 +379,14 @@ async function renderQuickSetupLanguage(backFn:() => api.ODPromiseVoid){
style:terminal.white,
hintStyle:terminal.gray,
cancelable:true,
autoComplete:opendiscord.defaults.getDefault("languageList"),
autoComplete:opendiscord.sharedFuses.getFuse("languageList"),
autoCompleteHint:true,
autoCompleteMenu:autoCompleteMenuOpts as Terminal.Autocompletion
autoCompleteMenu:autoCompleteMenuOpts as terminalKit.Terminal.Autocompletion
}).promise
if (typeof answer != "string") return await backFn()
else{
if (!opendiscord.defaults.getDefault("languageList").includes(answer.toLowerCase())){
if (!opendiscord.sharedFuses.getFuse("languageList").includes(answer.toLowerCase())){
terminal.red.bold("\n\n❌ Please insert an available language from the list. (TIP: use tab for autocomplete)\n")
await utilities.timer(2000)
return await renderQuickSetupLanguage(backFn)
@@ -403,7 +398,7 @@ async function renderQuickSetupLanguage(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupCommandTypes(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Command Types")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Command Types")
terminal.bold.blue(stepCount(7)+"Would you like to use slash commands, text commands or both?\n")
terminal.gray("Slash commands are recommended.\n\n")
@@ -436,7 +431,7 @@ async function renderQuickSetupCommandTypes(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupStatusType(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Status Type")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Status Type")
terminal.bold.blue(stepCount(8)+"Please select the type of status you want to use.\n")
terminal.gray("The status will be shown below the bot name in the userlist.\n\n")
@@ -471,7 +466,7 @@ async function renderQuickSetupStatusText(backFn:() => api.ODPromiseVoid){
const {status} = quickSetupStorage
if (!status) return
renderHeader("⏱️ Open Ticket Quick Setup: Status Text")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Status Text")
terminal.bold.blue(stepCount(8.1)+"What text would you like to display in the status?\n")
terminal.gray("This will be appended after the type you have chosen in the previous question.\n\n> ")
@@ -494,7 +489,7 @@ async function renderQuickSetupLogs(backFn:() => api.ODPromiseVoid){
const {client,guild} = quickSetupStorage
if (!client || !guild) return
renderHeader("⏱️ Open Ticket Quick Setup: Channel Logs")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Channel Logs")
terminal.bold.blue(stepCount(9)+"Please select the 'Text Channel' to use for logs.\n")
terminal.gray("All logs of the bot will be sent here. Make sure only admins can access this channel.\n\n")
@@ -531,7 +526,7 @@ async function renderQuickSetupTicketCategory(backFn:() => api.ODPromiseVoid){
const {client,guild} = quickSetupStorage
if (!client || !guild) return
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Category")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Category")
terminal.bold.blue(stepCount(10)+"Please select which 'Category' you would like tickets to be created in.\n")
terminal.gray("When no category is selected, tickets will appear at the top of the channel list.\n\n")
@@ -564,7 +559,7 @@ async function renderQuickSetupTicketCategory(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupTicketCount(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Configuration")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Configuration")
terminal.bold.blue(stepCount(11)+"How many ticket options/types would you like to create?\n")
terminal.gray("You can always add more ticket options/types in the config afterwards.\n\n")
@@ -601,7 +596,7 @@ async function renderQuickSetupTicketCount(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupCreateTicketName(ticketIndex:number,requiredTickets:number,backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
terminal.bold.blue("("+utilities.ordinalNumber(ticketIndex+1)+" Ticket) Please insert the name of this ticket option.\n")
terminal.gray("Recommendation: Clean, short, obvious name, not more than ±30 characters.\n\n> ")
@@ -635,7 +630,7 @@ async function renderQuickSetupCreateTicketName(ticketIndex:number,requiredTicke
}
async function renderQuickSetupCreateTicketDescription(ticketIndex:number,requiredTickets:number,backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
terminal.bold.blue("("+utilities.ordinalNumber(ticketIndex+1)+" Ticket) Please insert the description of this ticket option.\n")
terminal.gray("Recommendation: Use '\\n' (backslash-n) for a newline.\n\n> ")
@@ -655,7 +650,7 @@ async function renderQuickSetupCreateTicketDescription(ticketIndex:number,requir
}
async function renderQuickSetupCreateTicketButtonType(ticketIndex:number,requiredTickets:number,backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
terminal.bold.blue("("+utilities.ordinalNumber(ticketIndex+1)+" Ticket) How would you like to display the ticket name in the button/dropdown?\n")
terminal.gray("You will be able to choose between dropdown/buttons when configuring panels.\n\n")
@@ -686,7 +681,7 @@ async function renderQuickSetupCreateTicketButtonType(ticketIndex:number,require
}
async function renderQuickSetupCreateTicketButtonEmoji(ticketIndex:number,requiredTickets:number,backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
terminal.bold.blue("("+utilities.ordinalNumber(ticketIndex+1)+" Ticket) Please insert the button emoji of this ticket option.\n")
terminal.gray("Only 1 emoji allowed. Tip: Insert custom emoji's via the following syntax: <:12345678910:emoji_name>\n\n> ")
@@ -714,7 +709,7 @@ async function renderQuickSetupCreateTicketButtonEmoji(ticketIndex:number,requir
}
async function renderQuickSetupCreateTicketButtonColor(ticketIndex:number,requiredTickets:number,backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
terminal.bold.blue("("+utilities.ordinalNumber(ticketIndex+1)+" Ticket) What color would you like the button to be?\n")
terminal.gray("This will not apply when choosing 'dropdown' mode in the panel configuration.\n\n")
@@ -742,7 +737,7 @@ async function renderQuickSetupCreateTicketButtonColor(ticketIndex:number,requir
}
async function renderQuickSetupCreateTicketChannelPrefix(ticketIndex:number,requiredTickets:number,backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
terminal.bold.blue("("+utilities.ordinalNumber(ticketIndex+1)+" Ticket) Please insert the channel prefix of this ticket option.\n")
terminal.gray("Examples: 'ticket-', 'question-', 'test-channel-', ...\n\n> ")
@@ -766,7 +761,7 @@ async function renderQuickSetupCreateTicketChannelPrefix(ticketIndex:number,requ
}
async function renderQuickSetupCreateTicketChannelSuffix(ticketIndex:number,requiredTickets:number,backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Configuration (Ticket "+(ticketIndex+1)+"/"+requiredTickets+")")
terminal.bold.blue("("+utilities.ordinalNumber(ticketIndex+1)+" Ticket) Please select the channel suffix mode of this ticket option.\n")
terminal.gray("The suffix is appended after the prefix and will be generated on ticket creation.\n\n")
@@ -806,7 +801,7 @@ async function renderQuickSetupCreateTicketChannelSuffix(ticketIndex:number,requ
}
async function renderQuickSetupAutoclose(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Autoclose")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Autoclose")
terminal.bold.blue(stepCount(12)+"Would you like to enable autoclosing tickets?\n")
terminal.gray("Applies to all created tickets. You can always change/disable autoclose per ticket-option in the config afterwards.\n\n")
@@ -839,7 +834,7 @@ async function renderQuickSetupAutoclose(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupCooldown(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Cooldown")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Cooldown")
terminal.bold.blue(stepCount(13)+"Would you like to enable ticket creation cooldown?\n")
terminal.gray("Applies to all created tickets. You can always change/disable cooldown per ticket-option in the config afterwards.\n\n")
@@ -873,7 +868,7 @@ async function renderQuickSetupCooldown(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupLimits(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Limits")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Limits")
terminal.bold.blue(stepCount(14)+"Would you like to enable user ticket creation limits?\n")
terminal.gray("Applies to all created tickets. You can always change/disable limits globally or per ticket-option in the config afterwards.\n\n")
@@ -904,7 +899,7 @@ async function renderQuickSetupLimits(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupCloseParticipants(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Close Configuration")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Close Configuration")
terminal.bold.blue(stepCount(15)+"Would you like to remove all ticket participants when closing the ticket?\n")
terminal.gray("When a ticket is closed, only admins can read/write in the ticket. Reopen ticket to restore read/write perms.\n\n")
@@ -929,7 +924,7 @@ async function renderQuickSetupCloseParticipants(backFn:() => api.ODPromiseVoid)
}
async function renderQuickSetupTicketMessageLayout(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Message Configuration")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Message Configuration")
terminal.bold.blue(stepCount(16)+"How would you like the (initial) ticket message to be displayed?\n")
terminal.gray("This message is sent by the bot when creating a ticket and contains buttons like closing, claiming & deleting.\n\n")
@@ -955,7 +950,7 @@ async function renderQuickSetupTicketMessageLayout(backFn:() => api.ODPromiseVoi
}
async function renderQuickSetupEmojiStyle(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Emoji Style")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Emoji Style")
terminal.bold.blue(stepCount(17)+"How would you like emojis to be displayed in messages?\n")
terminal.gray("This will affect emojis in all messages of the bot, but does not apply to buttons & dropdowns.\n\n")
@@ -982,7 +977,7 @@ async function renderQuickSetupEmojiStyle(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupPanelName(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Panel Name")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Panel Name")
terminal.bold.blue(stepCount(18)+"Please insert the name of the ticket panel.\n")
terminal.gray("This will be shown as the title of the panel message where all tickets are located.\n\n> ")
@@ -1005,7 +1000,7 @@ async function renderQuickSetupPanelName(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupPanelDescription(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Panel Description")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Panel Description")
terminal.bold.blue(stepCount(19)+"Please insert the description of the ticket panel.\n")
terminal.gray("Shown below the title. Can be used to explain some info/rules about the ticket system.\n\n> ")
@@ -1024,7 +1019,7 @@ async function renderQuickSetupPanelDescription(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupPanelDropdown(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Panel Mode")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Panel Mode")
terminal.bold.blue(stepCount(20)+"Do you want to show the tickets as buttons or a dropdown?\n")
terminal.gray("Dropdown doesn't support colors and cannot contain option types other than 'tickets' (e.g. website/url or reaction roles).\n\n")
@@ -1049,7 +1044,7 @@ async function renderQuickSetupPanelDropdown(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupPanelLayout(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Panel Layout")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Panel Layout")
terminal.bold.blue(stepCount(21)+"How would you like the panel message to be displayed?\n")
terminal.gray("Most of the time embeds are used. But for a simpler solution, you can choose the text layout.\n\n")
@@ -1074,7 +1069,7 @@ async function renderQuickSetupPanelLayout(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupPanelDescribeOptions(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Panel Option Descriptions")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Panel Option Descriptions")
terminal.bold.blue(stepCount(22)+"Would you like the panel to have auto-generated (ticket-)option descriptions?\n")
terminal.gray("It will use the 'name' & 'description' of each ticket option and displays it below the panel description.\n\n")
@@ -1101,7 +1096,7 @@ async function renderQuickSetupPanelDescribeOptions(backFn:() => api.ODPromiseVo
}
async function renderQuickSetupPanelMaxTicketsWarning(backFn:() => api.ODPromiseVoid){
renderHeader("⏱️ Open Ticket Quick Setup: Ticket Close Configuration")
cli.renderHeader(headerOpts,"⏱️ Open Ticket Quick Setup: Ticket Close Configuration")
terminal.bold.blue(stepCount(23)+"Would you like to show the maximum amount of tickets a user can create in the panel?\n")
terminal.gray("This will show the amount of tickets a user can create at the same time when limits are enabled.\n\n")
@@ -1126,7 +1121,7 @@ async function renderQuickSetupPanelMaxTicketsWarning(backFn:() => api.ODPromise
}
async function renderQuickSetupReady(backFn:() => api.ODPromiseVoid){
renderHeader("😎 Open Ticket Quick Setup: Overview")
cli.renderHeader(headerOpts,"😎 Open Ticket Quick Setup: Overview")
terminal.bold.blue(stepCount(24)+"This is the overview of your ticket bot configuration!\n")
terminal.gray("Press 'Enter' to save the result to the config.\n\n")
@@ -1171,7 +1166,7 @@ async function renderQuickSetupReady(backFn:() => api.ODPromiseVoid){
}
async function renderQuickSetupFinished(){
renderHeader("✅ Open Ticket Quick Setup: Ready")
cli.renderHeader(headerOpts,"✅ Open Ticket Quick Setup: Ready")
terminal.bold.green("The config has been saved succesfully and the bot is now ready for usage!\n")
terminal.gray("Press 'Enter' to exit the Quick Setup CLI.\n\n")
@@ -1203,18 +1198,14 @@ async function renderQuickSetupFinished(){
}).promise
//stop CLI
return await terminate()
return await cli.terminate(headerOpts)
}
async function saveQuickSetupConfig(){
//GENERAL CONFIG
const generalConfig = opendiscord.configs.get("opendiscord:general")
const generalConfigData: api.ODJsonConfig_DefaultGeneralData = {
_INFO:{
support:"https://otdocs.dj-dj.be",
discord:"https://discord.dj-dj.be",
version:"open-ticket-"+opendiscord.versions.get("opendiscord:version").toString()
},
const generalConfigData: api.ODGeneralJsonConfig_GeneralData = {
_CONFIG_VERSION:"open-ticket-"+opendiscord.versions.get("opendiscord:version").toString(),
token:quickSetupStorage.client?.token ?? "<unknown-token>",
tokenFromENV:false,
@@ -1229,8 +1220,29 @@ async function saveQuickSetupConfig(){
textCommands:quickSetupStorage.textCommands ?? false,
status:quickSetupStorage.status ?? {enabled:false,mode:"online",type:"custom",text:"",state:""},
logs:{
enabled:(typeof quickSetupStorage.logChannel == "string"),
channel:quickSetupStorage.logChannel ?? "",
logMessages:{
creation:{dm:true,logs:true},
closing:{dm:true,logs:true},
deleting:{dm:true,logs:true},
reopening:{dm:false,logs:true},
claiming:{dm:false,logs:true},
pinning:{dm:false,logs:true},
adding:{dm:false,logs:true},
removing:{dm:false,logs:true},
renaming:{dm:false,logs:true},
moving:{dm:true,logs:true},
blacklisting:{dm:true,logs:true},
transferring:{dm:true,logs:true},
topicChange:{dm:false,logs:true},
priorityChange:{dm:false,logs:true},
reactionRole:{dm:false,logs:true}
}
},
system:{
ticketSystem:{
preferSlashOverText:quickSetupStorage.slashCommands ?? false,
sendErrorOnUnknownCommand:true,
questionFieldsInCodeBlock:true,
@@ -1241,10 +1253,11 @@ async function saveQuickSetupConfig(){
alwaysShowReason:false,
emojiStyle:quickSetupStorage.emojiStyle ?? "before",
pinEmoji:"📌",
closeEmoji:"🔒",
replyOnTicketCreation:false,
replyOnTicketCreation:true,
replyOnReactionRole:true,
askPriorityOnTicketCreation:false,
askPriorityOnTicketCreation:true,
removeParticipantsOnClose:quickSetupStorage.removeParticipantsOnClose ?? false,
disableAutocloseAfterReopen:true,
autodeleteRequiresClosedTicket:true,
@@ -1252,7 +1265,7 @@ async function saveQuickSetupConfig(){
allowCloseBeforeMessage:false,
allowCloseBeforeAdminMessage:true,
useTranslatedConfigChecker:true,
pinFirstTicketMessage:false,
pinFirstTicketMessage:true,
enableTicketClaimButtons:true,
enableTicketCloseButtons:true,
@@ -1260,11 +1273,7 @@ async function saveQuickSetupConfig(){
enableTicketDeleteButtons:true,
enableTicketActionWithReason:true,
enableDeleteWithoutTranscript:true,
logs:{
enabled:(typeof quickSetupStorage.logChannel == "string"),
channel:quickSetupStorage.logChannel ?? ""
},
enableCreateTicketForOtherUser:true,
limits:{
enabled:(typeof quickSetupStorage.globalUserLimit == "number"),
@@ -1283,49 +1292,41 @@ async function saveQuickSetupConfig(){
showCreator:false,
showParticipants:false
},
permissions:{
help:"everyone",
panel:"admin",
ticket:"everyone",
close:"admin",
delete:"admin",
reopen:"admin",
claim:"admin",
unclaim:"admin",
pin:"admin",
unpin:"admin",
move:"admin",
rename:"admin",
add:"admin",
remove:"admin",
blacklist:"admin",
stats:"everyone",
clear:"admin",
autoclose:"admin",
autodelete:"admin",
transfer:"admin",
topic:"admin",
priority:"admin",
closedCategory:{
enabled:false,
categoryId:""
},
messages:{
creation:{dm:true,logs:true},
closing:{dm:true,logs:true},
deleting:{dm:true,logs:true},
reopening:{dm:false,logs:true},
claiming:{dm:false,logs:true},
pinning:{dm:false,logs:true},
adding:{dm:false,logs:true},
removing:{dm:false,logs:true},
renaming:{dm:false,logs:true},
moving:{dm:true,logs:true},
blacklisting:{dm:true,logs:true},
transferring:{dm:true,logs:true},
topicChange:{dm:false,logs:true},
priorityChange:{dm:false,logs:true},
reactionRole:{dm:false,logs:true}
}
backupCategory:{
enabled:false,
categoryId:""
},
claimedCategories:[],
},
permissions:{
help:"everyone",
panel:"admin",
ticket:"everyone",
close:"admin",
delete:"admin",
reopen:"admin",
claim:"admin",
unclaim:"admin",
pin:"admin",
unpin:"admin",
move:"admin",
rename:"admin",
add:"admin",
remove:"admin",
blacklist:"admin",
stats:"everyone",
clear:"admin",
autoclose:"admin",
autodelete:"admin",
transfer:"admin",
topic:"admin",
priority:"admin",
transcripts:"admin"
}
}
generalConfig.data = generalConfigData
@@ -1333,14 +1334,15 @@ async function saveQuickSetupConfig(){
//QUESTIONS CONFIG => no configuration needed (coming soonTM)
const questionsConfig = opendiscord.configs.get("opendiscord:questions")
const questionsConfigData: api.ODJsonConfig_DefaultQuestionsData = [
const questionsConfigData: api.ODQuestionsJsonConfig_QuestionsData = [
{
id:"example-question-1",
name:"Example Question 1",
description:"This is a short text input question.",
type:"short",
required:true,
placeholder:"Insert your short answer here!",
placeholder:"Insert answer...",
length:{
enabled:false,
min:0,
@@ -1350,15 +1352,69 @@ async function saveQuickSetupConfig(){
{
id:"example-question-2",
name:"Example Question 2",
description:"This is a paragraph text input question.",
type:"paragraph",
required:false,
placeholder:"Insert your long answer here!",
placeholder:"Insert answer...",
length:{
enabled:false,
min:0,
max:1000
}
},
{
id:"example-question-3",
name:"Example Question 3",
description:"This is a dropdown question.",
type:"dropdown",
required:false,
placeholder:"Choose your answer...",
choices:[
{title:"Choice A",description:"Apple",emoji:"🍎"},
{title:"Choice B",description:"Banana",emoji:"🍌"},
{title:"Choice C",description:"Orange",emoji:"🍊"},
{title:"Choice D",description:"Kiwi",emoji:"🥝"}
]
},
{
id:"example-question-4",
name:"Example Question 4",
description:"This is a radio select question.",
type:"radio-select",
required:true,
choices:[
{title:"Choice A",description:"Up",selectedByDefault:false},
{title:"Choice B",description:"Down",selectedByDefault:false},
{title:"Choice C",description:"Left",selectedByDefault:false},
{title:"Choice D",description:"Right",selectedByDefault:false}
]
},
{
id:"example-question-5",
name:"Example Question 5",
description:"This is a checkbox select question.",
type:"checkbox-select",
required:true,
limits:{
enabled:false,
min:0,
max:10
},
choices:[
{title:"Choice A",description:"Happiness",selectedByDefault:false},
{title:"Choice B",description:"Anger",selectedByDefault:false},
{title:"Choice C",description:"Sadness",selectedByDefault:false},
{title:"Choice D",description:"Fear",selectedByDefault:false}
]
},
{
id:"example-text-display",
type:"text-display",
textContents:"This is a text display. It isn't a question, but allows you to display a text, explaination or details."
}
]
questionsConfig.data = questionsConfigData
@@ -1366,8 +1422,8 @@ async function saveQuickSetupConfig(){
//OPTIONS CONFIG
const optionsConfig = opendiscord.configs.get("opendiscord:options")
const optionsConfigData: api.ODJsonConfig_DefaultOptionsData = quickSetupStorage.ticketOptions.filter((ticket) => ticket !== null).map((ticket) => {
const id = generateUniqueIdFromName(ticket.name)
const optionsConfigData: api.ODOptionsJsonConfig_OptionsData = quickSetupStorage.ticketOptions.filter((ticket) => ticket !== null).map((ticket) => {
const id = cli.generateUniqueIdFromName(ticket.name)
quickSetupStorage.optionIdStorage.push(id)
return {
@@ -1391,9 +1447,6 @@ async function saveQuickSetupConfig(){
prefix:ticket.channelPrefix,
suffix:ticket.channelSuffix,
category:quickSetupStorage.ticketCategory ?? "",
closedCategory:"",
backupCategory:"",
claimedCategory:[],
topic:ticket.description
},
@@ -1464,9 +1517,9 @@ async function saveQuickSetupConfig(){
//PANELS CONFIG
const panelsConfig = opendiscord.configs.get("opendiscord:panels")
const panelsConfigData: api.ODJsonConfig_DefaultPanelsData = [
const panelsConfigData: api.ODPanelsJsonConfig_PanelsData = [
{
id:generateUniqueIdFromName(quickSetupStorage.panelName ?? "ticket-panel"),
id:cli.generateUniqueIdFromName(quickSetupStorage.panelName ?? "ticket-panel"),
name:quickSetupStorage.panelName ?? "Ticket Panel",
dropdown:quickSetupStorage.panelDropdown ?? false,
options:quickSetupStorage.optionIdStorage,
@@ -1489,6 +1542,7 @@ async function saveQuickSetupConfig(){
},
settings:{
dropdownPlaceholder:"Open a ticket",
maximumButtonsPerRow:5,
enableMaxTicketsWarningInText:(quickSetupStorage.panelLayout == "text" && (quickSetupStorage.panelMaxTicketsWarning ?? false)),
enableMaxTicketsWarningInEmbed:(quickSetupStorage.panelLayout == "embed" && (quickSetupStorage.panelMaxTicketsWarning ?? false)),
@@ -1506,7 +1560,7 @@ async function saveQuickSetupConfig(){
//TRANSCRIPTS CONFIG => no configuration needed (coming soonTM)
const transcriptsConfig = opendiscord.configs.get("opendiscord:transcripts")
const transcriptsConfigData: api.ODJsonConfig_DefaultTranscriptsData = {
const transcriptsConfigData: api.ODTranscriptsJsonConfig_TranscriptsData = {
general:{
enabled:(typeof quickSetupStorage.logChannel == "string"),
+137
View File
@@ -0,0 +1,137 @@
///////////////////////////////////////
//OPEN TICKET MAIN MODULE
///////////////////////////////////////
import * as api from "./api.js"
import * as utilities from "@open-discord-bots/framework/utilities"
export class ODOpenTicketMain extends api.ODMain {
declare versions: api.ODMappedVersionManager
declare events: api.ODMappedEventManager
declare plugins: api.ODMappedPluginManager
declare flags: api.ODMappedFlagManager
declare progressbars: api.ODMappedProgressBarManager
declare configs: api.ODMappedConfigManager
declare databases: api.ODMappedDatabaseManager
declare sessions: api.ODMappedSessionManager
declare languages: api.ODMappedLanguageManager
declare checkers: api.ODMappedCheckerManager
declare builders: api.ODMappedBuilderManager
declare components: api.ODMappedComponentManager
declare responders: api.ODMappedResponderManager
declare actions: api.ODMappedActionManager
declare verifybars: api.ODMappedVerifyBarManager
declare permissions: api.ODMappedPermissionManager
declare cooldowns: api.ODMappedCooldownManager
declare helpmenu: api.ODMappedHelpMenuManager
declare statistics: api.ODMappedStatisticManager
declare code: api.ODMappedCodeManager
declare posts: api.ODMappedPostManager
declare states: api.ODMappedStateManager
declare client: api.ODMappedClientManager
declare livestatus: api.ODMappedLiveStatusManager
declare startscreen: api.ODMappedStartScreenManager
/////////////////////
//// OPEN TICKET ////
/////////////////////
/**Open Ticket specific fuses. With these fuses/switches, you can turn off "default behaviours" from the bot. Useful for replacing default behaviour with a custom implementation. */
fuses: api.ODFuseManager<api.ODOpenTicketFuseList>
/**The manager that manages all the data of questions in the bot. (these are used in options & tickets) */
questions: api.ODQuestionManager
/**The manager that manages all the data of options in the bot. (these are used for panels, ticket creation, reaction roles) */
options: api.ODOptionManager
/**The manager that manages all the data of panels in the bot. (panels contain the options) */
panels: api.ODPanelManager
/**The manager that manages all tickets in the bot. (here, you can get & edit a lot of data from tickets) */
tickets: api.ODTicketManager
/**The manager that manages the ticket blacklist. (people who are blacklisted can't create a ticket) */
blacklist: api.ODBlacklistManager
/**The manager that manages the ticket transcripts. (both the history & compilers) */
transcripts: api.ODMappedTranscriptManager
/**The manager that manages all reaction roles in the bot. (here, you can add additional data to roles) */
roles: api.ODRoleManager
/**The manager that manages all priority levels in the bot. (register/edit ticket priority levels) */
priorities: api.ODMappedPriorityManager
constructor(){
const version = api.ODVersion.fromString("opendiscord:version","v4.2.0")
const debugfile = new api.ODDebugFileManager("./","otdebug.txt",5000,version)
const console = new api.ODConsoleManager(100,debugfile)
const debug = new api.ODDebugger(console)
const client = new api.ODMappedClientManager(debug)
const livestatus = new api.ODMappedLiveStatusManager(debug,console)
const permissions = new api.ODMappedPermissionManager(debug,client,true)
super({
versions:new api.ODMappedVersionManager(),
debugfile,console,debug,
events:new api.ODMappedEventManager(debug),
processStartupDate:new Date(),
readyStartupDate:null,
plugins:new api.ODMappedPluginManager(debug),
flags:new api.ODMappedFlagManager(debug),
progressbars:new api.ODMappedProgressBarManager(debug),
configs:new api.ODMappedConfigManager(debug),
databases:new api.ODMappedDatabaseManager(debug),
sessions:new api.ODMappedSessionManager(debug),
languages:new api.ODMappedLanguageManager(debug,false),
checkers:new api.ODMappedCheckerManager(debug,
new api.ODCheckerStorage(),
new api.ODDefaultCheckerRenderer("#f8ba00","https://discord.dj-dj.be","https://otdocs.dj-dj.be"),
new api.ODMappedCheckerTranslationRegister(),
new api.ODMappedCheckerFunctionManager(debug)
),
builders:new api.ODMappedBuilderManager(debug),
components:new api.ODMappedComponentManager(debug),
client,
responders:new api.ODMappedResponderManager(debug,client),
actions:new api.ODMappedActionManager(debug),
verifybars:new api.ODMappedVerifyBarManager(debug),
permissions,
cooldowns:new api.ODMappedCooldownManager(debug),
helpmenu:new api.ODMappedHelpMenuManager(debug),
statistics:new api.ODMappedStatisticManager(debug),
code:new api.ODMappedCodeManager(debug),
posts:new api.ODMappedPostManager(debug),
states:new api.ODMappedStateManager(debug),
sharedFuses:utilities.sharedFuses,
env:new api.ODEnvHelper(),
livestatus,
startscreen:new api.ODMappedStartScreenManager(debug,livestatus),
},"openticket")
this.livestatus.useMain(this)
this.versions.add(api.ODVersion.fromString("opendiscord:version","v4.2.0"))
this.versions.add(api.ODVersion.fromString("opendiscord:transcripts","v2.1.0"))
//OPEN TICKET
this.fuses = new api.ODFuseManager<api.ODOpenTicketFuseList>({
priorityLoading:true,
questionLoading:true,
optionLoading:true,
panelLoading:true,
ticketLoading:true,
roleLoading:true,
blacklistLoading:true,
transcriptCompilerLoading:true,
transcriptHistoryLoading:true,
autocloseCheckInterval:300000, //5 minutes
autodeleteCheckInterval:300000 //5 minutes
})
this.questions = new api.ODQuestionManager(debug)
this.options = new api.ODOptionManager(debug)
this.panels = new api.ODPanelManager(debug)
this.tickets = new api.ODTicketManager(debug,client)
this.blacklist = new api.ODBlacklistManager(debug)
this.transcripts = new api.ODMappedTranscriptManager(debug,this.tickets,client,permissions)
this.roles = new api.ODRoleManager(debug)
this.priorities = new api.ODMappedPriorityManager(debug)
}
}
@@ -1,173 +1,152 @@
///////////////////////////////////////
//DEFAULT ACTION MODULE
//OPEN TICKET ACTION MAPPINGS
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODAction, ODActionManager } from "../modules/action"
import { ODWorkerManager_Default } from "./worker"
import * as api from "@open-discord-bots/framework/api"
import * as discord from "discord.js"
import { ODRoleOption, ODTicketOption } from "../openticket/option"
import { ODTicket, ODTicketClearFilter } from "../openticket/ticket"
import { ODTranscriptCompiler, ODTranscriptCompilerCompileResult } from "../openticket/transcript"
import { ODMessageBuildSentResult } from "../modules/builder"
import { ODRole, ODRoleUpdateMode, ODRoleUpdateResult } from "../openticket/role"
import { ODPriorityLevel } from "../openticket/priority"
import { ODRoleOption, ODTicketOption } from "../api/option.js"
import { ODTicket, ODTicketClearFilter } from "../api/ticket.js"
import { ODTranscriptCompiler, ODTranscriptCompilerCompileResult } from "../api/transcript.js"
import { ODRole, ODRoleUpdateMode, ODRoleUpdateResult } from "../api/role.js"
import { ODPriorityLevel } from "../api/priority.js"
/**## ODActionManagerIds_Default `interface`
* This interface is a list of ids available in the `ODActionManager_Default` class.
/**## ODActionManagerIdMappings `interface`
* A list of all available IDs in the default `ODActionManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODActionManagerIds_Default {
export interface ODActionManagerIdMappings extends api.ODActionManagerIdConstraint {
"opendiscord:create-ticket-permissions":{
source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",
origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",
params:{guild:discord.Guild,user:discord.User,option:ODTicketOption},
result:{valid:boolean,reason:"blacklist"|"cooldown"|"global-limit"|"global-user-limit"|"option-limit"|"option-user-limit"|"custom"|null,cooldownUntil?:Date,customReason?:string},
workers:"opendiscord:check-blacklist"|"opendiscord:check-cooldown"|"opendiscord:check-global-limits"|"opendiscord:check-option-limits"|"opendiscord:valid"
},
"opendiscord:create-transcript":{
source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",
origin:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},
result:{compiler:ODTranscriptCompiler<any,object|null>, success:boolean, result:ODTranscriptCompilerCompileResult<any>, errorReason:string|null, pendingMessage:ODMessageBuildSentResult<true>|null, initData:object|null, participants:{user:discord.User,role:"creator"|"participant"|"admin"}[]},
result:{compiler:ODTranscriptCompiler<any,object|null>, success:boolean, result:ODTranscriptCompilerCompileResult<any>, errorReason:string|null, pendingMessage:api.ODResponderSendResult<true>|null, initData:object|null, participants:{user:discord.User,role:"creator"|"participant"|"admin"}[]},
workers:"opendiscord:select-compiler"|"opendiscord:init-transcript"|"opendiscord:compile-transcript"|"opendiscord:ready-transcript"|"opendiscord:logs"
},
"opendiscord:create-ticket":{
source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",
origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",
params:{guild:discord.Guild,user:discord.User,option:ODTicketOption,answers:{id:string,name:string,type:"short"|"paragraph",value:string|null}[]},
result:{channel:discord.GuildTextBasedChannel,ticket:ODTicket},
workers:"opendiscord:create-ticket"|"opendiscord:send-ticket-message"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:close-ticket":{
source:"slash"|"text"|"ticket-message"|"reopen-message"|"autoclose"|"other",
origin:"slash"|"text"|"ticket-message"|"reopen-message"|"autoclose"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean,allowCategoryChange?:boolean},
result:{},
workers:"opendiscord:close-ticket"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:delete-ticket":{
source:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",
origin:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean,withoutTranscript:boolean},
result:{},
workers:"opendiscord:delete-ticket"|"opendiscord:discord-logs"|"opendiscord:delete-channel"|"opendiscord:logs"
},
"opendiscord:reopen-ticket":{
source:"slash"|"text"|"ticket-message"|"close-message"|"autoclose-message"|"other",
origin:"slash"|"text"|"ticket-message"|"close-message"|"autoclose-message"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean,allowCategoryChange?:boolean},
result:{},
workers:"opendiscord:reopen-ticket"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:claim-ticket":{
source:"slash"|"text"|"ticket-message"|"unclaim-message"|"other",
origin:"slash"|"text"|"ticket-message"|"unclaim-message"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean,allowCategoryChange?:boolean},
result:{},
workers:"opendiscord:claim-ticket"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:unclaim-ticket":{
source:"slash"|"text"|"ticket-message"|"claim-message"|"other",
origin:"slash"|"text"|"ticket-message"|"claim-message"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean,allowCategoryChange?:boolean},
result:{},
workers:"opendiscord:unclaim-ticket"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:pin-ticket":{
source:"slash"|"text"|"ticket-message"|"unpin-message"|"other",
origin:"slash"|"text"|"ticket-message"|"unpin-message"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean},
result:{},
workers:"opendiscord:pin-ticket"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:unpin-ticket":{
source:"slash"|"text"|"ticket-message"|"pin-message"|"other",
origin:"slash"|"text"|"ticket-message"|"pin-message"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean},
result:{},
workers:"opendiscord:unpin-ticket"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:rename-ticket":{
source:"slash"|"text"|"other",
origin:"slash"|"text"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean,data:string},
result:{},
workers:"opendiscord:rename-ticket"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:move-ticket":{
source:"slash"|"text"|"other",
origin:"slash"|"text"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean,data:ODTicketOption},
result:{},
workers:"opendiscord:move-ticket"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:add-ticket-user":{
source:"slash"|"text"|"other",
origin:"slash"|"text"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean,data:discord.User},
result:{},
workers:"opendiscord:add-ticket-user"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:remove-ticket-user":{
source:"slash"|"text"|"other",
origin:"slash"|"text"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean,data:discord.User},
result:{},
workers:"opendiscord:remove-ticket-user"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:reaction-role":{
source:"panel-button"|"other",
origin:"panel-button"|"other",
params:{guild:discord.Guild,user:discord.User,option:ODRoleOption,overwriteMode:ODRoleUpdateMode|null},
result:{result:ODRoleUpdateResult[],role:ODRole},
workers:"opendiscord:reaction-role"|"opendiscord:logs"
},
"opendiscord:clear-tickets":{
source:"slash"|"text"|"other",
origin:"slash"|"text"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:ODTicket[]},
result:{list:string[]},
workers:"opendiscord:clear-tickets"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:update-ticket-topic":{
source:"slash"|"text"|"ticket-action"|"other",
origin:"slash"|"text"|"ticket-action"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,newTopic:string|null,sendMessage:boolean},
result:{},
workers:"opendiscord:update-ticket-topic"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:update-ticket-priority":{
source:"slash"|"text"|"other",
origin:"slash"|"text"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,newPriority:ODPriorityLevel,reason:string|null,sendMessage:boolean},
result:{},
workers:"opendiscord:update-ticket-priority"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:transfer-ticket":{
source:"slash"|"text"|"other",
origin:"slash"|"text"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,newCreator:discord.User,reason:string|null,sendMessage:boolean},
result:{},
workers:"opendiscord:transfer-ticket"|"opendiscord:discord-logs"|"opendiscord:logs"
},
"opendiscord:calculate-ticket-category":{
origin:"create-ticket"|"close-ticket"|"reopen-ticket"|"claim-ticket"|"unclaim-ticket"|"move-ticket"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel|null,user:discord.User,option:ODTicketOption,ticket:ODTicket|null,currentCategoryId:string|null},
result:{newCategoryId:string|null,newCategoryMode:string|null,newCategory:discord.CategoryChannel|null,shouldChangeCategory:boolean},
workers:"opendiscord:default-category"|"opendiscord:close-category"|"opendiscord:claim-category"|"opendiscord:backup-category"
},
"opendiscord:calculate-ticket-name":{
origin:"create-ticket"|"close-ticket"|"reopen-ticket"|"claim-ticket"|"unclaim-ticket"|"move-ticket"|"pin-ticket"|"unpin-ticket"|"rename-ticket"|"transfer-ticket"|"priority-change"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel|null,user:discord.User,option:ODTicketOption,ticket:ODTicket|null,currentChannelName:string|null},
result:{newChannelName:string,newChannelSuffix:string,shouldChangeName:boolean},
workers:"opendiscord:calculate-ticket-name"
},
}
/**## ODActionManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODActionManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.actions`!
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedActionManager `class
* A special class with types for the Open Ticket `ODActionManager` class.
*/
export class ODActionManager_Default extends ODActionManager {
get<ActionId extends keyof ODActionManagerIds_Default>(id:ActionId): ODAction_Default<ODActionManagerIds_Default[ActionId]["source"],ODActionManagerIds_Default[ActionId]["params"],ODActionManagerIds_Default[ActionId]["result"],ODActionManagerIds_Default[ActionId]["workers"]>
get(id:ODValidId): ODAction<string,any,any>|null
get(id:ODValidId): ODAction<string,any,any>|null {
return super.get(id)
}
remove<ActionId extends keyof ODActionManagerIds_Default>(id:ActionId): ODAction_Default<ODActionManagerIds_Default[ActionId]["source"],ODActionManagerIds_Default[ActionId]["params"],ODActionManagerIds_Default[ActionId]["result"],ODActionManagerIds_Default[ActionId]["workers"]>
remove(id:ODValidId): ODAction<string,any,any>|null
remove(id:ODValidId): ODAction<string,any,any>|null {
return super.remove(id)
}
exists(id:keyof ODActionManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODAction_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODAction class.
* It doesn't add any extra features!
*
* This default class is made for the default `ODAction`'s!
*/
export class ODAction_Default<Source extends string, Params extends object, Result extends object, WorkerIds extends string> extends ODAction<Source,Params,Result> {
declare workers: ODWorkerManager_Default<Result,Source,Params,WorkerIds>
}
export class ODMappedActionManager extends api.ODActionManager<ODActionManagerIdMappings> {}
+25
View File
@@ -0,0 +1,25 @@
///////////////////////////////////////
//BASE MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODVersionManagerIdMappings `interface`
* A list of all available IDs in the default `ODVersionManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODVersionManagerIdMappings extends api.ODVersionManagerIdConstraint {
"opendiscord:version":api.ODVersion,
"opendiscord:last-version":api.ODVersion,
"opendiscord:api":api.ODVersion,
"opendiscord:transcripts":api.ODVersion,
"opendiscord:livestatus":api.ODVersion
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedVersionManager `class
* A special class with types for the Open Ticket `ODVersionManager` class.
*/
export class ODMappedVersionManager extends api.ODVersionManager<ODVersionManagerIdMappings> {}
+285
View File
@@ -0,0 +1,285 @@
///////////////////////////////////////
//OPEN TICKET BUILDER MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
import { ODPermissionEmbedType } from "./permission.js"
import { ODTranscriptCompiler, ODTranscriptCompilerCompileResult } from "../api/transcript.js"
import { ODRoleOption, ODTicketOption, ODWebsiteOption } from "../api/option.js"
import { ODTicket, ODTicketClearFilter } from "../api/ticket.js"
import { ODRole, ODRoleUpdateResult } from "../api/role.js"
import { ODPriorityLevel } from "../api/priority.js"
import { ODPanel } from "../api/panel.js"
import * as discord from "discord.js"
/**## ODButtonManagerIdMappings `interface`
* A list of all available IDs in the default `ODButtonManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODButtonManagerIdMappings extends api.ODButtonManagerIdConstraint {
"opendiscord:verifybar-button":{origin:"verifybar"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:api.ODVerifyBar<string>,verifyButtonId:string,defaultButtonType:"✅"|"❌",useDefaultLabels:boolean,customLabel?:string,customColor?:api.ODValidButtonColor,customEmoji?:string},workers:"opendiscord:verifybar-button"},
"opendiscord:error-ticket-deprecated-transcript":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{},workers:"opendiscord:error-ticket-deprecated-transcript"},
"opendiscord:help-menu-previous":{origin:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu-previous"},
"opendiscord:help-menu-next":{origin:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu-next"},
"opendiscord:help-menu-page":{origin:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu-page"}
"opendiscord:help-menu-switch":{origin:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu-switch"},
"opendiscord:ticket-option":{origin:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODTicketOption},workers:"opendiscord:ticket-option"},
"opendiscord:website-option":{origin:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODWebsiteOption},workers:"opendiscord:website-option"},
"opendiscord:role-option":{origin:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODRoleOption},workers:"opendiscord:role-option"}
"opendiscord:visit-ticket":{origin:"ticket-created"|"dm"|"logs"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:visit-ticket"},
"opendiscord:close-ticket":{origin:"ticket-message"|"reopen-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:close-ticket"},
"opendiscord:delete-ticket":{origin:"ticket-message"|"close-message"|"autoclose-message"|"reopen-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:delete-ticket"},
"opendiscord:reopen-ticket":{origin:"ticket-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:reopen-ticket"},
"opendiscord:claim-ticket":{origin:"ticket-message"|"unclaim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:claim-ticket"},
"opendiscord:unclaim-ticket":{origin:"ticket-message"|"claim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:unclaim-ticket"},
"opendiscord:pin-ticket":{origin:"ticket-message"|"unpin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:pin-ticket"},
"opendiscord:unpin-ticket":{origin:"ticket-message"|"pin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:unpin-ticket"},
"opendiscord:transcript-html-visit":{origin:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,result:ODTranscriptCompilerCompileResult<{url:string,availableUntil:Date}>},workers:"opendiscord:transcript-html-visit"},
"opendiscord:transcript-error-retry":{origin:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,reason:string|null},workers:"opendiscord:transcript-error-retry"},
"opendiscord:transcript-error-continue":{origin:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,reason:string|null},workers:"opendiscord:transcript-error-continue"},
"opendiscord:clear-continue":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[],inProgress:boolean},workers:"opendiscord:clear-continue"},
}
/**## ODDropdownManagerIdMappings `interface`
* A list of all available IDs in the default `ODDropdownManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODDropdownManagerIdMappings extends api.ODDropdownManagerIdConstraint {
"opendiscord:panel-dropdown-tickets":{origin:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,options:ODTicketOption[]},workers:"opendiscord:panel-dropdown-tickets"}
}
/**## ODFileManagerIdMappings `interface`
* A list of all available IDs in the default `ODFileManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODFileManagerIdMappings extends api.ODFileManagerIdConstraint {
"opendiscord:text-transcript":{origin:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,result:ODTranscriptCompilerCompileResult<any>},workers:"opendiscord:text-transcript"}
}
/**## ODEmbedManagerIdMappings `interface`
* A list of all available IDs in the default `ODEmbedManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODEmbedManagerIdMappings extends api.ODEmbedManagerIdConstraint {
"opendiscord:error":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:string,layout:"simple"|"advanced",customTitle?:string},workers:"opendiscord:error"},
"opendiscord:error-option-missing":{origin:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:api.ODTextCommandErrorMissingOption},workers:"opendiscord:error-option-missing"},
"opendiscord:error-option-invalid":{origin:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:api.ODTextCommandErrorInvalidOption},workers:"opendiscord:error-option-invalid"},
"opendiscord:error-unknown-command":{origin:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:api.ODTextCommandErrorUnknownCommand},workers:"opendiscord:error-unknown-command"},
"opendiscord:error-no-permissions":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,permissions:ODPermissionEmbedType[]},workers:"opendiscord:error-no-permissions"},
"opendiscord:error-no-permissions-cooldown":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,until?:Date},workers:"opendiscord:error-no-permissions-cooldown"},
"opendiscord:error-no-permissions-blacklisted":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-no-permissions-blacklisted"},
"opendiscord:error-no-permissions-limits":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,limit:"global"|"global-user"|"option"|"option-user"},workers:"opendiscord:error-no-permissions-limits"},
"opendiscord:error-responder-timeout":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-responder-timeout"},
"opendiscord:error-ticket-unknown":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-ticket-unknown"},
"opendiscord:error-ticket-deprecated":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-ticket-deprecated"},
"opendiscord:error-option-unknown":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-option-unknown"},
"opendiscord:error-panel-unknown":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-panel-unknown"},
"opendiscord:error-not-in-guild":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-not-in-guild"},
"opendiscord:error-channel-rename":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"ticket-pin"|"ticket-unpin"|"ticket-rename"|"ticket-move"|"ticket-priority"|"ticket-transfer"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,originalName:string,newName:string},workers:"opendiscord:error-channel-rename"},
"opendiscord:error-channel-category":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"ticket-create"|"ticket-close"|"ticket-reopen"|"ticket-claim"|"ticket-unclaim"|"ticket-move"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,originalCategory:string,newCategory:string},workers:"opendiscord:error-channel-category"},
"opendiscord:error-ticket-busy":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-ticket-busy"},
"opendiscord:help-menu":{origin:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu"},
"opendiscord:stats-global":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:stats-global"},
"opendiscord:stats-ticket":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,scopeData:ODTicket},workers:"opendiscord:stats-ticket"},
"opendiscord:stats-user":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,scopeData:discord.User},workers:"opendiscord:stats-user"|"opendiscord:easter-egg"},
"opendiscord:stats-reset":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,reason:string|null},workers:"opendiscord:stats-reset"},
"opendiscord:stats-ticket-unknown":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,id:string},workers:"opendiscord:stats-ticket-unknown"},
"opendiscord:panel":{origin:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel},workers:"opendiscord:panel"},
"opendiscord:ticket-created":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created"},
"opendiscord:ticket-created-dm":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created-dm"},
"opendiscord:ticket-created-logs":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created-logs"},
"opendiscord:ticket-message":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-message"},
"opendiscord:close-message":{origin:"slash"|"text"|"ticket-message"|"reopen-message"|"autoclose"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:close-message"},
"opendiscord:reopen-message":{origin:"slash"|"text"|"ticket-message"|"close-message"|"autoclose-message"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:reopen-message"},
"opendiscord:delete-message":{origin:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:delete-message"},
"opendiscord:claim-message":{origin:"slash"|"text"|"ticket-message"|"unclaim-message"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:claim-message"},
"opendiscord:unclaim-message":{origin:"slash"|"text"|"ticket-message"|"claim-message"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:unclaim-message"},
"opendiscord:pin-message":{origin:"slash"|"text"|"ticket-message"|"unpin-message"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:pin-message"},
"opendiscord:unpin-message":{origin:"slash"|"text"|"ticket-message"|"pin-message"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:unpin-message"},
"opendiscord:rename-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:string},workers:"opendiscord:rename-message"},
"opendiscord:move-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:ODTicketOption},workers:"opendiscord:move-message"},
"opendiscord:add-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:discord.User},workers:"opendiscord:add-message"},
"opendiscord:remove-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:discord.User},workers:"opendiscord:remove-message"},
"opendiscord:ticket-action-dm":{origin:"slash"|"text"|"ticket-message"|"close-message"|"reopen-message"|"delete-message"|"claim-message"|"unclaim-message"|"pin-message"|"unpin-message"|"autoclose-message"|"autoclose"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"close"|"reopen"|"delete"|"claim"|"unclaim"|"pin"|"unpin"|"rename"|"move"|"add"|"remove",ticket:ODTicket,reason:string|null,additionalData:null|string|discord.User|ODTicketOption},workers:"opendiscord:ticket-action-dm"},
"opendiscord:ticket-action-logs":{origin:"slash"|"text"|"ticket-message"|"close-message"|"reopen-message"|"delete-message"|"claim-message"|"unclaim-message"|"pin-message"|"unpin-message"|"autoclose-message"|"autoclose"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"close"|"reopen"|"delete"|"claim"|"unclaim"|"pin"|"unpin"|"rename"|"move"|"add"|"remove",ticket:ODTicket,reason:string|null,additionalData:null|string|discord.User|ODTicketOption},workers:"opendiscord:ticket-action-logs"},
"opendiscord:blacklist-view":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:blacklist-view"},
"opendiscord:blacklist-get":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User},workers:"opendiscord:blacklist-get"},
"opendiscord:blacklist-add":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User,reason:string|null},workers:"opendiscord:blacklist-add"},
"opendiscord:blacklist-remove":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User,reason:string|null},workers:"opendiscord:blacklist-remove"}
"opendiscord:blacklist-dm":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-dm"},
"opendiscord:blacklist-logs":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-logs"},
"opendiscord:transcript-text-ready":{origin:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{contents:string},null>,result:ODTranscriptCompilerCompileResult<{contents:string}>},workers:"opendiscord:transcript-text-ready"},
"opendiscord:transcript-html-ready":{origin:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,result:ODTranscriptCompilerCompileResult<{url:string,availableUntil:Date}>},workers:"opendiscord:transcript-html-ready"},
"opendiscord:transcript-html-progress":{origin:"channel"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,remaining:number},workers:"opendiscord:transcript-html-progress"},
"opendiscord:transcript-error":{origin:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,reason:string|null},workers:"opendiscord:transcript-error"},
"opendiscord:reaction-role":{origin:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role"},
"opendiscord:reaction-role-dm":{origin:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role-dm"},
"opendiscord:reaction-role-logs":{origin:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role-logs"},
"opendiscord:clear-verify-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[],inProgress:boolean},workers:"opendiscord:clear-verify-message"},
"opendiscord:clear-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-message"},
"opendiscord:clear-logs":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-logs"},
"opendiscord:autoclose-message":{origin:"timeout"|"leave"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:autoclose-message"},
"opendiscord:autodelete-message":{origin:"timeout"|"leave"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:autodelete-message"},
"opendiscord:autoclose-enable":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,time:number,reason:string|null},workers:"opendiscord:autoclose-enable"},
"opendiscord:autodelete-enable":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,time:number,reason:string|null},workers:"opendiscord:autodelete-enable"},
"opendiscord:autoclose-disable":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:autoclose-disable"},
"opendiscord:autodelete-disable":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:autodelete-disable"},
"opendiscord:topic-set":{origin:"slash"|"text"|"ticket-action"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,topic:string},workers:"opendiscord:topic-set"},
"opendiscord:priority-set":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,priority:ODPriorityLevel,reason:string|null},workers:"opendiscord:priority-set"},
"opendiscord:priority-get":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,priority:ODPriorityLevel},workers:"opendiscord:priority-get"},
"opendiscord:transfer-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,oldCreator:discord.User,newCreator:discord.User,reason:string|null},workers:"opendiscord:transfer-message"},
}
/**## ODMessageManagerIdMappings `interface`
* A list of all available IDs in the default `ODMessageManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODMessageManagerIdMappings extends api.ODMessageManagerIdConstraint {
"opendiscord:error":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:string,layout:"simple"|"advanced",customTitle?:string},workers:"opendiscord:error"},
"opendiscord:error-option-missing":{origin:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:api.ODTextCommandErrorMissingOption},workers:"opendiscord:error-option-missing"},
"opendiscord:error-option-invalid":{origin:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:api.ODTextCommandErrorInvalidOption},workers:"opendiscord:error-option-invalid"},
"opendiscord:error-unknown-command":{origin:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:api.ODTextCommandErrorUnknownCommand},workers:"opendiscord:error-unknown-command"},
"opendiscord:error-no-permissions":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,permissions:ODPermissionEmbedType[]},workers:"opendiscord:error-no-permissions"},
"opendiscord:error-no-permissions-cooldown":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,until?:Date},workers:"opendiscord:error-no-permissions-cooldown"},
"opendiscord:error-no-permissions-blacklisted":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-no-permissions-blacklisted"},
"opendiscord:error-no-permissions-limits":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,limit:"global"|"global-user"|"option"|"option-user"},workers:"opendiscord:error-no-permissions-limits"},
"opendiscord:error-responder-timeout":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-responder-timeout"},
"opendiscord:error-ticket-unknown":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-ticket-unknown"},
"opendiscord:error-ticket-deprecated":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-ticket-deprecated"},
"opendiscord:error-option-unknown":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-option-unknown"},
"opendiscord:error-panel-unknown":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-panel-unknown"},
"opendiscord:error-not-in-guild":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-not-in-guild"},
"opendiscord:error-channel-rename":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"ticket-pin"|"ticket-unpin"|"ticket-rename"|"ticket-move"|"ticket-priority"|"ticket-transfer"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,originalName:string,newName:string},workers:"opendiscord:error-channel-rename"},
"opendiscord:error-channel-category":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"ticket-create"|"ticket-close"|"ticket-reopen"|"ticket-claim"|"ticket-unclaim"|"ticket-move"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,originalCategory:string,newCategory:string},workers:"opendiscord:error-channel-category"},
"opendiscord:error-ticket-busy":{origin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:error-ticket-busy"},
"opendiscord:help-menu":{origin:"slash"|"text"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"opendiscord:help-menu"},
"opendiscord:stats-global":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:stats-global"},
"opendiscord:stats-ticket":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,scopeData:ODTicket},workers:"opendiscord:stats-ticket"},
"opendiscord:stats-user":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,scopeData:discord.User},workers:"opendiscord:stats-user"|"opendiscord:easter-egg"},
"opendiscord:stats-reset":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,reason:string|null},workers:"opendiscord:stats-reset"},
"opendiscord:stats-ticket-unknown":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,id:string},workers:"opendiscord:stats-ticket-unknown"},
"opendiscord:panel":{origin:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel},workers:"opendiscord:panel-layout"|"opendiscord:panel-components"},
"opendiscord:panel-ready":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel},workers:"opendiscord:panel-ready"},
"opendiscord:ticket-created":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created"},
"opendiscord:ticket-created-dm":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created-dm"},
"opendiscord:ticket-created-logs":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-created-logs"},
"opendiscord:ticket-message":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:ticket-message-layout"|"opendiscord:ticket-message-components"|"opendiscord:ticket-message-disable-components"},
"opendiscord:close-message":{origin:"slash"|"text"|"ticket-message"|"reopen-message"|"autoclose"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:close-message"},
"opendiscord:reopen-message":{origin:"slash"|"text"|"ticket-message"|"close-message"|"autoclose-message"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:reopen-message"},
"opendiscord:delete-message":{origin:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:delete-message"},
"opendiscord:claim-message":{origin:"slash"|"text"|"ticket-message"|"unclaim-message"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:claim-message"},
"opendiscord:unclaim-message":{origin:"slash"|"text"|"ticket-message"|"claim-message"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:unclaim-message"},
"opendiscord:pin-message":{origin:"slash"|"text"|"ticket-message"|"unpin-message"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:pin-message"},
"opendiscord:unpin-message":{origin:"slash"|"text"|"ticket-message"|"pin-message"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:unpin-message"},
"opendiscord:rename-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:string},workers:"opendiscord:rename-message"},
"opendiscord:move-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:ODTicketOption},workers:"opendiscord:move-message"},
"opendiscord:add-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:discord.User},workers:"opendiscord:add-message"},
"opendiscord:remove-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:discord.User},workers:"opendiscord:remove-message"},
"opendiscord:ticket-action-dm":{origin:"slash"|"text"|"ticket-message"|"close-message"|"reopen-message"|"delete-message"|"claim-message"|"unclaim-message"|"pin-message"|"unpin-message"|"autoclose-message"|"autoclose"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"close"|"reopen"|"delete"|"claim"|"unclaim"|"pin"|"unpin"|"rename"|"move"|"add"|"remove",ticket:ODTicket,reason:string|null,additionalData:null|string|discord.User|ODTicketOption},workers:"opendiscord:ticket-action-dm"},
"opendiscord:ticket-action-logs":{origin:"slash"|"text"|"ticket-message"|"close-message"|"reopen-message"|"delete-message"|"claim-message"|"unclaim-message"|"pin-message"|"unpin-message"|"autoclose-message"|"autoclose"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"close"|"reopen"|"delete"|"claim"|"unclaim"|"pin"|"unpin"|"rename"|"move"|"add"|"remove",ticket:ODTicket,reason:string|null,additionalData:null|string|discord.User|ODTicketOption},workers:"opendiscord:ticket-action-logs"},
"opendiscord:blacklist-view":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:blacklist-view"},
"opendiscord:blacklist-get":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User},workers:"opendiscord:blacklist-get"},
"opendiscord:blacklist-add":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User,reason:string|null},workers:"opendiscord:blacklist-add"},
"opendiscord:blacklist-remove":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User,reason:string|null},workers:"opendiscord:blacklist-remove"},
"opendiscord:blacklist-dm":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-dm"},
"opendiscord:blacklist-logs":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,mode:"add"|"remove",data:discord.User,reason:string|null},workers:"opendiscord:blacklist-logs"},
"opendiscord:transcript-text-ready":{origin:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{contents:string},null>,result:ODTranscriptCompilerCompileResult<{contents:string}>},workers:"opendiscord:transcript-text-ready"},
"opendiscord:transcript-html-ready":{origin:"channel"|"creator-dm"|"participant-dm"|"active-admin-dm"|"every-admin-dm"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,result:ODTranscriptCompilerCompileResult<{url:string,availableUntil:Date}>},workers:"opendiscord:transcript-html-ready"},
"opendiscord:transcript-html-progress":{origin:"channel"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string,availableUntil:Date},{auth:string}>,remaining:number},workers:"opendiscord:transcript-html-progress"},
"opendiscord:transcript-error":{origin:"slash"|"text"|"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"autodelete"|"clear"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<any,object|null>,reason:string|null},workers:"opendiscord:transcript-error"},
"opendiscord:reaction-role":{origin:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role"},
"opendiscord:reaction-role-dm":{origin:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role-dm"},
"opendiscord:reaction-role-logs":{origin:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:ODRoleUpdateResult[]},workers:"opendiscord:reaction-role-logs"},
"opendiscord:clear-verify-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[],inProgress:boolean},workers:"opendiscord:clear-verify-message"},
"opendiscord:clear-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-message"},
"opendiscord:clear-logs":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"opendiscord:clear-logs"},
"opendiscord:autoclose-message":{origin:"timeout"|"leave"|"verifybar"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:autoclose-message"},
"opendiscord:autodelete-message":{origin:"timeout"|"leave"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},workers:"opendiscord:autodelete-message"},
"opendiscord:autoclose-enable":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,time:number,reason:string|null},workers:"opendiscord:autoclose-enable"},
"opendiscord:autodelete-enable":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,time:number,reason:string|null},workers:"opendiscord:autodelete-enable"},
"opendiscord:autoclose-disable":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:autoclose-disable"},
"opendiscord:autodelete-disable":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"opendiscord:autodelete-disable"},
"opendiscord:topic-set":{origin:"slash"|"text"|"ticket-action"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,topic:string},workers:"opendiscord:topic-set"},
"opendiscord:priority-set":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,priority:ODPriorityLevel,reason:string|null},workers:"opendiscord:priority-set"},
"opendiscord:priority-get":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,priority:ODPriorityLevel},workers:"opendiscord:priority-get"},
"opendiscord:transfer-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,oldCreator:discord.User,newCreator:discord.User,reason:string|null},workers:"opendiscord:transfer-message"},
}
/**## ODModalManagerIdMappings `interface`
* A list of all available IDs in the default `ODModalManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODModalManagerIdMappings extends api.ODModalManagerIdConstraint {
"opendiscord:ticket-questions":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,option:ODTicketOption},workers:"opendiscord:ticket-questions"}
"opendiscord:close-ticket-reason":{origin:"ticket-message"|"reopen-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:close-ticket-reason"}
"opendiscord:reopen-ticket-reason":{origin:"ticket-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:reopen-ticket-reason"}
"opendiscord:delete-ticket-reason":{origin:"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:delete-ticket-reason"}
"opendiscord:claim-ticket-reason":{origin:"ticket-message"|"unclaim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:claim-ticket-reason"}
"opendiscord:unclaim-ticket-reason":{origin:"ticket-message"|"claim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:unclaim-ticket-reason"}
"opendiscord:pin-ticket-reason":{origin:"ticket-message"|"unpin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:pin-ticket-reason"}
"opendiscord:unpin-ticket-reason":{origin:"ticket-message"|"pin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:unpin-ticket-reason"}
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedButtonManager `class
* A special class with types for the Open Ticket `ODButtonManager` class.
*/
export class ODMappedButtonManager extends api.ODButtonManager<ODButtonManagerIdMappings> {}
/**## ODMappedDropdownManager `class
* A special class with types for the Open Ticket `ODDropdownManager` class.
*/
export class ODMappedDropdownManager extends api.ODDropdownManager<ODDropdownManagerIdMappings> {}
/**## ODMappedFileManager `class
* A special class with types for the Open Ticket `ODFileManager` class.
*/
export class ODMappedFileManager extends api.ODFileManager<ODFileManagerIdMappings> {}
/**## ODMappedEmbedManager `class
* A special class with types for the Open Ticket `ODEmbedManager` class.
*/
export class ODMappedEmbedManager extends api.ODEmbedManager<ODEmbedManagerIdMappings> {}
/**## ODMappedMessageManager `class
* A special class with types for the Open Ticket `ODMessageManager` class.
*/
export class ODMappedMessageManager extends api.ODMessageManager<ODMessageManagerIdMappings> {}
/**## ODMappedModalManager `class
* A special class with types for the Open Ticket `ODModalManager` class.
*/
export class ODMappedModalManager extends api.ODModalManager<ODModalManagerIdMappings> {}
/**## ODMappedBuilderManager `class
* A special class with types for the Open Ticket `ODBuilderManager` class.
*/
export class ODMappedBuilderManager extends api.ODBuilderManager<ODButtonManagerIdMappings,ODDropdownManagerIdMappings,ODFileManagerIdMappings,ODEmbedManagerIdMappings,ODMessageManagerIdMappings,ODModalManagerIdMappings> {}
+149
View File
@@ -0,0 +1,149 @@
///////////////////////////////////////
//OPEN TICKET CONFIG CHECKER MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODBCheckerManagerIdMappings `interface`
* A list of all available IDs in the default `ODBCheckerManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODCheckerManagerIdMappings extends api.ODCheckerManagerIdConstraint {
"opendiscord:general":api.ODChecker,
"opendiscord:questions":api.ODChecker,
"opendiscord:options":api.ODChecker,
"opendiscord:panels":api.ODChecker,
"opendiscord:transcripts":api.ODChecker
}
/**## ODCheckerTranslationRegisterOtherIdMappings `type`
* A list of all available IDs in the default `ODCheckerTranslationRegister` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export type ODCheckerTranslationRegisterOtherIdMappings = (
"opendiscord:header-openticket"|
"opendiscord:header-configchecker"|
"opendiscord:header-description"|
"opendiscord:type-error"|
"opendiscord:type-warning"|
"opendiscord:type-info"|
"opendiscord:data-path"|
"opendiscord:data-docs"|
"opendiscord:data-message"|
"opendiscord:compact-information"|
"opendiscord:footer-error"|
"opendiscord:footer-warning"|
"opendiscord:footer-support"
)
/**## ODCheckerTranslationRegisterMessageIdMappings `type`
* A list of all available IDs in the default `ODCheckerTranslationRegister` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export type ODCheckerTranslationRegisterMessageIdMappings = (
"opendiscord:invalid-type"|
"opendiscord:property-missing"|
"opendiscord:property-optional"|
"opendiscord:object-disabled"|
"opendiscord:null-invalid"|
"opendiscord:switch-invalid-type"|
"opendiscord:object-switch-invalid-type"|
"opendiscord:string-too-short"|
"opendiscord:string-too-long"|
"opendiscord:string-length-invalid"|
"opendiscord:string-starts-with"|
"opendiscord:string-ends-with"|
"opendiscord:string-contains"|
"opendiscord:string-inverted-contains"|
"opendiscord:string-choices"|
"opendiscord:string-lowercase"|
"opendiscord:string-uppercase"|
"opendiscord:string-special-characters"|
"opendiscord:string-no-spaces"|
"opendiscord:string-regex"|
"opendiscord:string-capital-word"|
"opendiscord:string-capital-sentence"|
"opendiscord:string-punctuation"|
"opendiscord:number-nan"|
"opendiscord:number-too-short"|
"opendiscord:number-too-long"|
"opendiscord:number-length-invalid"|
"opendiscord:number-too-small"|
"opendiscord:number-too-large"|
"opendiscord:number-not-equal"|
"opendiscord:number-step"|
"opendiscord:number-step-offset"|
"opendiscord:number-starts-with"|
"opendiscord:number-ends-with"|
"opendiscord:number-contains"|
"opendiscord:number-inverted-contains"|
"opendiscord:number-choices"|
"opendiscord:number-float"|
"opendiscord:number-negative"|
"opendiscord:number-positive"|
"opendiscord:number-zero"|
"opendiscord:boolean-true"|
"opendiscord:boolean-false"|
"opendiscord:array-empty-disabled"|
"opendiscord:array-empty-required"|
"opendiscord:array-too-short"|
"opendiscord:array-too-long"|
"opendiscord:array-length-invalid"|
"opendiscord:array-invalid-types"|
"opendiscord:array-double"|
"opendiscord:discord-invalid-id"|
"opendiscord:discord-invalid-id-options"|
"opendiscord:discord-invalid-token"|
"opendiscord:color-invalid"|
"opendiscord:emoji-too-short"|
"opendiscord:emoji-too-long"|
"opendiscord:emoji-custom"|
"opendiscord:emoji-invalid"|
"opendiscord:url-invalid"|
"opendiscord:url-invalid-http"|
"opendiscord:url-invalid-protocol"|
"opendiscord:url-invalid-hostname"|
"opendiscord:url-invalid-extension"|
"opendiscord:url-invalid-path"|
"opendiscord:id-not-unique"|
"opendiscord:id-non-existent"|
"opendiscord:invalid-language"|
"opendiscord:invalid-button"|
"opendiscord:unused-option"|
"opendiscord:unused-question"|
"opendiscord:dropdown-option"
)
/**## ODCheckerFunctionManagerIdMappings `type`
* A list of all available IDs in the default `ODCheckerFunctionManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODCheckerFunctionManagerIdMappings extends api.ODCheckerFunctionManagerIdConstraint {
"opendiscord:unused-options":api.ODCheckerFunction,
"opendiscord:unused-questions":api.ODCheckerFunction,
"opendiscord:dropdown-options":api.ODCheckerFunction
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedCheckerManager `class
* A special class with types for the Open Ticket `ODCheckerManager` class.
*/
export class ODMappedCheckerManager extends api.ODCheckerManager<ODCheckerManagerIdMappings,ODCheckerFunctionManagerIdMappings,api.ODDefaultCheckerRenderer,ODCheckerTranslationRegisterMessageIdMappings,ODCheckerTranslationRegisterOtherIdMappings> {}
/**## ODMappedCheckerFunctionManager `class
* A special class with types for the Open Ticket `ODCheckerFunctionManager` class.
*/
export class ODMappedCheckerFunctionManager extends api.ODCheckerFunctionManager<ODCheckerFunctionManagerIdMappings> {}
/**## ODMappedCheckerTranslationRegister `class
* A special class with types for the Open Ticket `ODCheckerTranslationRegister` class.
*/
export class ODMappedCheckerTranslationRegister extends api.ODCheckerTranslationRegister<ODCheckerTranslationRegisterMessageIdMappings,ODCheckerTranslationRegisterOtherIdMappings> {}
+103
View File
@@ -0,0 +1,103 @@
///////////////////////////////////////
//OPEN TICKET CLIENT MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODSlashCommandManagerIdMappings `interface`
* A list of all available IDs in the default `ODSlashCommandManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODSlashCommandManagerIdMappings extends api.ODSlashCommandManagerIdConstraint {
"opendiscord:help":api.ODSlashCommand,
"opendiscord:panel":api.ODSlashCommand,
"opendiscord:ticket":api.ODSlashCommand,
"opendiscord:close":api.ODSlashCommand,
"opendiscord:delete":api.ODSlashCommand,
"opendiscord:reopen":api.ODSlashCommand,
"opendiscord:claim":api.ODSlashCommand,
"opendiscord:unclaim":api.ODSlashCommand,
"opendiscord:pin":api.ODSlashCommand,
"opendiscord:unpin":api.ODSlashCommand,
"opendiscord:move":api.ODSlashCommand,
"opendiscord:rename":api.ODSlashCommand,
"opendiscord:add":api.ODSlashCommand,
"opendiscord:remove":api.ODSlashCommand,
"opendiscord:blacklist":api.ODSlashCommand,
"opendiscord:stats":api.ODSlashCommand,
"opendiscord:clear":api.ODSlashCommand,
"opendiscord:autoclose":api.ODSlashCommand,
"opendiscord:autodelete":api.ODSlashCommand,
"opendiscord:topic":api.ODSlashCommand,
"opendiscord:priority":api.ODSlashCommand,
"opendiscord:transfer":api.ODSlashCommand,
}
/**## ODTextCommandManagerIdMappings `interface`
* A list of all available IDs in the default `ODTextCommandManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODTextCommandManagerIdMappings extends api.ODTextCommandManagerIdConstraint {
"opendiscord:dump":api.ODTextCommand,
"opendiscord:help":api.ODTextCommand,
"opendiscord:panel":api.ODTextCommand,
"opendiscord:close":api.ODTextCommand,
"opendiscord:delete":api.ODTextCommand,
"opendiscord:reopen":api.ODTextCommand,
"opendiscord:claim":api.ODTextCommand,
"opendiscord:unclaim":api.ODTextCommand,
"opendiscord:pin":api.ODTextCommand,
"opendiscord:unpin":api.ODTextCommand,
"opendiscord:move":api.ODTextCommand,
"opendiscord:rename":api.ODTextCommand,
"opendiscord:add":api.ODTextCommand,
"opendiscord:remove":api.ODTextCommand,
"opendiscord:blacklist-view":api.ODTextCommand,
"opendiscord:blacklist-add":api.ODTextCommand,
"opendiscord:blacklist-remove":api.ODTextCommand,
"opendiscord:blacklist-get":api.ODTextCommand,
"opendiscord:stats-global":api.ODTextCommand,
"opendiscord:stats-reset":api.ODTextCommand,
"opendiscord:stats-ticket":api.ODTextCommand,
"opendiscord:stats-user":api.ODTextCommand,
"opendiscord:clear":api.ODTextCommand,
"opendiscord:autoclose-disable":api.ODTextCommand,
"opendiscord:autoclose-enable":api.ODTextCommand,
"opendiscord:autodelete-disable":api.ODTextCommand,
"opendiscord:autodelete-enable":api.ODTextCommand,
"opendiscord:topic-set":api.ODTextCommand,
"opendiscord:priority-set":api.ODTextCommand,
"opendiscord:priority-get":api.ODTextCommand,
"opendiscord:transfer":api.ODTextCommand,
}
/**## ODContextMenuManagerIdMappings `interface`
* A list of all available IDs in the default `ODContextMenuManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODContextMenuManagerIdMappings extends api.ODContextMenuManagerIdConstraint {
//"opendiscord:test-menu":ODContextMenu
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedClientManager `class
* A special class with types for the Open Ticket `ODClientManager` class.
*/
export class ODMappedClientManager extends api.ODClientManager<ODSlashCommandManagerIdMappings,ODTextCommandManagerIdMappings,ODContextMenuManagerIdMappings> {}
/**## ODMappedSlashCommandManager `class
* A special class with types for the Open Ticket `ODSlashCommandManager` class.
*/
export class ODMappedSlashCommandManager extends api.ODSlashCommandManager<ODSlashCommandManagerIdMappings> {}
/**## ODMappedTextCommandManager `class
* A special class with types for the Open Ticket `ODTextCommandManager` class.
*/
export class ODMappedTextCommandManager extends api.ODTextCommandManager<ODTextCommandManagerIdMappings> {}
/**## ODMappedContextMenuManager `class
* A special class with types for the Open Ticket `ODContextMenuManager` class.
*/
export class ODMappedContextMenuManager extends api.ODContextMenuManager<ODContextMenuManagerIdMappings> {}
+36
View File
@@ -0,0 +1,36 @@
///////////////////////////////////////
//OPEN TICKET CODE MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODCodeManagerIdMappings `interface`
* A list of all available IDs in the default `ODCodeManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODCodeManagerIdMappings extends api.ODCodeManagerIdConstraint {
"opendiscord:command-error-handling":api.ODCode,
"opendiscord:start-listening-interactions":api.ODCode,
"opendiscord:panel-database-cleaner":api.ODCode,
"opendiscord:suffix-database-cleaner":api.ODCode,
"opendiscord:option-database-cleaner":api.ODCode,
"opendiscord:user-database-cleaner":api.ODCode,
"opendiscord:ticket-database-cleaner":api.ODCode,
"opendiscord:panel-auto-update":api.ODCode,
"opendiscord:ticket-saver":api.ODCode,
"opendiscord:blacklist-saver":api.ODCode,
"opendiscord:auto-role-on-join":api.ODCode,
"opendiscord:autoclose-timeout":api.ODCode,
"opendiscord:autoclose-leave":api.ODCode,
"opendiscord:autodelete-timeout":api.ODCode,
"opendiscord:autodelete-leave":api.ODCode,
"opendiscord:ticket-anti-busy":api.ODCode,
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedCodeManager `class
* A special class with types for the Open Ticket `ODCodeManager` class.
*/
export class ODMappedCodeManager extends api.ODCodeManager<ODCodeManagerIdMappings> {}
+72
View File
@@ -0,0 +1,72 @@
///////////////////////////////////////
//OPEN TICKET COMPONENT MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
import * as discord from "discord.js"
/**## ODSharedComponentManagerIdMappings `interface`
* A list of all available IDs in the default `ODSharedComponentManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODSharedComponentManagerIdMappings extends api.ODComponentManagerIdConstraint {
//"opendiscord:example-component":{origin:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:example-component"},
}
/**## ODMessageComponentManagerIdMappings `interface`
* A list of all available IDs in the default `ODMessageComponentManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODMessageComponentManagerIdMappings extends api.ODComponentManagerIdConstraint {
//"opendiscord:example-message":{origin:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:example-message"},
}
/**## ODModalComponentManagerIdMappings `interface`
* A list of all available IDs in the default `ODModalComponentManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODModalComponentManagerIdMappings extends api.ODComponentManagerIdConstraint {
//"opendiscord:example-modal":{origin:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:example-modal"},
}
/**## ODComponentModifierManagerIdMappings `interface`
* A list of all available IDs in the default `ODComponentModifierManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODComponentModifierManagerIdMappings extends api.ODComponentModifierManagerIdConstraint {
"opendiscord:close-ticket-verifybar":api.ODMessageComponentModifier<"ticket-message"|"reopen-message",{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:api.ODVerifyBar<string>},string>,
"opendiscord:reopen-ticket-verifybar":api.ODMessageComponentModifier<"ticket-message"|"close-message"|"autoclose-message",{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:api.ODVerifyBar<string>},string>,
"opendiscord:delete-ticket-verifybar":api.ODMessageComponentModifier<"ticket-message"|"close-message"|"autoclose-message"|"reopen-message",{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:api.ODVerifyBar<string>},string>,
"opendiscord:claim-ticket-verifybar":api.ODMessageComponentModifier<"ticket-message"|"unclaim-message",{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:api.ODVerifyBar<string>},string>,
"opendiscord:unclaim-ticket-verifybar":api.ODMessageComponentModifier<"ticket-message"|"claim-message",{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:api.ODVerifyBar<string>},string>,
"opendiscord:pin-ticket-verifybar":api.ODMessageComponentModifier<"ticket-message"|"unpin-message",{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:api.ODVerifyBar<string>},string>,
"opendiscord:unpin-ticket-verifybar":api.ODMessageComponentModifier<"ticket-message"|"pin-message",{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:api.ODVerifyBar<string>},string>,
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedSharedComponentManager `class
* A special class with types for the Open Ticket `ODSharedComponentManager` class.
*/
export class ODMappedSharedComponentManager extends api.ODSharedComponentManager<ODSharedComponentManagerIdMappings> {}
/**## ODMappedMessageComponentManager `class
* A special class with types for the Open Ticket `ODMessageComponentManager` class.
*/
export class ODMappedMessageComponentManager extends api.ODMessageComponentManager<ODMessageComponentManagerIdMappings> {}
/**## ODMappedModalComponentManager `class
* A special class with types for the Open Ticket `ODModalComponentManager` class.
*/
export class ODMappedModalComponentManager extends api.ODModalComponentManager<ODModalComponentManagerIdMappings> {}
/**## ODMappedComponentModifierManager `class
* A special class with types for the Open Ticket `ODComponentModifierManager` class.
*/
export class ODMappedComponentModifierManager extends api.ODComponentModifierManager<ODComponentModifierManagerIdMappings> {}
/**## ODMappedComponentManager `class
* A special class with types for the Open Ticket `ODBuilderManager` class.
*/
export class ODMappedComponentManager extends api.ODComponentManager<ODSharedComponentManagerIdMappings,ODMessageComponentManagerIdMappings,ODModalComponentManagerIdMappings,ODComponentModifierManagerIdMappings> {}
@@ -1,130 +1,74 @@
///////////////////////////////////////
//DEFAULT CONFIG MODULE
//OPEN TICKET CONFIG MAPPINGS
///////////////////////////////////////
import { ODValidButtonColor, ODValidId } from "../modules/base"
import * as api from "@open-discord-bots/framework/api"
import * as discord from "discord.js"
import { ODConfigManager, ODConfig, ODJsonConfig } from "../modules/config"
import { ODClientActivityMode, ODClientActivityType } from "../modules/client"
import { ODRoleUpdateMode } from "../openticket/role"
import { ODRoleUpdateMode } from "../api/role.js"
/** (CONTRIBUTOR GUIDE) HOW TO ADD NEW CONFIG VARIABLES?
* - Make the change to the config file in (./config/) and be aware of the following things:
* - The variable has a clear name and its function is obvious.
* - The variable is in the correct position/category of the config.
* - The variable contains a default placeholder to suggest the contents.
* - If there's a (./devconfig/), also modify this file.
* - Register the config in loadAllConfigs() in (./src/data/framework/configLoader.ts)
* - The variable should be added to the "formatters" in the correct position.
* - Add autocomplete for the variable in ODJsonConfig_Default... in (./src/core/api/defaults/config.ts)
* - Add the variable to the config checker in (./src/data/framework/checkerLoader.ts)
* - Make sure the variable is compatible with the Interactive Setup CLI.
* - The variable should be added by the migration manager (./src/core/startup/migration.ts) when missing.
* - Update the Open Ticket Documentation.
*
* IF VARIABLE IS FROM questions.json, options.json OR panels.json:
* - Check (./src/data/openticket/...) for loading/unloading of data.
* - Check (./src/actions/createTicket.ts) and related files.
* - Check (./src/builders), (./src/actions), (./src/data) & (./src/commands) in general in the areas that were changed.
*/
/**## ODConfigManagerIds_Default `interface`
* This interface is a list of ids available in the `ODConfigManager_Default` class.
/**## ODConfigManagerIdMappings `interface`
* A list of all available IDs in the default `ODConfigManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODConfigManagerIds_Default {
"opendiscord:general":ODJsonConfig_DefaultGeneral,
"opendiscord:questions":ODJsonConfig_DefaultQuestions,
"opendiscord:options":ODJsonConfig_DefaultOptions,
"opendiscord:panels":ODJsonConfig_DefaultPanels,
"opendiscord:transcripts":ODJsonConfig_DefaultTranscripts
export interface ODConfigManagerIdMappings extends api.ODConfigManagerIdConstraint {
"opendiscord:general":ODGeneralJsonCommentsConfig,
"opendiscord:questions":ODQuestionsJsonCommentsConfig,
"opendiscord:options":ODOptionsJsonCommentsConfig,
"opendiscord:panels":ODPanelsJsonCommentsConfig,
"opendiscord:transcripts":ODTranscriptsJsonCommentsConfig
}
/**## ODConfigManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODConfigManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.configs`!
*/
export class ODConfigManager_Default extends ODConfigManager {
get<ConfigId extends keyof ODConfigManagerIds_Default>(id:ConfigId): ODConfigManagerIds_Default[ConfigId]
get(id:ODValidId): ODConfig|null
get(id:ODValidId): ODConfig|null {
return super.get(id)
}
remove<ConfigId extends keyof ODConfigManagerIds_Default>(id:ConfigId): ODConfigManagerIds_Default[ConfigId]
remove(id:ODValidId): ODConfig|null
remove(id:ODValidId): ODConfig|null {
return super.remove(id)
}
///////////////////////////////////////
// CONFIG STRUCTURES, VALUES & TYPES
// --> general.jsonc
///////////////////////////////////////
exists(id:keyof ODConfigManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## ODJsonConfig_DefaultStatusType `interface`
* This interface is an object which has all properties for the status object in the `general.json` config!
/**## ODGeneralJsonConfig_Status `interface`
* This interface is an object which has all properties for the status object in the `general.jsonc` config!
*/
export interface ODJsonConfig_DefaultStatusType {
export interface ODGeneralJsonConfig_Status {
/**Is the status enabled? */
enabled:boolean,
/**The type of status (e.g. playing, listening, custom, ...) */
type:Exclude<ODClientActivityType,false>,
type:Exclude<api.ODClientActivityType,false>,
/**The mode/status of the bot (e.g. online, invisible, idle, do not disturb) */
mode:ODClientActivityMode
mode:api.ODClientActivityMode
/**The text for the status. */
text:string,
/**Additional text for the status. (visible below 'text') */
state:string,
}
/**## ODJsonConfig_DefaultMessageSettingsType `interface`
* This interface is an object which has all properties for the "system"."messages".... object in the `general.json` config!
/**## ODGeneralJsonConfig_MessageSettings `interface`
* This interface is an object which has all properties for the "system"."messages".... object in the `general.jsonc` config!
*/
export interface ODJsonConfig_DefaultMessageSettingsType {
export interface ODGeneralJsonConfig_MessageSettings {
/**Enable sending DM logs to the ticket creator for this action. */
dm:boolean,
/**Enable sending logsto the log channel for this action. */
logs:boolean
}
/**## ODJsonConfig_DefaultCmdPermissionSettingsType `type`
* This type is a collection of command permission settings for the "system"."permissions".... object in the `general.json` config!
/**## ODGeneralJsonConfig_CmdPermissionSettingsType `type`
* This type is a collection of command permission settings for the "system"."permissions".... object in the `general.jsonc` config!
*/
export type ODJsonConfig_DefaultCmdPermissionSettingsType = "admin"|"everyone"|"none"|string
export type ODGeneralJsonConfig_CmdPermissionSettingsType = "admin"|"everyone"|"none"|string
/**## ODJsonConfig_DefaultInfo `interface`
* This object contains a few URLs and metadata for the config.
*/
export interface ODJsonConfig_DefaultInfo {
/**A link to the Open Ticket documentation. */
support:string,
/**A link to the DJdj Development discord server. */
discord:string,
/**The version of Open Ticket this config is compatible with. */
version:string
}
/**## ODJsonConfig_DefaultSystemLogs `interface`
/**## ODGeneralJsonConfig_SystemLogs `interface`
* All settings related to the log channel.
*/
export interface ODJsonConfig_DefaultSystemLogs {
export interface ODGeneralJsonConfig_SystemLogs {
/**Enable logging. Individual actions should still be added via the `"system"."messages"..."logs"` */
enabled:boolean,
/**The channel to send logs to. */
channel:string
channel:string,
/**Configure dm & log messages for all Open Ticket commands & actions. */
logMessages:ODGeneralJsonConfig_LogMessages
}
/**## ODJsonConfig_DefaultSystemLimits `interface`
/**## ODGeneralJsonConfig_SystemLimits `interface`
* All settings related to global ticket limits.
*/
export interface ODJsonConfig_DefaultSystemLimits {
export interface ODGeneralJsonConfig_SystemLimits {
/**Enable global ticket limits. */
enabled:boolean,
/**The maximum amount of tickets that are allowed in the server at the same time. */
@@ -133,10 +77,10 @@ export interface ODJsonConfig_DefaultSystemLimits {
userMaximum:number
}
/**## ODJsonConfig_DefaultSystemChannelTopic `interface`
/**## ODGeneralJsonConfig_SystemChannelTopic `interface`
* All global channel topic settings.
*/
export interface ODJsonConfig_DefaultSystemChannelTopic {
export interface ODGeneralJsonConfig_SystemChannelTopic {
/**Show the option name in the channel topic. */
showOptionName:boolean,
/**Show the option description in the channel topic. */
@@ -157,59 +101,60 @@ export interface ODJsonConfig_DefaultSystemChannelTopic {
showParticipants:boolean
}
/**## ODJsonConfig_DefaultSystemPermissions `interface`
/**## ODGeneralJsonConfig_SystemPermissions `interface`
* Configure permissions for all Open Ticket commands & actions.
*/
export interface ODJsonConfig_DefaultSystemPermissions {
help:ODJsonConfig_DefaultCmdPermissionSettingsType,
panel:ODJsonConfig_DefaultCmdPermissionSettingsType,
ticket:ODJsonConfig_DefaultCmdPermissionSettingsType,
close:ODJsonConfig_DefaultCmdPermissionSettingsType,
delete:ODJsonConfig_DefaultCmdPermissionSettingsType,
reopen:ODJsonConfig_DefaultCmdPermissionSettingsType,
claim:ODJsonConfig_DefaultCmdPermissionSettingsType,
unclaim:ODJsonConfig_DefaultCmdPermissionSettingsType,
pin:ODJsonConfig_DefaultCmdPermissionSettingsType,
unpin:ODJsonConfig_DefaultCmdPermissionSettingsType,
move:ODJsonConfig_DefaultCmdPermissionSettingsType,
rename:ODJsonConfig_DefaultCmdPermissionSettingsType,
add:ODJsonConfig_DefaultCmdPermissionSettingsType,
remove:ODJsonConfig_DefaultCmdPermissionSettingsType,
blacklist:ODJsonConfig_DefaultCmdPermissionSettingsType,
stats:ODJsonConfig_DefaultCmdPermissionSettingsType,
clear:ODJsonConfig_DefaultCmdPermissionSettingsType,
autoclose:ODJsonConfig_DefaultCmdPermissionSettingsType,
autodelete:ODJsonConfig_DefaultCmdPermissionSettingsType,
transfer:ODJsonConfig_DefaultCmdPermissionSettingsType,
topic:ODJsonConfig_DefaultCmdPermissionSettingsType,
priority:ODJsonConfig_DefaultCmdPermissionSettingsType,
export interface ODGeneralJsonConfig_SystemPermissions {
help:ODGeneralJsonConfig_CmdPermissionSettingsType,
panel:ODGeneralJsonConfig_CmdPermissionSettingsType,
ticket:ODGeneralJsonConfig_CmdPermissionSettingsType,
close:ODGeneralJsonConfig_CmdPermissionSettingsType,
delete:ODGeneralJsonConfig_CmdPermissionSettingsType,
reopen:ODGeneralJsonConfig_CmdPermissionSettingsType,
claim:ODGeneralJsonConfig_CmdPermissionSettingsType,
unclaim:ODGeneralJsonConfig_CmdPermissionSettingsType,
pin:ODGeneralJsonConfig_CmdPermissionSettingsType,
unpin:ODGeneralJsonConfig_CmdPermissionSettingsType,
move:ODGeneralJsonConfig_CmdPermissionSettingsType,
rename:ODGeneralJsonConfig_CmdPermissionSettingsType,
add:ODGeneralJsonConfig_CmdPermissionSettingsType,
remove:ODGeneralJsonConfig_CmdPermissionSettingsType,
blacklist:ODGeneralJsonConfig_CmdPermissionSettingsType,
stats:ODGeneralJsonConfig_CmdPermissionSettingsType,
clear:ODGeneralJsonConfig_CmdPermissionSettingsType,
autoclose:ODGeneralJsonConfig_CmdPermissionSettingsType,
autodelete:ODGeneralJsonConfig_CmdPermissionSettingsType,
transfer:ODGeneralJsonConfig_CmdPermissionSettingsType,
topic:ODGeneralJsonConfig_CmdPermissionSettingsType,
priority:ODGeneralJsonConfig_CmdPermissionSettingsType,
transcripts:ODGeneralJsonConfig_CmdPermissionSettingsType,
}
/**## ODJsonConfig_DefaultSystemMessages `interface`
/**## ODGeneralJsonConfig_LogMessages `interface`
* Configure dm & log messages for all Open Ticket commands & actions.
*/
export interface ODJsonConfig_DefaultSystemMessages {
creation:ODJsonConfig_DefaultMessageSettingsType,
closing:ODJsonConfig_DefaultMessageSettingsType,
deleting:ODJsonConfig_DefaultMessageSettingsType,
reopening:ODJsonConfig_DefaultMessageSettingsType,
claiming:ODJsonConfig_DefaultMessageSettingsType,
pinning:ODJsonConfig_DefaultMessageSettingsType,
adding:ODJsonConfig_DefaultMessageSettingsType,
removing:ODJsonConfig_DefaultMessageSettingsType,
renaming:ODJsonConfig_DefaultMessageSettingsType,
moving:ODJsonConfig_DefaultMessageSettingsType,
blacklisting:ODJsonConfig_DefaultMessageSettingsType,
transferring:ODJsonConfig_DefaultMessageSettingsType,
topicChange:ODJsonConfig_DefaultMessageSettingsType,
priorityChange:ODJsonConfig_DefaultMessageSettingsType,
reactionRole:ODJsonConfig_DefaultMessageSettingsType,
export interface ODGeneralJsonConfig_LogMessages {
creation:ODGeneralJsonConfig_MessageSettings,
closing:ODGeneralJsonConfig_MessageSettings,
deleting:ODGeneralJsonConfig_MessageSettings,
reopening:ODGeneralJsonConfig_MessageSettings,
claiming:ODGeneralJsonConfig_MessageSettings,
pinning:ODGeneralJsonConfig_MessageSettings,
adding:ODGeneralJsonConfig_MessageSettings,
removing:ODGeneralJsonConfig_MessageSettings,
renaming:ODGeneralJsonConfig_MessageSettings,
moving:ODGeneralJsonConfig_MessageSettings,
blacklisting:ODGeneralJsonConfig_MessageSettings,
transferring:ODGeneralJsonConfig_MessageSettings,
topicChange:ODGeneralJsonConfig_MessageSettings,
priorityChange:ODGeneralJsonConfig_MessageSettings,
reactionRole:ODGeneralJsonConfig_MessageSettings,
}
/**## ODJsonConfig_DefaultSystem `interface`
/**## ODGeneralJsonConfig_TicketSystem `interface`
* All settings related to the ticket system.
*/
export interface ODJsonConfig_DefaultSystem {
export interface ODGeneralJsonConfig_TicketSystem {
/**Prefer slash-commands over text-commands when displaying them in menu's and messages. */
preferSlashOverText:boolean,
/**Reply with "unknown command" when the prefix is used without a valid command. */
@@ -230,6 +175,8 @@ export interface ODJsonConfig_DefaultSystem {
emojiStyle:"before"|"after"|"double"|"disabled",
/**The emoji used when pinning tickets. This is '📌' by default. */
pinEmoji:string,
/**The emoji used when closing tickets. This is '🔒' by default. */
closeEmoji:string,
/**Reply with an ephemeral message when a ticket is created. */
replyOnTicketCreation:boolean,
@@ -266,29 +213,40 @@ export interface ODJsonConfig_DefaultSystem {
enableTicketActionWithReason:boolean,
/**Enable/disable the delete without transcript feature (button & /delete command). */
enableDeleteWithoutTranscript:boolean,
/**All settings related to the log channel. */
logs:ODJsonConfig_DefaultSystemLogs,
/**Enable/disable creating tickets for other users with /ticket <user>. (ADMIN ONLY) */
enableCreateTicketForOtherUser:boolean,
/**All settings related to global ticket limits. */
limits:ODJsonConfig_DefaultSystemLimits,
limits:ODGeneralJsonConfig_SystemLimits,
/**All global channel topic settings. */
channelTopic:ODJsonConfig_DefaultSystemChannelTopic,
channelTopic:ODGeneralJsonConfig_SystemChannelTopic,
/**Configure permissions for all Open Ticket commands & actions. */
permissions:ODJsonConfig_DefaultSystemPermissions,
/**Configure dm & log messages for all Open Ticket commands & actions. */
messages:ODJsonConfig_DefaultSystemMessages
/**Move closed tickets to this channel category. */
closedCategory:{
enabled:boolean
categoryId:string
},
/**Create tickets in this channel category when the original category is full (max 50 channels). */
backupCategory:{
enabled:boolean
categoryId:string
},
/**Move claimed tickets to the matching channel category of the user that claimed the ticket. */
claimedCategories:{
/**The user who claimed the ticket. */
user:string,
/**The category to move the ticket to. */
category:string
}[],
}
/**## ODJsonConfig_DefaultGeneralData `interface`
* All contents of the `general.json` config file.
/**## ODGeneralJsonConfig_GeneralData `interface`
* All contents of the `general.jsonc` config file.
*/
export interface ODJsonConfig_DefaultGeneralData {
export interface ODGeneralJsonConfig_GeneralData {
/**This object contains a few URLs and metadata for the config. */
_INFO:ODJsonConfig_DefaultInfo,
_CONFIG_VERSION:string,
/**The token of the bot. (Empty when using `tokenFromENV`) */
token:string,
@@ -312,26 +270,27 @@ export interface ODJsonConfig_DefaultGeneralData {
textCommands:boolean,
/**All settings related to the status of the bot. */
status:ODJsonConfig_DefaultStatusType,
status:ODGeneralJsonConfig_Status,
/**All settings related to the ticket system. */
system:ODJsonConfig_DefaultSystem
ticketSystem:ODGeneralJsonConfig_TicketSystem,
/**Configure permissions for all Open Ticket commands & actions. */
permissions:ODGeneralJsonConfig_SystemPermissions,
/**All settings related to the log channel. */
logs:ODGeneralJsonConfig_SystemLogs,
}
/**## ODJsonConfig_DefaultGeneral `default_class`
* This is a special class that adds type definitions & typescript to the ODJsonConfig class.
* It doesn't add any extra features!
*
* This default class is made for the `general.json` config!
*/
export class ODJsonConfig_DefaultGeneral extends ODJsonConfig {
declare data: ODJsonConfig_DefaultGeneralData
}
///////////////////////////////////////
// CONFIG STRUCTURES, VALUES & TYPES
// --> options.jsonc
///////////////////////////////////////
/**## ODJsonConfig_DefaultOptionType `interface`
* This interface is an object which has all basic properties for options in the `options.json` config!
/**## ODOptionsJsonConfig_BaseOption `interface`
* The basic properties for options in the `options.jsonc` config!
*/
export interface ODJsonConfig_DefaultOptionType {
export interface ODOptionsJsonConfig_BaseOption {
/**The id of this option. */
id:string,
/**The name of this option. */
@@ -339,7 +298,7 @@ export interface ODJsonConfig_DefaultOptionType {
/**The description of this option. */
description:string,
/**The type of this option. This type also determines the other option-specific variables. */
type:"ticket"|"website"|"role",
type:"ticket"|"website"|"role"|"sub-panel",
/**All settings related to the button for the 3 option types. */
button:{
/**The emoji of the button. (can also be empty) */
@@ -349,22 +308,22 @@ export interface ODJsonConfig_DefaultOptionType {
}
}
/**## ODJsonConfig_DefaultOptionButtonSettingsType `interface`
* This interface is an object which has all button settings for ticket & reaction role options in the `options.json` config!
/**## ODOptionsJsonConfig_OptionButtonSettings `interface`
* The button settings for ticket, sub-panel & reaction role options in the `options.jsonc` config!
*/
export interface ODJsonConfig_DefaultOptionButtonSettingsType {
export interface ODOptionsJsonConfig_OptionButtonSettings {
/**The emoji of the button. (can also be empty) */
emoji:string,
/**The label of the button (can also be empty) */
label:string,
/**The color of the button (not available in options with the 'website' type!) */
color:ODValidButtonColor
color:api.ODValidButtonColor
}
/**## ODJsonConfig_DefaultOptionEmbedSettingsType `interface`
* This interface is an object which has all message embed settings for ticket options in the `options.json` config!
/**## ODOptionsJsonConfig_TicketOptionEmbedSettings `interface`
* The message embed settings for ticket options in the `options.jsonc` config!
*/
export interface ODJsonConfig_DefaultOptionEmbedSettingsType {
export interface ODOptionsJsonConfig_TicketOptionEmbedSettings {
/**Is this embed enabled? */
enabled:boolean,
/**The title of the embed. */
@@ -390,10 +349,10 @@ export interface ODJsonConfig_DefaultOptionEmbedSettingsType {
timestamp:boolean
}
/**## ODJsonConfig_DefaultOptionPingSettingsType `interface`
* This interface is an object which has all message ping settings for ticket options in the `options.json` config!
/**## ODOptionsJsonConfig_TicketOptionPingSettings `interface`
* The message ping settings for ticket options in the `options.jsonc` config!
*/
export interface ODJsonConfig_DefaultOptionPingSettingsType {
export interface ODOptionsJsonConfig_TicketOptionPingSettings {
/**Ping `@here`. */
"@here":boolean,
/**Ping `@everyone`. */
@@ -402,47 +361,36 @@ export interface ODJsonConfig_DefaultOptionPingSettingsType {
custom:string[]
}
/**## ODJsonConfig_DefaultOptionTicketChannelType `interface`
/**## ODOptionsJsonConfig_TicketOptionChannelSettings `interface`
* All settings related to the ticket channel itself in a ticket option.
*/
export interface ODJsonConfig_DefaultOptionTicketChannelType {
export interface ODOptionsJsonConfig_TicketOptionChannelSettings {
/**The prefix used in the name of this ticket channel. */
prefix:string,
/**The type of suffix used in the name of this ticket channel. */
suffix:"user-name"|"user-nickname"|"user-id"|"random-number"|"random-hex"|"counter-dynamic"|"counter-fixed",
/**An optional discord category id to create this ticket in. */
category:string,
/**An optional discord category id to move this ticket to when closed. */
closedCategory:string,
/**An optional discord category id to create this ticket in when the primary one is full (max. 50 tickets). */
backupCategory:string,
/**A list of discord category ids to move this ticket to when claimed by a specific user. */
claimedCategory:{
/**The user which claimed the ticket. */
user:string,
/**The category to move the ticket to when claimed by this user. */
category:string
}[],
/**The channel topic shown at the top of the channel in discord. */
topic:string
}
/**## ODJsonConfig_DefaultOptionTicketType `interface`
* This interface is an object which has all ticket properties for options in the `options.json` config!
/**## ODOptionsJsonConfig_TicketOption `interface`
* All properties for ticket options in the `options.jsonc` config!
*/
export interface ODJsonConfig_DefaultOptionTicketType extends ODJsonConfig_DefaultOptionType {
export interface ODOptionsJsonConfig_TicketOption extends ODOptionsJsonConfig_BaseOption {
type:"ticket",
button:ODJsonConfig_DefaultOptionButtonSettingsType,
button:ODOptionsJsonConfig_OptionButtonSettings,
/**A list of discord role ids which are able to access this ticket type & use commands. */
ticketAdmins:string[],
/**A list of discord role ids which are able to access this ticket type but can't write in the chat. */
readonlyAdmins:string[],
/**When enabled, blacklisted users can still create this ticket type. (used for appeals, etc) */
allowCreationByBlacklistedUsers:boolean,
/**A list of valid question ids from the `questions.json` config. */
/**A list of valid question ids from the `questions.jsonc` config. */
questions:string[],
/**All settings related to the ticket channel itself. */
channel:ODJsonConfig_DefaultOptionTicketChannelType,
channel:ODOptionsJsonConfig_TicketOptionChannelSettings,
/**All settings related to the message sent in DM to the creator when the ticket is created. */
dmMessage:{
/**Enable this message. */
@@ -450,7 +398,7 @@ export interface ODJsonConfig_DefaultOptionTicketType extends ODJsonConfig_Defau
/**The raw text contents of this message. (empty for embed only) */
text:string,
/**The embed of this message. */
embed:ODJsonConfig_DefaultOptionEmbedSettingsType
embed:ODOptionsJsonConfig_TicketOptionEmbedSettings
},
/**All settings related to the message sent in the ticket channel when the ticket is created. */
ticketMessage:{
@@ -459,9 +407,9 @@ export interface ODJsonConfig_DefaultOptionTicketType extends ODJsonConfig_Defau
/**The raw text contents of this message. (empty for embed only) */
text:string,
/**The embed of this message. */
embed:ODJsonConfig_DefaultOptionEmbedSettingsType,
embed:ODOptionsJsonConfig_TicketOptionEmbedSettings,
/**Additional ping/mention settings for this ticket channel. */
ping:ODJsonConfig_DefaultOptionPingSettingsType
ping:ODOptionsJsonConfig_TicketOptionPingSettings
},
/**All settings related to autoclosing this ticket type. */
autoclose:{
@@ -510,21 +458,21 @@ export interface ODJsonConfig_DefaultOptionTicketType extends ODJsonConfig_Defau
}
}
/**## ODJsonConfig_DefaultOptionWebsiteType `interface`
* This interface is an object which has all website properties for options in the `options.json` config!
/**## ODOptionsJsonConfig_WebsiteOption `interface`
* All properties for website options in the `options.jsonc` config!
*/
export interface ODJsonConfig_DefaultOptionWebsiteType extends ODJsonConfig_DefaultOptionType {
export interface ODOptionsJsonConfig_WebsiteOption extends ODOptionsJsonConfig_BaseOption {
type:"website",
/**The URL this button will point to. */
url:string
}
/**## ODJsonConfig_DefaultOptionRoleType `interface`
* This interface is an object which has all reaction role properties for options in the `options.json` config!
/**## ODOptionsJsonConfig_RoleOption `interface`
* All properties for reaction-role options in the `options.jsonc` config!
*/
export interface ODJsonConfig_DefaultOptionRoleType extends ODJsonConfig_DefaultOptionType {
export interface ODOptionsJsonConfig_RoleOption extends ODOptionsJsonConfig_BaseOption {
type:"role",
button:ODJsonConfig_DefaultOptionButtonSettingsType,
button:ODOptionsJsonConfig_OptionButtonSettings,
/**All roles which will be affected by this button. */
roles:string[],
/**The mode determines what will happen with the affected roles on the user. */
@@ -535,25 +483,30 @@ export interface ODJsonConfig_DefaultOptionRoleType extends ODJsonConfig_Default
addOnMemberJoin:boolean
}
/**## ODJsonConfig_DefaultOptionsData `type`
* All contents of the `options.json` config file.
/**## ODOptionsJsonConfig_SubPanelOption `interface`
* All properties for sub-panel options in the `options.jsonc` config!
*/
export type ODJsonConfig_DefaultOptionsData = (ODJsonConfig_DefaultOptionTicketType|ODJsonConfig_DefaultOptionWebsiteType|ODJsonConfig_DefaultOptionRoleType)[]
/**## ODJsonConfig_DefaultOptions `default_class`
* This is a special class that adds type definitions & typescript to the ODJsonConfig class.
* It doesn't add any extra features!
*
* This default class is made for the `options.json` config!
*/
export class ODJsonConfig_DefaultOptions extends ODJsonConfig {
declare data: ODJsonConfig_DefaultOptionsData
export interface ODOptionsJsonConfig_SubPanelOption extends ODOptionsJsonConfig_BaseOption {
type:"sub-panel",
button:ODOptionsJsonConfig_OptionButtonSettings,
/**The panel ID of the sub-panel to show when the button is clicked. */
subPanelId:string
}
/**## ODJsonConfig_DefaultPanelEmbedSettingsType `interface`
* This interface is an object which has all message embed settings for panels in the `panels.json` config!
/**## ODOptionsJsonConfig_OptionsData `type`
* All contents of the `options.jsonc` config file.
*/
export interface ODJsonConfig_DefaultPanelEmbedSettingsType {
export type ODOptionsJsonConfig_OptionsData = (ODOptionsJsonConfig_TicketOption|ODOptionsJsonConfig_WebsiteOption|ODOptionsJsonConfig_RoleOption|ODOptionsJsonConfig_SubPanelOption)[]
///////////////////////////////////////
// CONFIG STRUCTURES, VALUES & TYPES
// --> panels.jsonc
///////////////////////////////////////
/**## ODPanelsJsonConfig_PanelEmbedSettings `interface`
* This interface is an object which has all message embed settings for panels in the `panels.jsonc` config!
*/
export interface ODPanelsJsonConfig_PanelEmbedSettings {
/**Is this embed enabled? */
enabled:boolean,
/**The title of the embed. */
@@ -585,12 +538,14 @@ export interface ODJsonConfig_DefaultPanelEmbedSettingsType {
timestamp:boolean
}
/**## ODJsonConfig_DefaultPanelSettingsType `interface`
/**## ODPanelsJsonConfig_PanelSettings `interface`
* This interface is a collection of additional settings for extra customisation in a panel.
*/
export interface ODJsonConfig_DefaultPanelSettingsType {
export interface ODPanelsJsonConfig_PanelSettings {
/**The placeholder used in the dropdown when enabled. */
dropdownPlaceholder:string,
/**The maximum amount of option buttons before starting a new row. */
maximumButtonsPerRow:number
/**Enable a max tickets warning in the text contents. */
enableMaxTicketsWarningInText:boolean,
@@ -609,46 +564,41 @@ export interface ODJsonConfig_DefaultPanelSettingsType {
describeOptionsInEmbedDescription:boolean
}
/**## ODJsonConfig_DefaultPanelType `interface`
* This interface is an object which has all properties for panels in the `panels.json` config!
/**## ODPanelsJsonConfig_Panel `interface`
* This interface is an object which has all properties for panels in the `panels.jsonc` config!
*/
export interface ODJsonConfig_DefaultPanelType {
export interface ODPanelsJsonConfig_Panel {
/**The id of this panel. */
id:string,
/**The name of this panel. */
name:string,
/**When enabled, the panel uses a dropdown instead of buttons. */
dropdown:boolean,
/**A list of valid options ids from the `options.json` config. */
/**A list of valid options ids from the `options.jsonc` config. */
options:string[],
/**The raw text contents of this panel. (empty for embed only) */
text:string,
/**The embed of this panel. */
embed:ODJsonConfig_DefaultPanelEmbedSettingsType,
embed:ODPanelsJsonConfig_PanelEmbedSettings,
/**A collection of additional settings for extra customisation in a panel. */
settings:ODJsonConfig_DefaultPanelSettingsType
settings:ODPanelsJsonConfig_PanelSettings
}
/**## ODJsonConfig_DefaultPanelsData `type`
* All contents of the `panels.json` config file.
/**## ODPanelsJsonConfig_PanelsData `type`
* All contents of the `panels.jsonc` config file.
*/
export type ODJsonConfig_DefaultPanelsData = ODJsonConfig_DefaultPanelType[]
export type ODPanelsJsonConfig_PanelsData = ODPanelsJsonConfig_Panel[]
/**## ODJsonConfig_DefaultPanels `default_class`
* This is a special class that adds type definitions & typescript to the ODJsonConfig class.
* It doesn't add any extra features!
*
* This default class is made for the `panels.json` config!
*/
export class ODJsonConfig_DefaultPanels extends ODJsonConfig {
declare data: ODJsonConfig_DefaultPanelsData
}
///////////////////////////////////////
// CONFIG STRUCTURES, VALUES & TYPES
// --> questions.jsonc
///////////////////////////////////////
/**## ODJSonConfig_DefaultQuestionLengthSettings `interface`
/**## ODQuestionsJsonConfig_TextLengthLimits `interface`
* This interface is a collection of settings related to length validation in a question.
*/
export interface ODJSonConfig_DefaultQuestionLengthSettings {
export interface ODQuestionsJsonConfig_TextLengthLimits {
/**Enable text length verification. */
enabled:boolean,
/**The minimum text input length. */
@@ -657,63 +607,144 @@ export interface ODJSonConfig_DefaultQuestionLengthSettings {
max:number
}
/**## ODJsonConfig_DefaultShortQuestionType `interface`
* This interface is an object which has all properties for short questions in the `questions.json` config!
/**## ODQuestionsJsonConfig_CheckboxLimits `interface`
* The required amount of checkboxes validation in a question.
*/
export interface ODJsonConfig_DefaultShortQuestionType {
export interface ODQuestionsJsonConfig_CheckboxLimits {
/**Enable checkbox limits. */
enabled:boolean,
/**The minimum amount of selected checkboxes. */
min:number,
/**The maximum amount of selected checkboxes. */
max:number
}
/**## ODQuestionsJsonConfig_DropdownChoice `interface`
* A dropdown choice used in `ODQuestionsJsonConfig_DropdownQuestion`
*/
export interface ODQuestionsJsonConfig_DropdownChoice {
/**The title of the choice. */
title:string,
/**The optional description of the choice. (Leave empty for none) */
description:string,
/**The optional emoji of the choice. (Leave empty for none) */
emoji:string
}
/**## ODQuestionsJsonConfig_RadioCheckboxChoice `interface`
* A radio/checkbox choice used in `ODQuestionsJsonConfig_RadioSelectQuestion` & `ODQuestionsJsonConfig_CheckboxSelectQuestion`
*/
export interface ODQuestionsJsonConfig_RadioCheckboxChoice {
/**The title of the choice. */
title:string,
/**The optional description of the choice. (Leave empty for none) */
description:string,
/**Is this choice selected by default? */
selectedByDefault:boolean
}
/**## ODQuestionsJsonConfig_BaseQuestion `interface`
* This interface is an object which has all universal properties for questions in the `questions.jsonc` config!
*/
export interface ODQuestionsJsonConfig_BaseQuestion {
/**The id of this question. */
id:string,
/**The name of this question. */
name:string,
/**The description of this question. (Leave empty for none) */
description:string,
/**The type of this question. */
type:"short"|"paragraph"|"text-display"|"dropdown"|"radio-select"|"checkbox-select",
/**Is this question required? */
required:boolean,
}
/**## ODQuestionsJsonConfig_TextDisplayQuestion `interface`
* All properties for a text-display in the `questions.jsonc` config!
*/
export interface ODQuestionsJsonConfig_TextDisplayQuestion {
/**The id of this text-display. */
id:string,
/**The type of this question. */
type:"text-display",
/**The text contents to show in the modal. */
textContents:string
}
/**## ODQuestionsJsonConfig_ShortQuestion `interface`
* All properties for short questions in the `questions.jsonc` config!
*/
export interface ODQuestionsJsonConfig_ShortQuestion extends ODQuestionsJsonConfig_BaseQuestion {
type:"short",
/**Is this question required? */
required:boolean,
/**A placeholder for the question. */
placeholder:string,
/**A collection of settings related to length validation in a question. */
length:ODJSonConfig_DefaultQuestionLengthSettings
length:ODQuestionsJsonConfig_TextLengthLimits
}
/**## ODJsonConfig_DefaultParagraphQuestionType `interface`
* This interface is an object which has all properties for paragraph questions in the `questions.json` config!
/**## ODQuestionsJsonConfig_ParagraphQuestion `interface`
* All properties for paragraph questions in the `questions.jsonc` config!
*/
export interface ODJsonConfig_DefaultParagraphQuestionType {
/**The id of this question. */
id:string,
/**The name of this question. */
name:string,
/**The type of this question. */
export interface ODQuestionsJsonConfig_ParagraphQuestion extends ODQuestionsJsonConfig_BaseQuestion {
type:"paragraph",
/**Is this question required? */
required:boolean,
/**A placeholder for the question. */
placeholder:string,
/**A collection of settings related to length validation in a question. */
length:ODJSonConfig_DefaultQuestionLengthSettings
length:ODQuestionsJsonConfig_TextLengthLimits
}
/**## ODJsonConfig_DefaultQuestionsData `type`
* All contents of the `questions.json` config file.
/**## ODQuestionsJsonConfig_DropdownQuestion `interface`
* All properties for dropdown questions in the `questions.jsonc` config!
*/
export type ODJsonConfig_DefaultQuestionsData = (ODJsonConfig_DefaultShortQuestionType|ODJsonConfig_DefaultParagraphQuestionType)[]
/**## ODJsonConfig_DefaultQuestions `default_class`
* This is a special class that adds type definitions & typescript to the ODJsonConfig class.
* It doesn't add any extra features!
*
* This default class is made for the `questions.json` config!
*/
export class ODJsonConfig_DefaultQuestions extends ODJsonConfig {
declare data: ODJsonConfig_DefaultQuestionsData
export interface ODQuestionsJsonConfig_DropdownQuestion extends ODQuestionsJsonConfig_BaseQuestion {
type:"dropdown",
/**A placeholder for the dropdown. */
placeholder:string,
/**A list of maximum 25 dropdown choices. */
choices:ODQuestionsJsonConfig_DropdownChoice[]
}
/**## ODJsonConfig_DefaultTranscriptsTextLayout `interface`
/**## ODQuestionsJsonConfig_RadioSelectQuestion `interface`
* All properties for radio select questions in the `questions.jsonc` config!
*/
export interface ODQuestionsJsonConfig_RadioSelectQuestion extends ODQuestionsJsonConfig_BaseQuestion {
type:"radio-select",
/**A list of minimum 2, maximum 10 radio choices. */
choices:ODQuestionsJsonConfig_RadioCheckboxChoice[]
}
/**## ODQuestionsJsonConfig_CheckboxSelectQuestion `interface`
* All properties for checkbox select questions in the `questions.jsonc` config!
*/
export interface ODQuestionsJsonConfig_CheckboxSelectQuestion extends ODQuestionsJsonConfig_BaseQuestion {
type:"checkbox-select",
/**Verify the checked amount of checkboxes with a minimum & maximum. */
limits:ODQuestionsJsonConfig_CheckboxLimits
/**A list of minimum 1, maximum 10 checkbox choices. */
choices:ODQuestionsJsonConfig_RadioCheckboxChoice[]
}
/**## ODQuestionsJsonConfig_QuestionsData `type`
* All contents of the `questions.jsonc` config file.
*/
export type ODQuestionsJsonConfig_QuestionsData = (
ODQuestionsJsonConfig_ShortQuestion|
ODQuestionsJsonConfig_ParagraphQuestion|
ODQuestionsJsonConfig_TextDisplayQuestion|
ODQuestionsJsonConfig_DropdownQuestion|
ODQuestionsJsonConfig_RadioSelectQuestion|
ODQuestionsJsonConfig_CheckboxSelectQuestion
)[]
///////////////////////////////////////
// CONFIG STRUCTURES, VALUES & TYPES
// --> transcripts.jsonc
///////////////////////////////////////
/**## ODTranscriptsJsonConfig_TranscriptsTextLayout `interface`
* This interface contains the layout of the text transcripts.
*/
export interface ODJsonConfig_DefaultTranscriptsTextLayout {
export interface ODTranscriptsJsonConfig_TranscriptsTextLayout {
/**The layout/complexity of the text transcripts. */
layout:"simple"|"normal"|"detailed",
/**Include stats in the transcript. */
@@ -733,10 +764,10 @@ export interface ODJsonConfig_DefaultTranscriptsTextLayout {
customFileName:string
}
/**## ODJsonConfig_DefaultTranscriptsHtmlLayout `interface`
/**## ODTranscriptsJsonConfig_TranscriptsHtmlLayout `interface`
* This interface contains the layout of the HTML transcripts.
*/
export interface ODJsonConfig_DefaultTranscriptsHtmlLayout {
export interface ODTranscriptsJsonConfig_TranscriptsHtmlLayout {
/**Settings related to the background. */
background:{
/**Enable a custom background. */
@@ -781,10 +812,10 @@ export interface ODJsonConfig_DefaultTranscriptsHtmlLayout {
}
}
/**## ODJsonConfig_DefaultTranscriptsData `interface`
* All contents of the `transcripts.json` config file.
/**## ODTranscriptsJsonConfig_TranscriptsData `interface`
* All contents of the `transcripts.jsonc` config file.
*/
export interface ODJsonConfig_DefaultTranscriptsData {
export interface ODTranscriptsJsonConfig_TranscriptsData {
/**All general settings related to transcripts. */
general:{
/**Are transcripts enabled? */
@@ -816,18 +847,41 @@ export interface ODJsonConfig_DefaultTranscriptsData {
includeTicketStats:boolean
},
/**The layout of the text transcripts. */
textTranscriptStyle:ODJsonConfig_DefaultTranscriptsTextLayout,
textTranscriptStyle:ODTranscriptsJsonConfig_TranscriptsTextLayout,
/**The layout of the HTML transcripts. */
htmlTranscriptStyle:ODJsonConfig_DefaultTranscriptsHtmlLayout
htmlTranscriptStyle:ODTranscriptsJsonConfig_TranscriptsHtmlLayout
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODJsonConfig_DefaultTranscripts `default_class`
* This is a special class that adds type definitions & typescript to the ODJsonConfig class.
* It doesn't add any extra features!
*
* This default class is made for the `transcripts.json` config!
/**## ODMappedConfigManager `class
* A special class with types for the Open Ticket `ODConfigManager` class.
*/
export class ODJsonConfig_DefaultTranscripts extends ODJsonConfig {
declare data: ODJsonConfig_DefaultTranscriptsData
}
export class ODMappedConfigManager extends api.ODConfigManager<ODConfigManagerIdMappings> {}
/**## ODGeneralJsonCommentsConfig `class
* A special class with types for the Open Ticket `config/general.jsonc` config file
*/
export class ODGeneralJsonCommentsConfig extends api.ODJsonCommentsConfig<ODGeneralJsonConfig_GeneralData> {}
/**## ODQuestionsJsonCommentsConfig `class
* A special class with types for the Open Ticket `config/questions.jsonc` config file
*/
export class ODQuestionsJsonCommentsConfig extends api.ODJsonCommentsConfig<ODQuestionsJsonConfig_QuestionsData> {}
/**## ODOptionsJsonCommentsConfig `class
* A special class with types for the Open Ticket `config/options.jsonc` config file
*/
export class ODOptionsJsonCommentsConfig extends api.ODJsonCommentsConfig<ODOptionsJsonConfig_OptionsData> {}
/**## ODPanelsJsonCommentsConfig `class
* A special class with types for the Open Ticket `config/panels.jsonc` config file
*/
export class ODPanelsJsonCommentsConfig extends api.ODJsonCommentsConfig<ODPanelsJsonConfig_PanelsData> {}
/**## ODTranscriptsJsonCommentsConfig `class
* A special class with types for the Open Ticket `config/transcripts.jsonc` config file
*/
export class ODTranscriptsJsonCommentsConfig extends api.ODJsonCommentsConfig<ODTranscriptsJsonConfig_TranscriptsData> {}
+21
View File
@@ -0,0 +1,21 @@
///////////////////////////////////////
//OPEN TICKET CONSOLE MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODLiveStatusManagerIdMappings `interface`
* A list of all available IDs in the default `ODLiveStatusManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODLiveStatusManagerIdMappings extends api.ODLiveStatusManagerIdConstraint {
"opendiscord:default-djdj-dev":api.ODLiveStatusUrlSource
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedLiveStatusManager `class
* A special class with types for the Open Ticket `ODLiveStatusManager` class.
*/
export class ODMappedLiveStatusManager extends api.ODLiveStatusManager<ODLiveStatusManagerIdMappings> {}
+21
View File
@@ -0,0 +1,21 @@
///////////////////////////////////////
//OPEN TICKET COOLDOWN MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODCooldownManagerIdMappings `interface`
* A list of all available IDs in the default `ODCooldownManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODCooldownManagerIdMappings extends api.ODCooldownManagerIdConstraint {
//"opendiscord:cooldown":api.ODCooldown
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedCooldownManager `class
* A special class with types for the Open Ticket `ODCooldownManager` class.
*/
export class ODMappedCooldownManager extends api.ODCooldownManager<ODCooldownManagerIdMappings> {}
+98
View File
@@ -0,0 +1,98 @@
///////////////////////////////////////
//OPEN TICKET DATABASE MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
import { ODTicketJson } from "../api/ticket.js"
import { ODOptionJson } from "../api/option.js"
/**## ODDatabaseManagerIdMappings `interface`
* A list of all available IDs in the default `ODDatabaseManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODDatabaseManagerIdMappings extends api.ODDatabaseManagerIdConstraint {
"opendiscord:global":ODGlobalDatabase,
"opendiscord:stats":ODStatsDatabase,
"opendiscord:tickets":ODTicketsDatabase,
"opendiscord:users":ODUsersDatabase,
"opendiscord:options":ODOptionsDatabase,
"opendiscord:message-states":ODMessageStatesDatabase,
}
/////////////////////////////////////////
// DATABASE MAPPINGS, CATEGORIES & TYPES
/////////////////////////////////////////
/**## ODGlobalDatabaseIdMappings `interface`
* A list of all available IDs in the default `ODGlobalDatabase` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODGlobalDatabaseIdMappings extends api.ODDatabaseIdConstraint {
"opendiscord:panel-message":string,
"opendiscord:panel-update":string,
"opendiscord:option-suffix-counter":number,
"opendiscord:option-suffix-history":string[],
"opendiscord:last-version":string
}
/**## ODTicketsDatabaseIdMappings `interface`
* A list of all available IDs in the default `ODTicketsDatabase` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODTicketsDatabaseIdMappings extends api.ODDatabaseIdConstraint {
"opendiscord:ticket":ODTicketJson
}
/**## ODUsersDatabaseIdMappings `interface`
* A list of all available IDs in the default `ODUsersDatabase` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODUsersDatabaseIdMappings extends api.ODDatabaseIdConstraint {
"opendiscord:blacklist":ODTicketJson
}
/**## ODOptionsDatabaseIdMappings `interface`
* A list of all available IDs in the default `ODOptionsDatabase` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODOptionsDatabaseIdMappings extends api.ODDatabaseIdConstraint {
"opendiscord:used-option":ODOptionJson
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedDatabaseManager `class
* A special class with types for the Open Ticket `ODDatabaseManager` class.
*/
export class ODMappedDatabaseManager extends api.ODDatabaseManager<ODDatabaseManagerIdMappings> {}
/**## ODGlobalDatabase `class
* A special class with types for the Open Ticket `database/global.json` database file
*/
export class ODGlobalDatabase extends api.ODFormattedJsonDatabase<ODGlobalDatabaseIdMappings> {}
/**## ODStatsDatabase `class
* A special class with types for the Open Ticket `database/stats.json` database file
*/
export class ODStatsDatabase extends api.ODFormattedJsonDatabase {}
/**## ODTicketsDatabase `class
* A special class with types for the Open Ticket `database/tickets.json` database file
*/
export class ODTicketsDatabase extends api.ODFormattedJsonDatabase<ODTicketsDatabaseIdMappings> {}
/**## ODUsersDatabase `class
* A special class with types for the Open Ticket `database/users.json` database file
*/
export class ODUsersDatabase extends api.ODFormattedJsonDatabase<ODUsersDatabaseIdMappings> {}
/**## ODOptionsDatabase `class
* A special class with types for the Open Ticket `database/options.json` database file
*/
export class ODOptionsDatabase extends api.ODFormattedJsonDatabase<ODOptionsDatabaseIdMappings> {}
/**## ODMessageStatesDatabase `class
* A special class with types for the Open Ticket `database/states.json` database file
*/
export class ODMessageStatesDatabase extends api.ODFormattedJsonDatabase {}
+361
View File
@@ -0,0 +1,361 @@
///////////////////////////////////////
//OPEN TICKET EVENT MAPPINGS
///////////////////////////////////////
//BASE MAPPINGSS
import * as api from "@open-discord-bots/framework/api"
import * as discord from "discord.js"
//OPEN TICKET MAPPINGS
import { ODMappedPluginClassManager, ODMappedPluginManager } from "./plugin.js"
import { ODMappedConfigManager} from "./config.js"
import { ODMappedDatabaseManager } from "./database.js"
import { ODMappedFlagManager } from "./flag.js"
import { ODMappedSessionManager } from "./session.js"
import { ODMappedLanguageManager } from "./language.js"
import { ODMappedCheckerFunctionManager, ODMappedCheckerManager, ODMappedCheckerTranslationRegister } from "./checker.js"
import { ODMappedClientManager, ODMappedContextMenuManager, ODMappedSlashCommandManager, ODMappedTextCommandManager } from "./client.js"
import { ODMappedBuilderManager, ODMappedButtonManager, ODMappedDropdownManager, ODMappedEmbedManager, ODMappedFileManager, ODMappedMessageManager, ODMappedModalManager } from "./builder.js"
import { ODMappedAutocompleteResponderManager, ODMappedButtonResponderManager, ODMappedCommandResponderManager, ODMappedContextMenuResponderManager, ODMappedDropdownResponderManager, ODMappedModalResponderManager, ODMappedResponderManager } from "./responder.js"
import { ODMappedActionManager } from "./action.js"
import { ODMappedPermissionManager } from "./permission.js"
import { ODMappedHelpMenuManager } from "./helpmenu.js"
import { ODMappedStatisticManager } from "./statistic.js"
import { ODMappedCodeManager } from "./code.js"
import { ODMappedCooldownManager } from "./cooldown.js"
import { ODMappedPostManager } from "./post.js"
import { ODMappedVerifyBarManager } from "./verifybar.js"
import { ODMappedStartScreenManager } from "./startscreen.js"
import { ODMappedLiveStatusManager } from "./console.js"
import { ODMappedProgressBarManager, ODMappedProgressBarRendererManager } from "./progressbar.js"
import { ODMappedComponentManager, ODMappedComponentModifierManager, ODMappedMessageComponentManager, ODMappedModalComponentManager, ODMappedSharedComponentManager } from "./component.js"
import { ODMappedStateManager } from "./state.js"
//OPEN TICKET MAPPINGSS
import { ODOptionManager, ODTicketOption } from "../api/option.js"
import { ODPanel, ODPanelManager } from "../api/panel.js"
import { ODTicket, ODTicketClearFilter, ODTicketManager } from "../api/ticket.js"
import { ODQuestionManager } from "../api/question.js"
import { ODBlacklistManager } from "../api/blacklist.js"
import { ODMappedTranscriptManager } from "../api/transcript.js"
import { ODRole, ODRoleManager } from "../api/role.js"
import { ODMappedPriorityManager, ODPriorityLevel } from "../api/priority.js"
/**## ODEventManagerIdMappings `interface`
* A list of all available IDs in the default `ODEventManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODEventManagerIdMappings extends api.ODEventManagerIdConstraint {
//error handling
"onErrorHandling": api.ODEvent<(error:Error, origin:NodeJS.UncaughtExceptionOrigin) => api.ODPromiseVoid>
"afterErrorHandling": api.ODEvent<(error:Error, origin:NodeJS.UncaughtExceptionOrigin, message:api.ODError) => api.ODPromiseVoid>
//plugins
"afterPluginsLoaded": api.ODEvent<(plugins:ODMappedPluginManager) => api.ODPromiseVoid>
"onPluginClassLoad": api.ODEvent<(classes:ODMappedPluginClassManager, plugins:ODMappedPluginManager) => api.ODPromiseVoid>
"afterPluginClassesLoaded": api.ODEvent<(classes:ODMappedPluginClassManager, plugins:ODMappedPluginManager) => api.ODPromiseVoid>
//flags
"onFlagLoad": api.ODEvent<(flags:ODMappedFlagManager) => api.ODPromiseVoid>
"afterFlagsLoaded": api.ODEvent<(flags:ODMappedFlagManager) => api.ODPromiseVoid>
"onFlagInit": api.ODEvent<(flags:ODMappedFlagManager) => api.ODPromiseVoid>
"afterFlagsInitiated": api.ODEvent<(flags:ODMappedFlagManager) => api.ODPromiseVoid>
//progress bars
"onProgressBarRendererLoad": api.ODEvent<(renderers:ODMappedProgressBarRendererManager) => api.ODPromiseVoid>
"afterProgressBarRenderersLoaded": api.ODEvent<(renderers:ODMappedProgressBarRendererManager) => api.ODPromiseVoid>
"onProgressBarLoad": api.ODEvent<(progressbars:ODMappedProgressBarManager) => api.ODPromiseVoid>
"afterProgressBarsLoaded": api.ODEvent<(progressbars:ODMappedProgressBarManager) => api.ODPromiseVoid>
//configs
"onConfigLoad": api.ODEvent<(configs:ODMappedConfigManager) => api.ODPromiseVoid>
"afterConfigsLoaded": api.ODEvent<(configs:ODMappedConfigManager) => api.ODPromiseVoid>
"onConfigInit": api.ODEvent<(configs:ODMappedConfigManager) => api.ODPromiseVoid>
"afterConfigsInitiated": api.ODEvent<(configs:ODMappedConfigManager) => api.ODPromiseVoid>
//databases
"onDatabaseLoad": api.ODEvent<(databases:ODMappedDatabaseManager) => api.ODPromiseVoid>
"afterDatabasesLoaded": api.ODEvent<(databases:ODMappedDatabaseManager) => api.ODPromiseVoid>
"onDatabaseInit": api.ODEvent<(databases:ODMappedDatabaseManager) => api.ODPromiseVoid>
"afterDatabasesInitiated": api.ODEvent<(databases:ODMappedDatabaseManager) => api.ODPromiseVoid>
//languages
"onLanguageLoad": api.ODEvent<(languages:ODMappedLanguageManager) => api.ODPromiseVoid>
"afterLanguagesLoaded": api.ODEvent<(languages:ODMappedLanguageManager) => api.ODPromiseVoid>
"onLanguageInit": api.ODEvent<(languages:ODMappedLanguageManager) => api.ODPromiseVoid>
"afterLanguagesInitiated": api.ODEvent<(languages:ODMappedLanguageManager) => api.ODPromiseVoid>
"onLanguageSelect": api.ODEvent<(languages:ODMappedLanguageManager) => api.ODPromiseVoid>
"afterLanguagesSelected": api.ODEvent<(main:api.ODLanguage|null, backup:api.ODLanguage|null, languages:ODMappedLanguageManager) => api.ODPromiseVoid>
//sessions
"onSessionLoad": api.ODEvent<(languages:ODMappedSessionManager) => api.ODPromiseVoid>
"afterSessionsLoaded": api.ODEvent<(languages:ODMappedSessionManager) => api.ODPromiseVoid>
//config checkers
"onCheckerLoad": api.ODEvent<(checkers:ODMappedCheckerManager) => api.ODPromiseVoid>
"afterCheckersLoaded": api.ODEvent<(checkers:ODMappedCheckerManager) => api.ODPromiseVoid>
"onCheckerFunctionLoad": api.ODEvent<(functions:ODMappedCheckerFunctionManager, checkers:ODMappedCheckerManager) => api.ODPromiseVoid>
"afterCheckerFunctionsLoaded": api.ODEvent<(functions:ODMappedCheckerFunctionManager, checkers:ODMappedCheckerManager) => api.ODPromiseVoid>
"onCheckerExecute": api.ODEvent<(checkers:ODMappedCheckerManager) => api.ODPromiseVoid>
"afterCheckersExecuted": api.ODEvent<(result:api.ODCheckerResult, checkers:ODMappedCheckerManager) => api.ODPromiseVoid>
"onCheckerTranslationLoad": api.ODEvent<(translations:ODMappedCheckerTranslationRegister, enabled:boolean, checkers:ODMappedCheckerManager) => api.ODPromiseVoid>
"afterCheckerTranslationsLoaded": api.ODEvent<(translations:ODMappedCheckerTranslationRegister, checkers:ODMappedCheckerManager) => api.ODPromiseVoid>
"onCheckerRender": api.ODEvent<(renderer:api.ODCheckerRenderer, checkers:ODMappedCheckerManager) => api.ODPromiseVoid>
"afterCheckersRendered": api.ODEvent<(renderer:api.ODCheckerRenderer, checkers:ODMappedCheckerManager) => api.ODPromiseVoid>
"onCheckerQuit": api.ODEvent<(checkers:ODMappedCheckerManager) => api.ODPromiseVoid>
//plugin loading before client
"onPluginBeforeClientLoad": api.ODEvent<() => api.ODPromiseVoid>,
"afterPluginBeforeClientLoaded": api.ODEvent<() => api.ODPromiseVoid>,
//client configuration
"onClientLoad": api.ODEvent<(client:ODMappedClientManager) => api.ODPromiseVoid>
"afterClientLoaded": api.ODEvent<(client:ODMappedClientManager) => api.ODPromiseVoid>
"onClientInit": api.ODEvent<(client:ODMappedClientManager) => api.ODPromiseVoid>
"afterClientInitiated": api.ODEvent<(client:ODMappedClientManager) => api.ODPromiseVoid>
"onClientReady": api.ODEvent<(client:ODMappedClientManager) => api.ODPromiseVoid>
"afterClientReady": api.ODEvent<(client:ODMappedClientManager) => api.ODPromiseVoid>
"onClientActivityLoad": api.ODEvent<(activity:api.ODClientActivityManager, client:ODMappedClientManager) => api.ODPromiseVoid>
"afterClientActivityLoaded": api.ODEvent<(activity:api.ODClientActivityManager, client:ODMappedClientManager) => api.ODPromiseVoid>
"onClientActivityInit": api.ODEvent<(activity:api.ODClientActivityManager, client:ODMappedClientManager) => api.ODPromiseVoid>
"afterClientActivityInitiated": api.ODEvent<(activity:api.ODClientActivityManager, client:ODMappedClientManager) => api.ODPromiseVoid>
//priority levels
"onPriorityLoad": api.ODEvent<(priorities:ODMappedPriorityManager) => api.ODPromiseVoid>
"afterPrioritiesLoaded": api.ODEvent<(priorities:ODMappedPriorityManager) => api.ODPromiseVoid>
//client slash commands
"onSlashCommandLoad": api.ODEvent<(slash:ODMappedSlashCommandManager, client:ODMappedClientManager) => api.ODPromiseVoid>
"afterSlashCommandsLoaded": api.ODEvent<(slash:ODMappedSlashCommandManager, client:ODMappedClientManager) => api.ODPromiseVoid>
"onSlashCommandRegister": api.ODEvent<(slash:ODMappedSlashCommandManager, client:ODMappedClientManager) => api.ODPromiseVoid>
"afterSlashCommandsRegistered": api.ODEvent<(slash:ODMappedSlashCommandManager, client:ODMappedClientManager) => api.ODPromiseVoid>
//client context menus
"onContextMenuLoad": api.ODEvent<(menu:ODMappedContextMenuManager, client:ODMappedClientManager) => api.ODPromiseVoid>
"afterContextMenusLoaded": api.ODEvent<(menu:ODMappedContextMenuManager, client:ODMappedClientManager) => api.ODPromiseVoid>
"onContextMenuRegister": api.ODEvent<(menu:ODMappedContextMenuManager, client:ODMappedClientManager) => api.ODPromiseVoid>
"afterContextMenusRegistered": api.ODEvent<(menu:ODMappedContextMenuManager, client:ODMappedClientManager) => api.ODPromiseVoid>
//client text commands
"onTextCommandLoad": api.ODEvent<(text:ODMappedTextCommandManager, client:ODMappedClientManager) => api.ODPromiseVoid>
"afterTextCommandsLoaded": api.ODEvent<(text:ODMappedTextCommandManager, client:ODMappedClientManager) => api.ODPromiseVoid>
//states
"onStateLoad": api.ODEvent<(posts:ODMappedStateManager) => api.ODPromiseVoid>
"afterStatesLoaded": api.ODEvent<(posts:ODMappedStateManager) => api.ODPromiseVoid>
"onStateInit": api.ODEvent<(posts:ODMappedStateManager) => api.ODPromiseVoid>
"afterStatesInitiated": api.ODEvent<(posts:ODMappedStateManager) => api.ODPromiseVoid>
//plugin loading before managers
"onPluginBeforeManagerLoad": api.ODEvent<() => api.ODPromiseVoid>,
"afterPluginBeforeManagerLoaded": api.ODEvent<() => api.ODPromiseVoid>,
//questions
"onQuestionLoad": api.ODEvent<(questions:ODQuestionManager) => api.ODPromiseVoid>
"afterQuestionsLoaded": api.ODEvent<(questions:ODQuestionManager) => api.ODPromiseVoid>
//options
"onOptionLoad": api.ODEvent<(options:ODOptionManager) => api.ODPromiseVoid>
"afterOptionsLoaded": api.ODEvent<(options:ODOptionManager) => api.ODPromiseVoid>
//panels
"onPanelLoad": api.ODEvent<(panels:ODPanelManager) => api.ODPromiseVoid>
"afterPanelsLoaded": api.ODEvent<(panels:ODPanelManager) => api.ODPromiseVoid>
"onPanelSpawn": api.ODEvent<(panel:ODPanel) => api.ODPromiseVoid>
"afterPanelSpawned": api.ODEvent<(panel:ODPanel) => api.ODPromiseVoid>
//tickets
"onTicketLoad": api.ODEvent<(tickets:ODTicketManager) => api.ODPromiseVoid>
"afterTicketsLoaded": api.ODEvent<(tickets:ODTicketManager) => api.ODPromiseVoid>
//ticket creation
"onTicketChannelCreation": api.ODEvent<(option:ODTicketOption, user:discord.User) => api.ODPromiseVoid>
"afterTicketChannelCreated": api.ODEvent<(option:ODTicketOption, channel:discord.GuildTextBasedChannel, user:discord.User) => api.ODPromiseVoid>
"onTicketChannelDeletion": api.ODEvent<(ticket:ODTicket, channel:discord.GuildTextBasedChannel, user:discord.User) => api.ODPromiseVoid>
"afterTicketChannelDeleted": api.ODEvent<(ticket:ODTicket, user:discord.User) => api.ODPromiseVoid>
"onTicketPermissionsCreated": api.ODEvent<(option:ODTicketOption, permissions:ODMappedPermissionManager, channel:discord.GuildTextBasedChannel, user:discord.User) => api.ODPromiseVoid>
"afterTicketPermissionsCreated": api.ODEvent<(option:ODTicketOption, permissions:ODMappedPermissionManager, channel:discord.GuildTextBasedChannel, user:discord.User) => api.ODPromiseVoid>
"onTicketMainMessageCreated": api.ODEvent<(ticket:ODTicket, channel:discord.GuildTextBasedChannel, user:discord.User) => api.ODPromiseVoid>
"afterTicketMainMessageCreated": api.ODEvent<(ticket:ODTicket, message:discord.Message, channel:discord.GuildTextBasedChannel, user:discord.User) => api.ODPromiseVoid>
//ticket actions
"onTicketCreate": api.ODEvent<(creator:discord.User) => api.ODPromiseVoid>
"afterTicketCreated": api.ODEvent<(ticket:ODTicket, creator:discord.User, channel:discord.GuildTextBasedChannel) => api.ODPromiseVoid>
"onTicketClose": api.ODEvent<(ticket:ODTicket, closer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"afterTicketClosed": api.ODEvent<(ticket:ODTicket, closer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"onTicketReopen": api.ODEvent<(ticket:ODTicket, reopener:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"afterTicketReopened": api.ODEvent<(ticket:ODTicket, reopener:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"onTicketDelete": api.ODEvent<(ticket:ODTicket, deleter:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"afterTicketDeleted": api.ODEvent<(ticket:ODTicket, deleter:discord.User, reason:string|null) => api.ODPromiseVoid>
"onTicketMove": api.ODEvent<(ticket:ODTicket, mover:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"afterTicketMoved": api.ODEvent<(ticket:ODTicket, mover:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"onTicketClaim": api.ODEvent<(ticket:ODTicket, claimer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"afterTicketClaimed": api.ODEvent<(ticket:ODTicket, claimer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"onTicketUnclaim": api.ODEvent<(ticket:ODTicket, unclaimer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"afterTicketUnclaimed": api.ODEvent<(ticket:ODTicket, unclaimer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"onTicketPin": api.ODEvent<(ticket:ODTicket, pinner:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"afterTicketPinned": api.ODEvent<(ticket:ODTicket, pinner:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"onTicketUnpin": api.ODEvent<(ticket:ODTicket, unpinner:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"afterTicketUnpinned": api.ODEvent<(ticket:ODTicket, unpinner:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"onTicketUserAdd": api.ODEvent<(ticket:ODTicket, adder:discord.User, user:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"afterTicketUserAdded": api.ODEvent<(ticket:ODTicket, adder:discord.User, user:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"onTicketUserRemove": api.ODEvent<(ticket:ODTicket, remover:discord.User, user:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"afterTicketUserRemoved": api.ODEvent<(ticket:ODTicket, remover:discord.User, user:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"onTicketRename": api.ODEvent<(ticket:ODTicket, renamer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"afterTicketRenamed": api.ODEvent<(ticket:ODTicket, renamer:discord.User, channel:discord.GuildTextBasedChannel, reason:string|null) => api.ODPromiseVoid>
"onTicketsClear": api.ODEvent<(tickets:ODTicket[], clearer:discord.User, channel:discord.GuildTextBasedChannel, filter:ODTicketClearFilter) => api.ODPromiseVoid>
"afterTicketsCleared": api.ODEvent<(tickets:ODTicket[], clearer:discord.User, channel:discord.GuildTextBasedChannel, filter:ODTicketClearFilter) => api.ODPromiseVoid>
"onTicketTopicChange": api.ODEvent<(ticket:ODTicket, changer:discord.User, channel:discord.GuildTextBasedChannel, oldTopic:string, newTopic:string) => api.ODPromiseVoid>
"afterTicketTopicChanged": api.ODEvent<(ticket:ODTicket, changer:discord.User, channel:discord.GuildTextBasedChannel, oldTopic:string, newTopic:string) => api.ODPromiseVoid>
"onTicketPriorityChange": api.ODEvent<(ticket:ODTicket, changer:discord.User, channel:discord.GuildTextBasedChannel, oldPriority:ODPriorityLevel, newPriority:ODPriorityLevel, reason:string|null) => api.ODPromiseVoid>
"afterTicketPriorityChanged": api.ODEvent<(ticket:ODTicket, changer:discord.User, channel:discord.GuildTextBasedChannel, oldPriority:ODPriorityLevel, newPriority:ODPriorityLevel, reason:string|null) => api.ODPromiseVoid>
"onTicketTransfer": api.ODEvent<(ticket:ODTicket, changer:discord.User, channel:discord.GuildTextBasedChannel, oldCreator:discord.User, newCreator:discord.User, reason:string|null) => api.ODPromiseVoid>
"afterTicketTransferred": api.ODEvent<(ticket:ODTicket, changer:discord.User, channel:discord.GuildTextBasedChannel, oldCreator:discord.User, newCreator:discord.User, reason:string|null) => api.ODPromiseVoid>
//roles
"onRoleLoad": api.ODEvent<(roles:ODRoleManager) => api.ODPromiseVoid>
"afterRolesLoaded": api.ODEvent<(roles:ODRoleManager) => api.ODPromiseVoid>
"onRoleUpdate": api.ODEvent<(user:discord.User,role:ODRole) => api.ODPromiseVoid>
"afterRolesUpdated": api.ODEvent<(user:discord.User,role:ODRole) => api.ODPromiseVoid>
//blacklist
"onBlacklistLoad": api.ODEvent<(blacklist:ODBlacklistManager) => api.ODPromiseVoid>
"afterBlacklistLoaded": api.ODEvent<(blacklist:ODBlacklistManager) => api.ODPromiseVoid>
//transcripts
"onTranscriptCompilerLoad": api.ODEvent<(transcripts:ODMappedTranscriptManager) => api.ODPromiseVoid>
"afterTranscriptCompilersLoaded": api.ODEvent<(transcripts:ODMappedTranscriptManager) => api.ODPromiseVoid>
"onTranscriptHistoryLoad": api.ODEvent<(transcripts:ODMappedTranscriptManager) => api.ODPromiseVoid>
"afterTranscriptHistoryLoaded": api.ODEvent<(transcripts:ODMappedTranscriptManager) => api.ODPromiseVoid>
//transcript creation
"onTranscriptCreate": api.ODEvent<(transcripts:ODMappedTranscriptManager,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => api.ODPromiseVoid>
"afterTranscriptCreated": api.ODEvent<(transcripts:ODMappedTranscriptManager,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => api.ODPromiseVoid>
"onTranscriptInit": api.ODEvent<(transcripts:ODMappedTranscriptManager,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => api.ODPromiseVoid>
"afterTranscriptInitiated": api.ODEvent<(transcripts:ODMappedTranscriptManager,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => api.ODPromiseVoid>
"onTranscriptCompile": api.ODEvent<(transcripts:ODMappedTranscriptManager,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => api.ODPromiseVoid>
"afterTranscriptCompiled": api.ODEvent<(transcripts:ODMappedTranscriptManager,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => api.ODPromiseVoid>
"onTranscriptReady": api.ODEvent<(transcripts:ODMappedTranscriptManager,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => api.ODPromiseVoid>
"afterTranscriptReady": api.ODEvent<(transcripts:ODMappedTranscriptManager,ticket:ODTicket,channel:discord.TextChannel,user:discord.User) => api.ODPromiseVoid>
//plugin loading before builders
"onPluginBeforeBuilderLoad": api.ODEvent<() => api.ODPromiseVoid>,
"afterPluginBeforeBuilderLoaded": api.ODEvent<() => api.ODPromiseVoid>,
//builders
"onButtonBuilderLoad": api.ODEvent<(buttons:ODMappedButtonManager, builders:ODMappedBuilderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterButtonBuildersLoaded": api.ODEvent<(buttons:ODMappedButtonManager, builders:ODMappedBuilderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onDropdownBuilderLoad": api.ODEvent<(dropdowns:ODMappedDropdownManager, builders:ODMappedBuilderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterDropdownBuildersLoaded": api.ODEvent<(dropdowns:ODMappedDropdownManager, builders:ODMappedBuilderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onFileBuilderLoad": api.ODEvent<(files:ODMappedFileManager, builders:ODMappedBuilderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterFileBuildersLoaded": api.ODEvent<(files:ODMappedFileManager, builders:ODMappedBuilderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onEmbedBuilderLoad": api.ODEvent<(embeds:ODMappedEmbedManager, builders:ODMappedBuilderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterEmbedBuildersLoaded": api.ODEvent<(embeds:ODMappedEmbedManager, builders:ODMappedBuilderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onMessageBuilderLoad": api.ODEvent<(messages:ODMappedMessageManager, builders:ODMappedBuilderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterMessageBuildersLoaded": api.ODEvent<(messages:ODMappedMessageManager, builders:ODMappedBuilderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onModalBuilderLoad": api.ODEvent<(modals:ODMappedModalManager, builders:ODMappedBuilderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterModalBuildersLoaded": api.ODEvent<(modals:ODMappedModalManager, builders:ODMappedBuilderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
//components
"onSharedComponentLoad": api.ODEvent<(shared:ODMappedSharedComponentManager, components:ODMappedComponentManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterSharedComponentsLoaded": api.ODEvent<(shared:ODMappedSharedComponentManager, components:ODMappedComponentManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onMessageComponentLoad": api.ODEvent<(shared:ODMappedMessageComponentManager, components:ODMappedComponentManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterMessageComponentsLoaded": api.ODEvent<(shared:ODMappedMessageComponentManager, components:ODMappedComponentManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onModalComponentLoad": api.ODEvent<(shared:ODMappedModalComponentManager, components:ODMappedComponentManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterModalComponentsLoaded": api.ODEvent<(shared:ODMappedModalComponentManager, components:ODMappedComponentManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onComponentModifierLoad": api.ODEvent<(modifiers:ODMappedComponentModifierManager, msgComponents:ODMappedMessageComponentManager, msgBuilders:ODMappedMessageManager) => api.ODPromiseVoid>
"afterComponentModifiersLoaded": api.ODEvent<(modifiers:ODMappedComponentModifierManager, msgComponents:ODMappedMessageComponentManager, msgBuilders:ODMappedMessageManager) => api.ODPromiseVoid>
//plugin loading before responders
"onPluginBeforeResponderLoad": api.ODEvent<() => api.ODPromiseVoid>,
"afterPluginBeforeResponderLoaded": api.ODEvent<() => api.ODPromiseVoid>,
//responders
"onCommandResponderLoad": api.ODEvent<(commands:ODMappedCommandResponderManager, responders:ODMappedResponderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterCommandRespondersLoaded": api.ODEvent<(commands:ODMappedCommandResponderManager, responders:ODMappedResponderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onButtonResponderLoad": api.ODEvent<(buttons:ODMappedButtonResponderManager, responders:ODMappedResponderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterButtonRespondersLoaded": api.ODEvent<(buttons:ODMappedButtonResponderManager, responders:ODMappedResponderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onDropdownResponderLoad": api.ODEvent<(dropdowns:ODMappedDropdownResponderManager, responders:ODMappedResponderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterDropdownRespondersLoaded": api.ODEvent<(dropdowns:ODMappedDropdownResponderManager, responders:ODMappedResponderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onModalResponderLoad": api.ODEvent<(modals:ODMappedModalResponderManager, responders:ODMappedResponderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterModalRespondersLoaded": api.ODEvent<(modals:ODMappedModalResponderManager, responders:ODMappedResponderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onContextMenuResponderLoad": api.ODEvent<(menus:ODMappedContextMenuResponderManager, responders:ODMappedResponderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterContextMenuRespondersLoaded": api.ODEvent<(menus:ODMappedContextMenuResponderManager, responders:ODMappedResponderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"onAutocompleteResponderLoad": api.ODEvent<(autocomplete:ODMappedAutocompleteResponderManager, responders:ODMappedResponderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterAutocompleteRespondersLoaded": api.ODEvent<(autocomplete:ODMappedAutocompleteResponderManager, responders:ODMappedResponderManager, actions:ODMappedActionManager) => api.ODPromiseVoid>
//plugin loading before finalizations
"onPluginBeforeFinalizationLoad": api.ODEvent<() => api.ODPromiseVoid>,
"afterPluginBeforeFinalizationLoaded": api.ODEvent<() => api.ODPromiseVoid>,
//actions
"onActionLoad": api.ODEvent<(actions:ODMappedActionManager) => api.ODPromiseVoid>
"afterActionsLoaded": api.ODEvent<(actions:ODMappedActionManager) => api.ODPromiseVoid>
//verifybars
"onVerifyBarLoad": api.ODEvent<(verifybars:ODMappedVerifyBarManager) => api.ODPromiseVoid>
"afterVerifyBarsLoaded": api.ODEvent<(verifybars:ODMappedVerifyBarManager) => api.ODPromiseVoid>
//permissions
"onPermissionLoad": api.ODEvent<(permissions:ODMappedPermissionManager) => api.ODPromiseVoid>
"afterPermissionsLoaded": api.ODEvent<(permissions:ODMappedPermissionManager) => api.ODPromiseVoid>
//posts
"onPostLoad": api.ODEvent<(posts:ODMappedPostManager) => api.ODPromiseVoid>
"afterPostsLoaded": api.ODEvent<(posts:ODMappedPostManager) => api.ODPromiseVoid>
"onPostInit": api.ODEvent<(posts:ODMappedPostManager) => api.ODPromiseVoid>
"afterPostsInitiated": api.ODEvent<(posts:ODMappedPostManager) => api.ODPromiseVoid>
//cooldowns
"onCooldownLoad": api.ODEvent<(cooldowns:ODMappedCooldownManager) => api.ODPromiseVoid>
"afterCooldownsLoaded": api.ODEvent<(cooldowns:ODMappedCooldownManager) => api.ODPromiseVoid>
"onCooldownInit": api.ODEvent<(cooldowns:ODMappedCooldownManager) => api.ODPromiseVoid>
"afterCooldownsInitiated": api.ODEvent<(cooldowns:ODMappedCooldownManager) => api.ODPromiseVoid>
//help menu
"onHelpMenuCategoryLoad": api.ODEvent<(menu:ODMappedHelpMenuManager) => api.ODPromiseVoid>
"afterHelpMenuCategoriesLoaded": api.ODEvent<(menu:ODMappedHelpMenuManager) => api.ODPromiseVoid>
"onHelpMenuComponentLoad": api.ODEvent<(menu:ODMappedHelpMenuManager) => api.ODPromiseVoid>
"afterHelpMenuComponentsLoaded": api.ODEvent<(menu:ODMappedHelpMenuManager) => api.ODPromiseVoid>
//stats
"onStatisticScopeLoad": api.ODEvent<(stats:ODMappedStatisticManager) => api.ODPromiseVoid>
"afterStatisticScopesLoaded": api.ODEvent<(stats:ODMappedStatisticManager) => api.ODPromiseVoid>
"onStatisticLoad": api.ODEvent<(stats:ODMappedStatisticManager) => api.ODPromiseVoid>
"afterStatisticsLoaded": api.ODEvent<(stats:ODMappedStatisticManager) => api.ODPromiseVoid>
"onStatisticInit": api.ODEvent<(stats:ODMappedStatisticManager) => api.ODPromiseVoid>
"afterStatisticsInitiated": api.ODEvent<(stats:ODMappedStatisticManager) => api.ODPromiseVoid>
//plugin loading before code
"onPluginBeforeCodeLoad": api.ODEvent<() => api.ODPromiseVoid>,
"afterPluginBeforeCodeLoaded": api.ODEvent<() => api.ODPromiseVoid>,
//code
"onCodeLoad": api.ODEvent<(code:ODMappedCodeManager) => api.ODPromiseVoid>
"afterCodeLoaded": api.ODEvent<(code:ODMappedCodeManager) => api.ODPromiseVoid>
"onCodeExecute": api.ODEvent<(code:ODMappedCodeManager) => api.ODPromiseVoid>
"afterCodeExecuted": api.ODEvent<(code:ODMappedCodeManager) => api.ODPromiseVoid>
//livestatus
"onLiveStatusSourceLoad": api.ODEvent<(livestatus:ODMappedLiveStatusManager) => api.ODPromiseVoid>
"afterLiveStatusSourcesLoaded": api.ODEvent<(livestatus:ODMappedLiveStatusManager) => api.ODPromiseVoid>
//startscreen
"onStartScreenLoad": api.ODEvent<(startscreen:ODMappedStartScreenManager) => api.ODPromiseVoid>
"afterStartScreensLoaded": api.ODEvent<(startscreen:ODMappedStartScreenManager) => api.ODPromiseVoid>
"onStartScreenRender": api.ODEvent<(startscreen:ODMappedStartScreenManager) => api.ODPromiseVoid>
"afterStartScreensRendered": api.ODEvent<(startscreen:ODMappedStartScreenManager) => api.ODPromiseVoid>
//ready
"beforeReadyForUsage": api.ODEvent<() => api.ODPromiseVoid>
"onReadyForUsage": api.ODEvent<() => api.ODPromiseVoid>
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedEventManager `class
* A special class with types for the Open Ticket `ODEventManager` class.
*/
export class ODMappedEventManager extends api.ODEventManager<ODEventManagerIdMappings> {}
+36
View File
@@ -0,0 +1,36 @@
///////////////////////////////////////
//OPEN TICKET PROCESS MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODFlagManagerIdMappings `interface`
* A list of all available IDs in the default `ODFlagManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODFlagManagerIdMappings extends api.ODFlagManagerIdConstraint {
"opendiscord:no-migration":api.ODFlag,
"opendiscord:dev-config":api.ODFlag,
"opendiscord:dev-database":api.ODFlag,
"opendiscord:debug":api.ODFlag,
"opendiscord:crash":api.ODFlag,
"opendiscord:no-transcripts":api.ODFlag,
"opendiscord:no-checker":api.ODFlag,
"opendiscord:checker":api.ODFlag,
"opendiscord:no-easter":api.ODFlag,
"opendiscord:no-plugins":api.ODFlag,
"opendiscord:soft-plugins":api.ODFlag,
"opendiscord:force-slash-update":api.ODFlag,
"opendiscord:no-compile":api.ODFlag,
"opendiscord:compile-only":api.ODFlag,
"opendiscord:silent":api.ODFlag,
"opendiscord:cli":api.ODFlag,
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedFlagManager `class
* A special class with types for the Open Ticket `ODFlagManager` class.
*/
export class ODMappedFlagManager extends api.ODFlagManager<ODFlagManagerIdMappings> {}
+29
View File
@@ -0,0 +1,29 @@
///////////////////////////////////////
//OPEN TICKET FUSE MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
export interface ODOpenTicketFuseList {
/**Load the default Open Ticket ticket priority levels. */
priorityLoading:boolean,
/**Load the default Open Ticket questions (from `config/questions.jsonc`) */
questionLoading:boolean,
/**Load the default Open Ticket options (from `config/options.jsonc`) */
optionLoading:boolean,
/**Load the default Open Ticket panels (from `config/panels.jsonc`) */
panelLoading:boolean,
/**Load the default Open Ticket tickets (from `database/tickets.json`) */
ticketLoading:boolean,
/**Load the default Open Ticket reaction roles (from `config/options.jsonc`) */
roleLoading:boolean,
/**Load the default Open Ticket blacklist (from `database/users.json`) */
blacklistLoading:boolean,
/**Load the default Open Ticket transcript compilers. */
transcriptCompilerLoading:boolean,
/**Load the default Open Ticket transcript history (from `database/transcripts.jsonc`) */
transcriptHistoryLoading:boolean,
/**The interval in milliseconds that are between autoclose timeout checkers. */
autocloseCheckInterval:number,
/**The interval in milliseconds that are between autodelete timeout checkers. */
autodeleteCheckInterval:number,
}
+145
View File
@@ -0,0 +1,145 @@
///////////////////////////////////////
//OPEN TICKET HELP MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODHelpMenuManagerIdMappings `interface`
* A list of all available IDs in the default `ODHelpMenuManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerIdMappings extends api.ODHelpMenuManagerIdConstraint {
"opendiscord:general":ODGeneralHelpMenuCategory,
"opendiscord:ticket-basic":ODBasicTicketHelpMenuCategory,
"opendiscord:ticket-advanced":ODAdvancedTicketHelpMenuCategory,
"opendiscord:ticket-user":ODUserTicketHelpMenuCategory,
"opendiscord:admin":ODAdminHelpMenuCategory,
"opendiscord:advanced":ODAdvancedHelpMenuCategory,
"opendiscord:extra":ODExtraHelpMenuCategory
}
/////////////////////////////////////////
// HELP MENU MAPPINGS, CATEGORIES & TYPES
/////////////////////////////////////////
/**## ODGeneralHelpMenuCategoryIdMappings `interface`
* A list of all available IDs in the default `ODGeneralHelpMenuCategory` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODGeneralHelpMenuCategoryIdMappings extends api.ODHelpMenuCategoryIdConstraint {
"opendiscord:help":api.ODHelpMenuCommandComponent,
"opendiscord:ticket":api.ODHelpMenuCommandComponent|null
}
/**## ODBasicTicketHelpMenuCategoryIdMappings `interface`
* A list of all available IDs in the default `ODBasicTicketHelpMenuCategory` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODBasicTicketHelpMenuCategoryIdMappings extends api.ODHelpMenuCategoryIdConstraint {
"opendiscord:close":api.ODHelpMenuCommandComponent,
"opendiscord:delete":api.ODHelpMenuCommandComponent,
"opendiscord:reopen":api.ODHelpMenuCommandComponent
}
/**## ODAdvancedTicketHelpMenuCategoryIdMappings `interface`
* A list of all available IDs in the default `ODAdvancedTicketHelpMenuCategory` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODAdvancedTicketHelpMenuCategoryIdMappings extends api.ODHelpMenuCategoryIdConstraint {
"opendiscord:pin":api.ODHelpMenuCommandComponent,
"opendiscord:unpin":api.ODHelpMenuCommandComponent,
"opendiscord:move":api.ODHelpMenuCommandComponent,
"opendiscord:rename":api.ODHelpMenuCommandComponent
}
/**## ODUserTicketHelpMenuCategoryIdMappings `interface`
* A list of all available IDs in the default `ODUserTicketHelpMenuCategory` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODUserTicketHelpMenuCategoryIdMappings extends api.ODHelpMenuCategoryIdConstraint {
"opendiscord:claim":api.ODHelpMenuCommandComponent,
"opendiscord:unclaim":api.ODHelpMenuCommandComponent,
"opendiscord:add":api.ODHelpMenuCommandComponent,
"opendiscord:remove":api.ODHelpMenuCommandComponent,
"opendiscord:transfer":api.ODHelpMenuCommandComponent,
}
/**## ODAdminHelpMenuCategoryIdMappings `interface`
* A list of all available IDs in the default `ODAdminHelpMenuCategory` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODAdminHelpMenuCategoryIdMappings extends api.ODHelpMenuCategoryIdConstraint {
"opendiscord:panel":api.ODHelpMenuCommandComponent,
"opendiscord:blacklist-view":api.ODHelpMenuCommandComponent,
"opendiscord:blacklist-add":api.ODHelpMenuCommandComponent,
"opendiscord:blacklist-remove":api.ODHelpMenuCommandComponent,
"opendiscord:blacklist-get":api.ODHelpMenuCommandComponent
}
/**## ODAdvancedHelpMenuCategoryIdMappings `interface`
* A list of all available IDs in the default `ODAdvancedHelpMenuCategory` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODAdvancedHelpMenuCategoryIdMappings extends api.ODHelpMenuCategoryIdConstraint {
"opendiscord:stats-global":api.ODHelpMenuCommandComponent,
"opendiscord:stats-reset":api.ODHelpMenuCommandComponent,
"opendiscord:stats-ticket":api.ODHelpMenuCommandComponent,
"opendiscord:stats-user":api.ODHelpMenuCommandComponent,
"opendiscord:autoclose-disable":api.ODHelpMenuCommandComponent,
"opendiscord:autoclose-enable":api.ODHelpMenuCommandComponent,
"opendiscord:autodelete-disable":api.ODHelpMenuCommandComponent,
"opendiscord:autodelete-enable":api.ODHelpMenuCommandComponent,
"opendiscord:topic-set":api.ODHelpMenuCommandComponent,
"opendiscord:priority-set":api.ODHelpMenuCommandComponent,
}
/**## ODExtraHelpMenuCategoryIdMappings `interface`
* A list of all available IDs in the default `ODExtraHelpMenuCategory` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODExtraHelpMenuCategoryIdMappings extends api.ODHelpMenuCategoryIdConstraint {
//"opendiscord:help-component":api.ODHelpMenuCommandComponent
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedHelpMenuManager `class
* A special class with types for the Open Ticket `ODHelpMenuManager` class.
*/
export class ODMappedHelpMenuManager extends api.ODHelpMenuManager<ODHelpMenuManagerIdMappings> {}
/**## ODGeneralHelpMenuCategory `class
* A special class with types for the Open Ticket `General Commands` help menu category.
*/
export class ODGeneralHelpMenuCategory extends api.ODHelpMenuCategory<ODGeneralHelpMenuCategoryIdMappings> {}
/**## ODBasicTicketHelpMenuCategory `class
* A special class with types for the Open Ticket `Basic Ticket Commands` help menu category.
*/
export class ODBasicTicketHelpMenuCategory extends api.ODHelpMenuCategory<ODBasicTicketHelpMenuCategoryIdMappings> {}
/**## ODAdvancedTicketHelpMenuCategory `class
* A special class with types for the Open Ticket `Advanced Ticket Commands` help menu category.
*/
export class ODAdvancedTicketHelpMenuCategory extends api.ODHelpMenuCategory<ODAdvancedTicketHelpMenuCategoryIdMappings> {}
/**## ODUserTicketHelpMenuCategory `class
* A special class with types for the Open Ticket `User ticket Commands` help menu category.
*/
export class ODUserTicketHelpMenuCategory extends api.ODHelpMenuCategory<ODUserTicketHelpMenuCategoryIdMappings> {}
/**## ODAdminHelpMenuCategory `class
* A special class with types for the Open Ticket `Admin Commands` help menu category.
*/
export class ODAdminHelpMenuCategory extends api.ODHelpMenuCategory<ODAdminHelpMenuCategoryIdMappings> {}
/**## ODAdvancedHelpMenuCategory `class
* A special class with types for the Open Ticket `Advanced Commands` help menu category.
*/
export class ODAdvancedHelpMenuCategory extends api.ODHelpMenuCategory<ODAdvancedHelpMenuCategoryIdMappings> {}
/**## ODExtraHelpMenuCategory `class
* A special class with types for the Open Ticket `Extra Commands` help menu category.
*/
export class ODExtraHelpMenuCategory extends api.ODHelpMenuCategory<ODExtraHelpMenuCategoryIdMappings> {}
@@ -1,68 +1,60 @@
///////////////////////////////////////
//DEFAULT LANGUAGE MODULE
//OPEN TICKET LANGUAGE MAPPINGS
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODLanguageManager, ODLanguage } from "../modules/language"
import * as api from "@open-discord-bots/framework/api"
/** (CONTRIBUTOR GUIDE) HOW TO ADD NEW LANGUAGES?
* - Add the file to (./languages/) and make sure the metadata is valid.
* - Register the language in loadAllLanguages() in (./src/data/framework/languageLoader.ts).
* - Add autocomplete for the language in ODLanguageManagerIds_Default in (./src/core/api/defaults/language.ts).
* - Update the language list in the README.md translator list.
* - Update the 2 language counters in the README.md features list.
* - Update the Open Ticket Documentation.
*/
/**## ODLanguageManagerIds_Default `interface`
* This interface is a list of ids available in the `ODLanguageManager_Default` class.
/**## ODLanguageManagerIdMappings `interface`
* A list of all available IDs in the default `ODLanguageManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODLanguageManagerIds_Default {
"opendiscord:custom":ODLanguage,
"opendiscord:english":ODLanguage,
"opendiscord:dutch":ODLanguage,
"opendiscord:portuguese":ODLanguage,
"opendiscord:czech":ODLanguage,
"opendiscord:german":ODLanguage,
"opendiscord:catalan":ODLanguage,
"opendiscord:hungarian":ODLanguage,
"opendiscord:spanish":ODLanguage,
"opendiscord:romanian":ODLanguage,
"opendiscord:ukrainian":ODLanguage,
"opendiscord:indonesian":ODLanguage,
"opendiscord:italian":ODLanguage,
"opendiscord:estonian":ODLanguage,
"opendiscord:finnish":ODLanguage,
"opendiscord:danish":ODLanguage,
"opendiscord:thai":ODLanguage,
"opendiscord:turkish":ODLanguage,
"opendiscord:french":ODLanguage,
"opendiscord:arabic":ODLanguage,
"opendiscord:hindi":ODLanguage,
"opendiscord:lithuanian":ODLanguage,
"opendiscord:polish":ODLanguage,
"opendiscord:latvian":ODLanguage,
"opendiscord:norwegian":ODLanguage,
"opendiscord:russian":ODLanguage,
"opendiscord:swedish":ODLanguage,
"opendiscord:vietnamese":ODLanguage,
"opendiscord:persian":ODLanguage,
"opendiscord:bengali":ODLanguage,
"opendiscord:greek":ODLanguage,
"opendiscord:japanese":ODLanguage,
"opendiscord:korean":ODLanguage,
"opendiscord:kurdish":ODLanguage,
"opendiscord:simplified-chinese":ODLanguage,
"opendiscord:slovenian":ODLanguage,
"opendiscord:tamil":ODLanguage,
export interface ODLanguageManagerIdMappings extends api.ODLanguageManagerIdConstraint {
"opendiscord:custom":api.ODLanguage,
"opendiscord:english":api.ODLanguage,
"opendiscord:dutch":api.ODLanguage,
"opendiscord:portuguese":api.ODLanguage,
"opendiscord:czech":api.ODLanguage,
"opendiscord:german":api.ODLanguage,
"opendiscord:catalan":api.ODLanguage,
"opendiscord:hungarian":api.ODLanguage,
"opendiscord:spanish":api.ODLanguage,
"opendiscord:romanian":api.ODLanguage,
"opendiscord:ukrainian":api.ODLanguage,
"opendiscord:indonesian":api.ODLanguage,
"opendiscord:italian":api.ODLanguage,
"opendiscord:estonian":api.ODLanguage,
"opendiscord:finnish":api.ODLanguage,
"opendiscord:danish":api.ODLanguage,
"opendiscord:thai":api.ODLanguage,
"opendiscord:turkish":api.ODLanguage,
"opendiscord:french":api.ODLanguage,
"opendiscord:arabic":api.ODLanguage,
"opendiscord:hindi":api.ODLanguage,
"opendiscord:lithuanian":api.ODLanguage,
"opendiscord:polish":api.ODLanguage,
"opendiscord:latvian":api.ODLanguage,
"opendiscord:norwegian":api.ODLanguage,
"opendiscord:russian":api.ODLanguage,
"opendiscord:swedish":api.ODLanguage,
"opendiscord:vietnamese":api.ODLanguage,
"opendiscord:persian":api.ODLanguage,
"opendiscord:bengali":api.ODLanguage,
"opendiscord:greek":api.ODLanguage,
"opendiscord:japanese":api.ODLanguage,
"opendiscord:korean":api.ODLanguage,
"opendiscord:kurdish":api.ODLanguage,
"opendiscord:simplified-chinese":api.ODLanguage,
"opendiscord:traditional-chinese":api.ODLanguage,
"opendiscord:slovenian":api.ODLanguage,
"opendiscord:tamil":api.ODLanguage,
"opendiscord:khmer ":api.ODLanguage,
//ADD NEW LANGUAGES HERE!!!
}
/**## ODLanguageManagerTranslations_Default `type`
* This interface is a list of ids available in the `ODLanguageManager_Default` class.
/**## ODLanguageManagerTranslationIdMappings `type`
* A list of all available translation IDs in the default `ODLanguageManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export type ODLanguageManagerTranslations_Default = (
export type ODLanguageManagerTranslationIdMappings = (
"checker.system.headerOpenTicket"|
"checker.system.typeError"|
"checker.system.typeWarning"|
@@ -622,59 +614,11 @@ export type ODLanguageManagerTranslations_Default = (
"priorities.none"
)
/**## ODLanguageManager_Default `default_class`
* This is a special class that adds type definitions & typescript to the ODLanguageManager class.
* It doesn't add any extra features!
*
* This default class is made for the global variable `opendiscord.languages`!
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedLanguageManager `class
* A special class with types for the Open Ticket `ODLanguageManager` class.
*/
export class ODLanguageManager_Default extends ODLanguageManager {
get<LanguageId extends keyof ODLanguageManagerIds_Default>(id:LanguageId): ODLanguageManagerIds_Default[LanguageId]
get(id:ODValidId): ODLanguage|null
get(id:ODValidId): ODLanguage|null {
return super.get(id)
}
remove<LanguageId extends keyof ODLanguageManagerIds_Default>(id:LanguageId): ODLanguageManagerIds_Default[LanguageId]
remove(id:ODValidId): ODLanguage|null
remove(id:ODValidId): ODLanguage|null {
return super.remove(id)
}
exists(id:keyof ODLanguageManagerIds_Default): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
getTranslation(id:ODLanguageManagerTranslations_Default): string
getTranslation(id:string): string|null
getTranslation(id:string): string|null {
return super.getTranslation(id)
}
setCurrentLanguage(id:keyof ODLanguageManagerIds_Default): void
setCurrentLanguage(id:ODValidId): void
setCurrentLanguage(id:ODValidId): void {
return super.setCurrentLanguage(id)
}
setBackupLanguage(id:keyof ODLanguageManagerIds_Default): void
setBackupLanguage(id:ODValidId): void
setBackupLanguage(id:ODValidId): void {
return super.setBackupLanguage(id)
}
getTranslationWithParams(id:ODLanguageManagerTranslations_Default, params:string[]): string
getTranslationWithParams(id:string, params:string[]): string|null
getTranslationWithParams(id:string, params:string[]): string|null {
return super.getTranslationWithParams(id,params)
}
}
export class ODMappedLanguageManager extends api.ODLanguageManager<ODLanguageManagerIdMappings,ODLanguageManagerTranslationIdMappings> {}
+34
View File
@@ -0,0 +1,34 @@
///////////////////////////////////////
//OPEN TICKET PERMISSION MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODPermissionManagerIdMappings `interface`
* A list of all available IDs in the default `ODPermissionManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODPermissionManagerIdMappings extends api.ODPermissionManagerIdConstraint {
//"opendiscord:test-permission":api.ODPermission
}
/**## ODPermissionEmbedType `type`
* A collection of all types available in the `opendiscord:no-permissions` embed.
*/
export type ODPermissionEmbedType = (
"developer"|
"owner"|
"admin"|
"moderator"|
"support"|
"member"|
"discord-administrator"
)
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedPermissionManager `class
* A special class with types for the Open Ticket `ODPermissionManager` class.
*/
export class ODMappedPermissionManager extends api.ODPermissionManager<ODPermissionManagerIdMappings> {}
+34
View File
@@ -0,0 +1,34 @@
///////////////////////////////////////
//OPEN TICKET POST MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODPluginManagerIdMappings `interface`
* A list of all available IDs in the default `ODPluginManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODPluginManagerIdMappings extends api.ODPluginManagerIdConstraint {
//"opendiscord:example-plugin":api.ODPlugin
}
/**## ODPluginClassManagerIdMappings `interface`
* A list of all available IDs in the default `ODPluginClassManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODPluginClassManagerIdMappings extends api.ODPluginClassManagerIdConstraint {
//"opendiscord:example-plugin":any
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedPluginManager `class
* A special class with types for the Open Ticket `ODPluginManager` class.
*/
export class ODMappedPluginManager extends api.ODPluginManager<ODPluginManagerIdMappings,ODPluginClassManagerIdMappings> {}
/**## ODMappedPluginClassManager `class
* A special class with types for the Open Ticket `ODPluginClassManager` class.
*/
export class ODMappedPluginClassManager extends api.ODPluginClassManager<ODPluginClassManagerIdMappings> {}
+23
View File
@@ -0,0 +1,23 @@
///////////////////////////////////////
//OPEN TICKET POST MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
import * as discord from "discord.js"
/**## ODPostManagerIdMappings `interface`
* A list of all available IDs in the default `ODPostManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODPostManagerIdMappings extends api.ODPostManagerIdConstraint {
"opendiscord:logs":api.ODPost<discord.GuildTextBasedChannel>|null,
"opendiscord:transcripts":api.ODPost<discord.GuildTextBasedChannel>|null
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedPostManager `class
* A special class with types for the Open Ticket `ODPostManager` class.
*/
export class ODMappedPostManager extends api.ODPostManager<ODPostManagerIdMappings> {}
+44
View File
@@ -0,0 +1,44 @@
///////////////////////////////////////
//OPEN TICKET PROGRESS BAR MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODProgressBarManagerIdMappings `interface`
* A list of all available IDs in the default `ODProgressBarManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODProgressBarManagerIdMappings extends api.ODProgressBarManagerIdConstraint {
"opendiscord:slash-command-remove":api.ODManualProgressBar,
"opendiscord:slash-command-create":api.ODManualProgressBar,
"opendiscord:slash-command-update":api.ODManualProgressBar,
"opendiscord:context-menu-remove":api.ODManualProgressBar,
"opendiscord:context-menu-create":api.ODManualProgressBar,
"opendiscord:context-menu-update":api.ODManualProgressBar,
}
/**## ODProgressBarRendererManagerIdMappings `interface`
* A list of all available IDs in the default `ODProgressBarRendererManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODProgressBarRendererManagerIdMappings extends api.ODProgressBarRendererManagerIdConstraint {
"opendiscord:value-renderer":api.ODDefaultProgressBarRenderer,
"opendiscord:fraction-renderer":api.ODDefaultProgressBarRenderer,
"opendiscord:percentage-renderer":api.ODDefaultProgressBarRenderer,
"opendiscord:time-ms-renderer":api.ODDefaultProgressBarRenderer,
"opendiscord:time-sec-renderer":api.ODDefaultProgressBarRenderer,
"opendiscord:time-min-renderer":api.ODDefaultProgressBarRenderer,
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedProgressBarManager `class
* A special class with types for the Open Ticket `ODProgressBarManager` class.
*/
export class ODMappedProgressBarManager extends api.ODProgressBarManager<ODProgressBarManagerIdMappings,ODProgressBarRendererManagerIdMappings> {}
/**## ODMappedProgressBarRendererManager `class
* A special class with types for the Open Ticket `ODProgressBarRendererManager` class.
*/
export class ODMappedProgressBarRendererManager extends api.ODProgressBarRendererManager<ODProgressBarRendererManagerIdMappings> {}
+142
View File
@@ -0,0 +1,142 @@
///////////////////////////////////////
//OPEN TICKET RESPONDER MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODCommandResponderManagerIdMappings `interface`
* A list of all available IDs in the default `ODCommandResponderManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODCommandResponderManagerIdMappings extends api.ODCommandResponderManagerIdConstraint {
"opendiscord:help":{origin:"slash"|"text",params:{},workers:"opendiscord:help"|"opendiscord:logs"},
"opendiscord:stats":{origin:"slash"|"text",params:{},workers:"opendiscord:stats"|"opendiscord:logs"},
"opendiscord:panel":{origin:"slash"|"text",params:{},workers:"opendiscord:panel"|"opendiscord:logs"},
"opendiscord:ticket":{origin:"slash"|"text",params:{},workers:"opendiscord:ticket"|"opendiscord:logs"},
"opendiscord:blacklist":{origin:"slash"|"text",params:{},workers:"opendiscord:blacklist"|"opendiscord:discord-logs"|"opendiscord:logs"},
"opendiscord:close":{origin:"slash"|"text",params:{},workers:"opendiscord:close"|"opendiscord:logs"},
"opendiscord:reopen":{origin:"slash"|"text",params:{},workers:"opendiscord:reopen"|"opendiscord:logs"},
"opendiscord:delete":{origin:"slash"|"text",params:{},workers:"opendiscord:delete"|"opendiscord:logs"},
"opendiscord:claim":{origin:"slash"|"text",params:{},workers:"opendiscord:claim"|"opendiscord:logs"},
"opendiscord:unclaim":{origin:"slash"|"text",params:{},workers:"opendiscord:unclaim"|"opendiscord:logs"},
"opendiscord:pin":{origin:"slash"|"text",params:{},workers:"opendiscord:pin"|"opendiscord:logs"},
"opendiscord:unpin":{origin:"slash"|"text",params:{},workers:"opendiscord:unpin"|"opendiscord:logs"},
"opendiscord:rename":{origin:"slash"|"text",params:{},workers:"opendiscord:rename"|"opendiscord:logs"},
"opendiscord:move":{origin:"slash"|"text",params:{},workers:"opendiscord:move"|"opendiscord:logs"},
"opendiscord:add":{origin:"slash"|"text",params:{},workers:"opendiscord:add"|"opendiscord:logs"},
"opendiscord:remove":{origin:"slash"|"text",params:{},workers:"opendiscord:remove"|"opendiscord:logs"},
"opendiscord:clear":{origin:"slash"|"text",params:{},workers:"opendiscord:clear"|"opendiscord:logs"},
"opendiscord:topic":{origin:"slash"|"text",params:{},workers:"opendiscord:topic"|"opendiscord:logs"},
"opendiscord:priority":{origin:"slash"|"text",params:{},workers:"opendiscord:priority"|"opendiscord:logs"},
"opendiscord:transfer":{origin:"slash"|"text",params:{},workers:"opendiscord:transfer"|"opendiscord:logs"},
"opendiscord:autoclose":{origin:"slash"|"text",params:{},workers:"opendiscord:autoclose"|"opendiscord:logs"},
"opendiscord:autodelete":{origin:"slash"|"text",params:{},workers:"opendiscord:autodelete"|"opendiscord:logs"},
}
/**## ODButtonResponderManagerIdMappings `interface`
* A list of all available IDs in the default `ODButtonResponderManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODButtonResponderManagerIdMappings extends api.ODButtonResponderManagerIdConstraint {
"opendiscord:verifybar-button":{origin:"button",params:{},workers:"opendiscord:verifybar-button"},
"opendiscord:help-menu-switch":{origin:"button",params:{},workers:"opendiscord:update-help-menu"},
"opendiscord:help-menu-previous":{origin:"button",params:{},workers:"opendiscord:update-help-menu"},
"opendiscord:help-menu-next":{origin:"button",params:{},workers:"opendiscord:update-help-menu"},
"opendiscord:ticket-option":{origin:"button",params:{},workers:"opendiscord:ticket-option"},
"opendiscord:role-option":{origin:"button",params:{},workers:"opendiscord:role-option"},
"opendiscord:claim-ticket":{origin:"button",params:{},workers:"opendiscord:claim-ticket"},
"opendiscord:unclaim-ticket":{origin:"button",params:{},workers:"opendiscord:unclaim-ticket"},
"opendiscord:pin-ticket":{origin:"button",params:{},workers:"opendiscord:pin-ticket"},
"opendiscord:unpin-ticket":{origin:"button",params:{},workers:"opendiscord:unpin-ticket"},
"opendiscord:close-ticket":{origin:"button",params:{},workers:"opendiscord:close-ticket"},
"opendiscord:reopen-ticket":{origin:"button",params:{},workers:"opendiscord:reopen-ticket"},
"opendiscord:delete-ticket":{origin:"button",params:{},workers:"opendiscord:delete-ticket"},
"opendiscord:transcript-error-retry":{origin:"button",params:{},workers:"opendiscord:delete-ticket"|"opendiscord:logs"},
"opendiscord:transcript-error-continue":{origin:"button",params:{},workers:"opendiscord:delete-ticket"|"opendiscord:logs"},
"opendiscord:clear-continue":{origin:"button",params:{},workers:"opendiscord:clear-continue"},
}
/**## ODDropdownResponderManagerIdMappings `interface`
* A list of all available IDs in the default `ODDropdownResponderManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODDropdownResponderManagerIdMappings extends api.ODDropdownResponderManagerIdConstraint {
"opendiscord:panel-dropdown-tickets":{origin:"dropdown",params:{},workers:"opendiscord:panel-dropdown-tickets"},
}
/**## ODModalResponderManagerIdMappings `interface`
* A list of all available IDs in the default `ODModalResponderManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODModalResponderManagerIdMappings extends api.ODModalResponderManagerIdConstraint {
"opendiscord:ticket-questions":{origin:"modal",params:{},workers:"opendiscord:ticket-questions"},
"opendiscord:close-ticket-reason":{origin:"modal",params:{},workers:"opendiscord:close-ticket-reason"},
"opendiscord:reopen-ticket-reason":{origin:"modal",params:{},workers:"opendiscord:reopen-ticket-reason"},
"opendiscord:delete-ticket-reason":{origin:"modal",params:{},workers:"opendiscord:delete-ticket-reason"},
"opendiscord:claim-ticket-reason":{origin:"modal",params:{},workers:"opendiscord:claim-ticket-reason"},
"opendiscord:unclaim-ticket-reason":{origin:"modal",params:{},workers:"opendiscord:unclaim-ticket-reason"},
"opendiscord:pin-ticket-reason":{origin:"modal",params:{},workers:"opendiscord:pin-ticket-reason"},
"opendiscord:unpin-ticket-reason":{origin:"modal",params:{},workers:"opendiscord:unpin-ticket-reason"},
}
/**## ODContextMenuResponderManagerIdMappings `interface`
* A list of all available IDs in the default `ODContextMenuResponderManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODContextMenuResponderManagerIdMappings extends api.ODContextMenuResponderManagerIdConstraint {
//"opendiscord:example":{origin:"context-menu",params:{},workers:"opendiscord:example"},
}
/**## ODAutocompleteResponderManagerIdMappings `interface`
* A list of all available IDs in the default `ODAutocompleteResponderManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODAutocompleteResponderManagerIdMappings extends api.ODAutocompleteResponderManagerIdConstraint {
"opendiscord:panel-id":{origin:"autocomplete",params:{},workers:"opendiscord:panel-id"},
"opendiscord:option-id":{origin:"autocomplete",params:{},workers:"opendiscord:option-id"}
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedCommandResponderManager `class
* A special class with types for the Open Ticket `ODCommandResponderManager` class.
*/
export class ODMappedCommandResponderManager extends api.ODCommandResponderManager<ODCommandResponderManagerIdMappings> {}
/**## ODMappedButtonResponderManager `class
* A special class with types for the Open Ticket `ODButtonResponderManager` class.
*/
export class ODMappedButtonResponderManager extends api.ODButtonResponderManager<ODButtonResponderManagerIdMappings> {}
/**## ODMappedDropdownResponderManager `class
* A special class with types for the Open Ticket `ODDropdownResponderManager` class.
*/
export class ODMappedDropdownResponderManager extends api.ODDropdownResponderManager<ODDropdownResponderManagerIdMappings> {}
/**## ODMappedModalResponderManager `class
* A special class with types for the Open Ticket `ODModalResponderManager` class.
*/
export class ODMappedModalResponderManager extends api.ODModalResponderManager<ODModalResponderManagerIdMappings> {}
/**## ODMappedContextMenuResponderManager `class
* A special class with types for the Open Ticket `ODContextMenuResponderManager` class.
*/
export class ODMappedContextMenuResponderManager extends api.ODContextMenuResponderManager<ODContextMenuResponderManagerIdMappings> {}
/**## ODMappedAutocompleteResponderManager `class
* A special class with types for the Open Ticket `ODAutocompleteResponderManager` class.
*/
export class ODMappedAutocompleteResponderManager extends api.ODAutocompleteResponderManager<ODAutocompleteResponderManagerIdMappings> {}
/**## ODMappedResponderManager `class
* A special class with types for the Open Ticket `ODResponderManager` class.
*/
export class ODMappedResponderManager extends api.ODResponderManager<ODCommandResponderManagerIdMappings,ODButtonResponderManagerIdMappings,ODDropdownResponderManagerIdMappings,ODModalResponderManagerIdMappings,ODContextMenuResponderManagerIdMappings,ODAutocompleteResponderManagerIdMappings> {}
+21
View File
@@ -0,0 +1,21 @@
///////////////////////////////////////
//OPEN TICKET SESSION MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODSessionManagerIdMappings `interface`
* A list of all available IDs in the default `ODSessionManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODSessionManagerIdMappings extends api.ODSessionManagerIdConstraint {
//"opendiscord:example-session":api.ODSession
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedSessionManager `class
* A special class with types for the Open Ticket `ODSessionManager` class.
*/
export class ODMappedSessionManager extends api.ODSessionManager<ODSessionManagerIdMappings> {}
+28
View File
@@ -0,0 +1,28 @@
///////////////////////////////////////
//OPEN TICKET STARTSCREEN MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
import { ODLiveStatusManagerIdMappings } from "./console.js"
/**## ODStartScreenManagerIdMappings `interface`
* A list of all available IDs in the default `ODStartScreenManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODStartScreenManagerIdMappings extends api.ODStartScreenManagerIdConstraint {
"opendiscord:logo":api.ODStartScreenLogoComponent,
"opendiscord:header":api.ODStartScreenHeaderComponent,
"opendiscord:flags":api.ODStartScreenFlagsCategoryComponent,
"opendiscord:plugins":api.ODStartScreenPluginsCategoryComponent,
"opendiscord:stats":api.ODStartScreenPropertiesCategoryComponent,
"opendiscord:livestatus":api.ODStartScreenLiveStatusCategoryComponent<api.ODLiveStatusManager<ODLiveStatusManagerIdMappings>>,
"opendiscord:logs":api.ODStartScreenCategoryComponent
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedStartScreenManager `class
* A special class with types for the Open Ticket `ODStartScreenManager` class.
*/
export class ODMappedStartScreenManager extends api.ODStartScreenManager<ODStartScreenManagerIdMappings> {}
+62
View File
@@ -0,0 +1,62 @@
///////////////////////////////////////
//OPEN TICKET STATE MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
import * as discord from "discord.js"
import { ODTicketClearFilter } from "../api/ticket.js"
/**## ODStateManagerIdMappings `interface`
* A list of all available IDs in the default `ODStateManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODStateManagerIdMappings extends api.ODStateManagerIdConstraint {
"opendiscord:interactive-message":ODInteractiveMessageState,
"opendiscord:clear-message":ODClearMessageState,
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedStateManager `class
* A special class with types for the Open Ticket `ODStateManager` class.
*/
export class ODMappedStateManager extends api.ODStateManager<ODStateManagerIdMappings> {}
/**## ODInteractiveMessageState `class
* A special class with state types for interactive Open Ticket message.
*/
export class ODInteractiveMessageState extends api.ODState<{
/**The method this message was generated with. */
messageOrigin:"slash"|"text"|"button"|"dropdown"|"modal"|"other",
/**The type of message. Used when editing messages. */
messageType:"ticket-message"|"close-message"|"reopen-message"|"autoclose-message"|"claim-message"|"unclaim-message"|"pin-message"|"unpin-message",
/**A reason this interactive message was generated. */
messageReason?:string|null,
/**The original author of this interactive message. */
messageAuthor?:string,
/**Additional data of this interactive message. */
messageExtraData?:any,
},false,false> {
constructor(id:api.ODValidId,client:api.ODClientManager,database:api.ODDatabase){
super(id,client,database,{})
}
}
/**## ODClearMessageState `class
* A special class with state types for the Open Ticket clear tickets message.
*/
export class ODClearMessageState extends api.ODState<{
/**The method this message was generated with. */
messageOrigin:"slash"|"text"|"other",
/**The clear filters. */
clearFilter:ODTicketClearFilter,
/**The list of ticket channel names (e.g. `#ticket-1`) to be cleared. */
clearChannelNameList:string[]
},false,true> {
constructor(id:api.ODValidId,client:api.ODClientManager,database:api.ODDatabase){
super(id,client,database,{
autodeleteOnRestart:true
})
}
}
+143
View File
@@ -0,0 +1,143 @@
///////////////////////////////////////
//OPEN TICKET STATISTICS MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODStatisticManagerIdMappings `interface`
* A list of all available IDs in the default `ODStatisticManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatisticManagerIdMappings extends api.ODStatisticManagerIdConstraint {
"opendiscord:global":ODGlobalStatisticScope,
"opendiscord:system":ODSystemStatisticScope,
"opendiscord:user":ODUserStatisticScope,
"opendiscord:ticket":ODTicketStatisticScope,
"opendiscord:participants":ODParticipantsStatisticScope,
"opendiscord:messages":ODMessagesStatisticScope,
}
/////////////////////////////////////////
// STATISTICS MAPPINGS, CATEGORIES & TYPES
/////////////////////////////////////////
/**## ODGlobalStatisticScopeIdMappings `interface`
* A list of all available IDs in the default `ODGlobalStatisticScope` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODGlobalStatisticScopeIdMappings extends api.ODStatisticScopeIdConstraint {
"opendiscord:tickets-created":api.ODBaseStatistic,
"opendiscord:tickets-closed":api.ODBaseStatistic,
"opendiscord:tickets-deleted":api.ODBaseStatistic,
"opendiscord:tickets-reopened":api.ODBaseStatistic,
"opendiscord:tickets-autoclosed":api.ODBaseStatistic,
"opendiscord:tickets-autodeleted":api.ODBaseStatistic,
"opendiscord:tickets-claimed":api.ODBaseStatistic,
"opendiscord:tickets-pinned":api.ODBaseStatistic,
"opendiscord:tickets-moved":api.ODBaseStatistic,
"opendiscord:tickets-transferred":api.ODBaseStatistic,
"opendiscord:users-blacklisted":api.ODBaseStatistic,
"opendiscord:transcripts-created":api.ODBaseStatistic,
"opendiscord:ticket-volume":api.ODDynamicStatistic,
"opendiscord:average-tickets":api.ODDynamicStatistic,
}
/**## ODSystemStatisticScopeIdMappings `interface`
* A list of all available IDs in the default `ODSystemStatisticScope` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODSystemStatisticScopeIdMappings extends api.ODStatisticScopeIdConstraint {
"opendiscord:startup-date":api.ODDynamicStatistic,
"opendiscord:system-uptime":api.ODDynamicStatistic,
"opendiscord:version":api.ODDynamicStatistic
}
/**## ODUserStatisticScopeIdMappings `interface`
* A list of all available IDs in the default `ODUserStatisticScope` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODUserStatisticScopeIdMappings extends api.ODStatisticScopeIdConstraint {
"opendiscord:name":api.ODDynamicStatistic,
"opendiscord:role":api.ODDynamicStatistic,
"opendiscord:tickets-created":api.ODBaseStatistic,
"opendiscord:tickets-closed":api.ODBaseStatistic,
"opendiscord:tickets-deleted":api.ODBaseStatistic,
"opendiscord:tickets-reopened":api.ODBaseStatistic,
"opendiscord:tickets-claimed":api.ODBaseStatistic,
"opendiscord:tickets-pinned":api.ODBaseStatistic,
"opendiscord:tickets-moved":api.ODBaseStatistic,
"opendiscord:tickets-transferred":api.ODBaseStatistic,
"opendiscord:users-blacklisted":api.ODBaseStatistic,
"opendiscord:transcripts-created":api.ODBaseStatistic,
"opendiscord:current-tickets":api.ODDynamicStatistic,
}
/**## ODTicketStatisticScopeIdMappings `interface`
* A list of all available IDs in the default `ODTicketStatisticScope` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODTicketStatisticScopeIdMappings extends api.ODStatisticScopeIdConstraint {
"opendiscord:name":api.ODDynamicStatistic,
"opendiscord:status":api.ODDynamicStatistic,
"opendiscord:claimed":api.ODDynamicStatistic,
"opendiscord:pinned":api.ODDynamicStatistic,
"opendiscord:creation-date":api.ODDynamicStatistic,
"opendiscord:creator":api.ODDynamicStatistic,
"opendiscord:ticket-age":api.ODDynamicStatistic,
"opendiscord:response-time":api.ODDynamicStatistic,
"opendiscord:resolution-time":api.ODDynamicStatistic,
}
/**## ODParticipantsStatisticScopeIdMappings `interface`
* A list of all available IDs in the default `ODParticipantsStatisticScope` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODParticipantsStatisticScopeIdMappings extends api.ODStatisticScopeIdConstraint {
"opendiscord:participants":api.ODDynamicStatistic
}
/**## ODMessagesStatisticScopeIdMappings `interface`
* A list of all available IDs in the default `ODMessagesStatisticScope` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODMessagesStatisticScopeIdMappings extends api.ODStatisticScopeIdConstraint {
"opendiscord:count":api.ODDynamicStatistic
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedStatisticManager `class
* A special class with types for the Open Ticket `ODStatisticManager` class.
*/
export class ODMappedStatisticManager extends api.ODStatisticManager<ODStatisticManagerIdMappings> {}
/**## ODGlobalStatisticScope `class
* A special class with types for the Open Ticket `Global` statistics category/scope.
*/
export class ODGlobalStatisticScope extends api.ODStatisticGlobalScope<ODGlobalStatisticScopeIdMappings> {}
/**## ODSystemStatisticScope `class
* A special class with types for the Open Ticket `System` statistics category/scope.
*/
export class ODSystemStatisticScope extends api.ODStatisticGlobalScope<ODSystemStatisticScopeIdMappings> {}
/**## ODUserStatisticScope `class
* A special class with types for the Open Ticket `User` statistics category/scope.
*/
export class ODUserStatisticScope extends api.ODStatisticScope<ODUserStatisticScopeIdMappings> {}
/**## ODTicketStatisticScope `class
* A special class with types for the Open Ticket `Ticket` statistics category/scope.
*/
export class ODTicketStatisticScope extends api.ODStatisticScope<ODTicketStatisticScopeIdMappings> {}
/**## ODParticipantsStatisticScope `class
* A special class with types for the Open Ticket `Participants` statistics category/scope.
*/
export class ODParticipantsStatisticScope extends api.ODStatisticScope<ODParticipantsStatisticScopeIdMappings> {}
/**## ODMessagesStatisticScope `class
* A special class with types for the Open Ticket `Messages` statistics category/scope.
*/
export class ODMessagesStatisticScope extends api.ODStatisticScope<ODMessagesStatisticScopeIdMappings> {}
+37
View File
@@ -0,0 +1,37 @@
///////////////////////////////////////
//OPEN TICKET VERIFYBAR MAPPINGS
///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api"
/**## ODVerifyBarManagerIdMappings `interface`
* A list of all available IDs in the default `ODVerifyBarManager` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODVerifyBarManagerIdMappings extends api.ODVerifyBarManagerIdConstraint {
"opendiscord:close-ticket":api.ODVerifyBar<"accept"|"cancel"|"accept-with-reason","opendiscord:close-ticket">,
"opendiscord:reopen-ticket":api.ODVerifyBar<"accept"|"cancel"|"accept-with-reason","opendiscord:reopen-ticket">,
"opendiscord:delete-ticket":api.ODVerifyBar<"accept"|"cancel"|"accept-with-reason"|"accept-without-transcript","opendiscord:delete-ticket">,
"opendiscord:claim-ticket":api.ODVerifyBar<"accept"|"cancel"|"accept-with-reason","opendiscord:claim-ticket">,
"opendiscord:unclaim-ticket":api.ODVerifyBar<"accept"|"cancel"|"accept-with-reason","opendiscord:unclaim-ticket">,
"opendiscord:pin-ticket":api.ODVerifyBar<"accept"|"cancel"|"accept-with-reason","opendiscord:pin-ticket">,
"opendiscord:unpin-ticket":api.ODVerifyBar<"accept"|"cancel"|"accept-with-reason","opendiscord:unpin-ticket">,
}
/**## ODVerifyButtonId `enum`
* Frequently used button ids in Open Ticket verify bars.
*/
export enum ODVerifyButtonId {
Cancel="cancel",
Accept="accept",
AcceptWithReason="accept-with-reason",
AcceptWithoutTranscript="accept-without-transcript"
}
/////////////////////////////
////// MAPPED MANAGERS //////
/////////////////////////////
/**## ODMappedVerifyBarManager `class
* A special class with types for the Open Ticket `ODVerifyBarManager` class.
*/
export class ODMappedVerifyBarManager extends api.ODVerifyBarManager<ODVerifyBarManagerIdMappings> {}
-49
View File
@@ -1,49 +0,0 @@
import {opendiscord, api, utilities} from "../../index"
import * as discord from "discord.js"
import * as fs from "fs"
/** WHAT IS THIS??
* This is the '!OPENTICKET:dump' command.
* It's a utility command which can only be used by the creator of Open Ticket or the owner of the bot.
* This command will send the `otdebug.txt` file in DM. It's not dangerous as the `otdebug.txt` file doesn't contain any sensitive data (only logs).
*
* WHY DOES IT EXIST??
* This command can be used to quickly get the `otdebug.txt` file without having access to the hosting
* in case you're helping someone with setting up (or debugging) Open Ticket.
*
* CAN I DISABLE IT??
* If you want to turn it off, you can always do it below this message!
*/
///////// DISABLE DUMP COMMAND /////////
const disableDumpCommand = false
////////////////////////////////////////
export const loadDumpCommand = () => {
if (disableDumpCommand) return
opendiscord.client.textCommands.add(new api.ODTextCommand("opendiscord:dump",{
allowBots:false,
guildPermission:true,
dmPermission:true,
name:"dump",
prefix:"!OPENTICKET:"
}))
opendiscord.client.textCommands.onInteraction("!OPENTICKET:","dump",async (msg) => {
if (msg.author.id == "779742674932072469" || opendiscord.permissions.hasPermissions("developer",await opendiscord.permissions.getPermissions(msg.author,msg.channel,null))){
//user is bot owner OR creator of Open Ticket :)
opendiscord.log("Dumped otdebug.txt!","system",[
{key:"user",value:msg.author.username},
{key:"id",value:msg.author.id}
])
const debug = fs.readFileSync("./otdebug.txt")
if (msg.channel.type != discord.ChannelType.GroupDM) msg.channel.send({content:"## The `otdebug.txt` dump is available!",files:[
new discord.AttachmentBuilder(debug)
.setName("otdebug.txt")
.setDescription("The Open Ticket debug dump!")
]})
}
})
}
-281
View File
@@ -1,281 +0,0 @@
import * as fs from "fs"
let tempErrors: string[] = []
const tempError = () => {
if (tempErrors.length > 0){
console.log("\n\n==============================\n[OPEN TICKET ERROR]: "+tempErrors.join("\n[OPEN TICKET ERROR]: ")+"\n==============================\n\n")
process.exit(1)
}
tempErrors = []
}
const nodev = process.versions.node.split(".")
if (Number(nodev[0]) < 18){
tempErrors.push("Invalid node.js version. Open Ticket requires node.js v18 or above!")
}
tempError()
const moduleInstalled = (id:string, throwError:boolean) => {
try{
require.resolve(id)
return true
}catch{
if (throwError) tempErrors.push("npm module \""+id+"\" is not installed! Install it via 'npm install "+id+"'")
return false
}
}
moduleInstalled("@discordjs/rest",true)
moduleInstalled("discord.js",true)
moduleInstalled("ansis",true)
moduleInstalled("formatted-json-stringify",true)
moduleInstalled("typescript",true)
moduleInstalled("terminal-kit",true)
tempError()
//init API
import * as api from "../api/api" //import for local use
export * as api from "../api/api" //export to other parts of bot
import ansis from "ansis" //import ansis for usage in initialization
export const opendiscord = new api.ODMain()
console.log("\n--------------------------- OPEN TICKET STARTUP ---------------------------")
opendiscord.log("Logging system activated!","system")
opendiscord.debug.debug("Using Node.js "+process.version+"!")
try{
const packageJson = JSON.parse(fs.readFileSync("./package.json").toString())
opendiscord.debug.debug("Using discord.js "+packageJson.dependencies["discord.js"]+"!")
opendiscord.debug.debug("Using @discordjs/rest "+packageJson.dependencies["@discordjs/rest"]+"!")
opendiscord.debug.debug("Using ansis "+packageJson.dependencies["ansis"]+"!")
opendiscord.debug.debug("Using formatted-json-stringify "+packageJson.dependencies["formatted-json-stringify"]+"!")
opendiscord.debug.debug("Using terminal-kit "+packageJson.dependencies["terminal-kit"]+"!")
opendiscord.debug.debug("Using typescript "+packageJson.dependencies["typescript"]+"!")
}catch{
opendiscord.debug.debug("Failed to fetch module versions!")
}
const timer = (ms:number): Promise<void> => {
return new Promise((resolve) => {
setTimeout(() => {
resolve()
},ms)
})
}
export interface ODUtilities {
/**## project `utility variable`
* This is the name of the project you are currently in.
*
* Developers can use this to create a multi-plugin compatible with all bots supporting the `open-discord` framework!
*/
project:"openticket"
/**## isBeta `utility variable`
* Check if you're running a beta version of Open Ticket.
*/
isBeta:boolean
/**## moduleInstalled `utility function`
* Use this function to check if an npm package is installed or not!
* @example utilities.moduleInstalled("discord.js") //check if discord.js is installed
*/
moduleInstalled(id:string): boolean
/**## timer `utility function`
* Use this to wait for a certain amount of milliseconds. This only works when using `await`
* @example await utilities.timer(1000) //wait 1sec
*/
timer(ms:number): Promise<void>
/**## emojiTitle `utility function`
* Use this function to create a title with an emoji before/after the text. The style & divider are set in `opendiscord.defaults`
* @example utilities.emojiTitle("📎","Links") //create a title with an emoji based on the bot emoji style
*/
emojiTitle(emoji:string, text:string): string
/**## runAsync `utility function`
* Use this function to run a snippet of code asyncronous without creating a separate function for it!
*/
runAsync(func:() => Promise<void>): void
/**## timedAwait `utility function`
* Use this function to await a promise but reject after the certain timeout has been reached.
*/
timedAwait<ReturnValue extends Promise<any>>(promise:ReturnValue, timeout:number, onError:(err:Error) => void): ReturnValue
/**## dateString `utility function`
* Use this function to create a short date string in the following format: `DD/MM/YYYY HH:MM:SS`
*/
dateString(date:Date): string
/**## asyncReplace `utility function`
* Same as `string.replace(search, value)` but with async compatibility
*/
asyncReplace(text:string, regex:RegExp, func:(value:string,...args:any[]) => Promise<string>): Promise<string>
/**## getLongestLength `utility function`
* Get the length of the longest string in the array.
*/
getLongestLength(text:string[]): number
/**## easterEggs `utility object`
* Object containing data for Open Ticket easter eggs.
*/
easterEggs: api.ODEasterEggs,
/**## ODVersionMigration `utility class`
* This class is used to manage data migration between Open Ticket versions.
*
* It shouldn't be used by plugins because this is an internal API feature!
*/
ODVersionMigration:new (version:api.ODVersion,func:() => void|Promise<void>,afterInitFunc:() => void|Promise<void>) => ODVersionMigration,
/**## ordinalNumber `utility function`
* Get a human readable ordinal number (e.g. 1st, 2nd, 3rd, 4th, ...) from a Javascript number.
*/
ordinalNumber(num:number): string,
/**## trimEmojis `utility function`
* Trim/remove all emoji's from a Javascript string.
*/
trimEmojis(text:string): string,
}
/**## ODVersionMigration `utility class`
* This class is used to manage data migration between Open Ticket versions.
*
* It shouldn't be used by plugins because this is an internal API feature!
*/
export class ODVersionMigration {
/**The version to migrate data to */
version: api.ODVersion
/**The migration function */
#func: () => void|Promise<void>
/**The migration function */
#afterInitFunc: () => void|Promise<void>
constructor(version:api.ODVersion,func:() => void|Promise<void>,afterInitFunc:() => void|Promise<void>){
this.version = version
this.#func = func
this.#afterInitFunc = afterInitFunc
}
/**Run this version migration as a plugin. Returns `false` when something goes wrong. */
async migrate(): Promise<boolean> {
try{
await this.#func()
return true
}catch(err){
process.emit("uncaughtException",err)
return false
}
}
/**Run this version migration as a plugin (after other plugins have loaded). Returns `false` when something goes wrong. */
async migrateAfterInit(): Promise<boolean> {
try{
await this.#afterInitFunc()
return true
}catch(err){
process.emit("uncaughtException",err)
return false
}
}
}
export const utilities: ODUtilities = {
project:"openticket",
isBeta:false,
moduleInstalled:(id:string) => {
return moduleInstalled(id,false)
},
timer,
emojiTitle(emoji:string, text:string){
const style = opendiscord.defaults.getDefault("emojiTitleStyle")
const divider = opendiscord.defaults.getDefault("emojiTitleDivider")
if (style == "disabled") return text
else if (style == "before") return emoji+divider+text
else if (style == "after") return text+divider+emoji
else if (style == "double") return emoji+divider+text+divider+emoji
else return text
},
runAsync(func){
func()
},
timedAwait<ReturnValue>(promise:ReturnValue,timeout:number,onError:(err:Error) => void): ReturnValue {
let allowResolve = true
return new Promise(async (resolve,reject) => {
//set timeout & stop if it is before the promise resolved
setTimeout(() => {
allowResolve = false
reject("utilities.timedAwait() => Promise Timeout")
},timeout)
//get promise result & return if not already rejected
try{
const res = await promise
if (allowResolve) resolve(res)
}catch(err){
onError(err)
}
return promise
}) as ReturnValue
},
dateString(date): string {
return `${date.getDate()}/${date.getMonth()+1}/${date.getFullYear()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
},
async asyncReplace(text,regex,func): Promise<string> {
const promises: Promise<string>[] = []
text.replace(regex,(match,...args) => {
promises.push(func(match,...args))
return match
})
const data = await Promise.all(promises)
const result = text.replace(regex,(match) => {
const replaceResult = data.shift()
return replaceResult ?? match
})
return result
},
getLongestLength(texts:string[]): number {
return Math.max(...texts.map((t) => ansis.strip(t).length))
},
easterEggs:{
/* THANK YOU TO ALL OUR CONTRIBUTORS!!! */
creator:"779742674932072469", //DJj123dj
translators:[
"779742674932072469", //DJj123dj
"574172558006681601", //Sanke
"540639725300613136", //Guillee.3
"547231585368539136", //Mods HD
"664934139954331649", //SpyEye
"498055992962187264", //Redactado
"912052735950618705", //T0miiis
"366673202610569227", //johusens
"360780292853858306", //David.3
"950611418389024809", //Sarcastic
"461603955517161473", //Maurizo
"465111430274875402", //The_Gamer
"586376952470831104", //Erxg
"226695254433202176", //Mkevas
"437695615095275520", //NoOneNook
"530047191222583307", //Anderskiy
"719072181631320145", //ToStam
"1172870906377408512", //Stragar
"1084794575945744445", //Sasanwm
"449613814049275905", //Benzorich
"905373133085741146", //Ronalds
"918504977369018408", //Palestinian
"807970841035145216", //Kornel0706
"1198883915826475080", //Nova
"669988226819162133", //Danoglez
"1313597620996018271", //Fraden1
"547809968145956884", //TsgIndrius
"264120132660363267", //Quiradon
"1272034143777329215", //NotMega
"LOREMIPSUM", //TODO
]
},
ODVersionMigration,
ordinalNumber(num:number){
const i = Math.abs(Math.round(num))
const cent = i % 100
if (cent >= 10 && cent <= 20) return i+'th'
const dec = i % 10
if (dec === 1) return i+'st'
if (dec === 2) return i+'nd'
if (dec === 3) return i+'rd'
return i+'th'
},
trimEmojis(text){
return text.replace(/(\p{Extended_Pictographic}(?:\uFE0F|\uFE0E)?(?:\u200D\p{Extended_Pictographic}(?:\uFE0F|\uFE0E)?)*)/gu,"")
},
}
+96 -50
View File
@@ -1,9 +1,24 @@
import {opendiscord, api, utilities} from "../../index"
import {opendiscord, api, utilities} from "../../index.js"
import fs from "fs"
import path from "path"
/**Check if the no-migration flag is active. */
function isMigrationAllowedFromFlag(){
return (!process.argv.includes("--no-migration") && !process.argv.includes("-nm"))
}
/**Read the global.json database raw to detect the last version of the bot. */
function getRawLastVersion(){
const isDevDatabase = process.argv.includes("--dev-database") || process.argv.includes("-dd")
const globalDatabaseLocation = path.join(process.cwd(),(isDevDatabase) ? "./devdatabase/global.json" : "./database/global.json")
const rawData: api.ODJsonDatabaseStructure = JSON.parse(fs.readFileSync(globalDatabaseLocation).toString())
const lastVersion = rawData.find((d) => d.category == "opendiscord:last-version" && d.key == "opendiscord:version")?.value ?? null
return lastVersion as string|null
}
/**Check if migration is required. Returns the last version used in the database. */
async function isMigrationRequired(): Promise<false|api.ODVersion> {
const rawVersion = await opendiscord.databases.get("opendiscord:global").get("opendiscord:last-version","opendiscord:version")
const rawVersion = getRawLastVersion()
if (!rawVersion) return false
const version = api.ODVersion.fromString("opendiscord:last-version",rawVersion)
if (opendiscord.versions.get("opendiscord:version").compare(version) == "higher"){
@@ -20,47 +35,6 @@ async function saveAllVersionsToDatabase(){
})
}
export const loadVersionMigrationSystem = async () => {
//ENTER MIGRATION CONTEXT
await preloadMigrationContext()
const lastVersion = await isMigrationRequired()
//save last version to database (OR set to current version if no migration is required)
opendiscord.versions.add(lastVersion ? lastVersion : api.ODVersion.fromString("opendiscord:last-version",opendiscord.versions.get("opendiscord:version").toString()))
if (lastVersion && !opendiscord.flags.get("opendiscord:no-migration").value){
//MIGRATION IS REQUIRED
opendiscord.log("Detected old data!","info")
opendiscord.log("Starting closed API context...","debug")
await utilities.timer(600)
opendiscord.log("Migrating data to new version...","debug")
await loadAllVersionMigrations(lastVersion)
opendiscord.log("Stopping closed API context...","debug")
await utilities.timer(400)
opendiscord.log("All data is now up to date!","info")
await utilities.timer(200)
console.log("---------------------------------------------------------------------")
}
saveAllVersionsToDatabase()
//DEFAULT FLAGS
if (opendiscord.flags.exists("opendiscord:no-plugins") && opendiscord.flags.get("opendiscord:no-plugins").value) opendiscord.defaults.setDefault("pluginLoading",false)
if (opendiscord.flags.exists("opendiscord:soft-plugins") && opendiscord.flags.get("opendiscord:soft-plugins").value) opendiscord.defaults.setDefault("softPluginLoading",true)
if (opendiscord.flags.exists("opendiscord:crash") && opendiscord.flags.get("opendiscord:crash").value) opendiscord.defaults.setDefault("crashOnError",true)
if (opendiscord.flags.exists("opendiscord:force-slash-update") && opendiscord.flags.get("opendiscord:force-slash-update").value){
opendiscord.defaults.setDefault("forceSlashCommandRegistration",true)
opendiscord.defaults.setDefault("forceContextMenuRegistration",true)
}
if (opendiscord.flags.exists("opendiscord:silent") && opendiscord.flags.get("opendiscord:silent").value) opendiscord.console.silent = true
//LEAVE MIGRATION CONTEXT
await unloadMigrationContext()
return lastVersion
}
/**Initialize the migration context by loading the built-in flags, configs & databases. */
async function preloadMigrationContext(){
opendiscord.debug.debug("-- MIGRATION CONTEXT START --")
@@ -73,6 +47,52 @@ async function preloadMigrationContext(){
opendiscord.debug.visible = true
}
export async function loadVersionMigrationSystem(){
const lastVersion = await isMigrationRequired()
//save last version in version manager (OR set to current version if no migration is required)
opendiscord.versions.add(lastVersion ? lastVersion : api.ODVersion.fromString("opendiscord:last-version",opendiscord.versions.get("opendiscord:version").toString()))
//MIGRATION IS REQUIRED
if (lastVersion && isMigrationAllowedFromFlag()){
//BEFORE STARTUP MIGRATION
opendiscord.log("Detected old data!","info")
await loadBeforeStartupMigrations(lastVersion)
}
//ENTER MIGRATION CONTEXT (must be separate for flags to work)
await preloadMigrationContext()
if (lastVersion && isMigrationAllowedFromFlag()){
//CONTEXT MIGRATION
opendiscord.log("Starting restricted API context...","debug")
await utilities.timer(600)
opendiscord.log("Migrating data to new version...","debug")
await loadContextMigrations(lastVersion)
opendiscord.log("Stopping restricted API context...","debug")
await utilities.timer(400)
opendiscord.log("All data is now up to date!","info")
await utilities.timer(200)
console.log("---------------------------------------------------------------------")
}
saveAllVersionsToDatabase()
//SET FUSES & PROPERTIES OF SPECIAL FLAGS
if (opendiscord.flags.exists("opendiscord:no-plugins") && opendiscord.flags.get("opendiscord:no-plugins").value) opendiscord.sharedFuses.setFuse("pluginLoading",false)
if (opendiscord.flags.exists("opendiscord:soft-plugins") && opendiscord.flags.get("opendiscord:soft-plugins").value) opendiscord.sharedFuses.setFuse("softPluginLoading",true)
if (opendiscord.flags.exists("opendiscord:crash") && opendiscord.flags.get("opendiscord:crash").value) opendiscord.sharedFuses.setFuse("crashOnError",true)
if (opendiscord.flags.exists("opendiscord:force-slash-update") && opendiscord.flags.get("opendiscord:force-slash-update").value){
opendiscord.sharedFuses.setFuse("forceSlashCommandRegistration",true)
opendiscord.sharedFuses.setFuse("forceContextMenuRegistration",true)
}
if (opendiscord.flags.exists("opendiscord:silent") && opendiscord.flags.get("opendiscord:silent").value) opendiscord.console.silent = true
//LEAVE MIGRATION CONTEXT
await unloadMigrationContext()
return lastVersion
}
/**Unload the migration context to start the bot normally. */
async function unloadMigrationContext(){
opendiscord.debug.visible = false
@@ -98,8 +118,8 @@ function createMigrationBackup(){
else fs.cpSync("./database/","./.backup/database/",{force:true,recursive:true})
}
/**Execute all version migration functions which are handled in the restricted migration context. */
async function loadAllVersionMigrations(lastVersion:api.ODVersion){
/**Execute all version migration functions which are handled before any flags, configs or databases are loaded. */
async function loadBeforeStartupMigrations(lastVersion:api.ODVersion){
const migrations = (await import("./migration.js")).migrations
migrations.sort((a,b) => {
const comparison = a.version.compare(b.version)
@@ -114,10 +134,36 @@ async function loadAllVersionMigrations(lastVersion:api.ODVersion){
for (const migration of migrations){
if (migration.version.compare(lastVersion) == "higher"){
const success = await migration.migrate()
const success = await migration.migrateBeforeStartup()
if (success) opendiscord.log("Migrated data to "+migration.version.toString()+"!","debug",[
{key:"success",value:success ? "true" : "false"},
{key:"afterInit",value:"false"}
{key:"type",value:"before-startup"}
])
else throw new api.ODSystemError("Migration Error: Unable to migrate database & config to the new version of the bot.")
}
}
}
/**Execute all version migration functions which are handled in the restricted migration context. */
async function loadContextMigrations(lastVersion:api.ODVersion){
const migrations = (await import("./migration.js")).migrations
migrations.sort((a,b) => {
const comparison = a.version.compare(b.version)
if (comparison == "equal") return 0
else if (comparison == "higher") return 1
else return -1
})
if (migrations.length > 0){
//create backup of config & database
createMigrationBackup()
}
for (const migration of migrations){
if (migration.version.compare(lastVersion) == "higher"){
const success = await migration.migrateInContext()
if (success) opendiscord.log("Migrated data to "+migration.version.toString()+"!","debug",[
{key:"success",value:success ? "true" : "false"},
{key:"type",value:"restricted-context"}
])
else throw new api.ODSystemError("Migration Error: Unable to migrate database & config to the new version of the bot.")
}
@@ -125,7 +171,7 @@ async function loadAllVersionMigrations(lastVersion:api.ODVersion){
}
/**Execute all version migration functions which are handled in the normal startup sequence. */
export async function loadAllAfterInitVersionMigrations(lastVersion:api.ODVersion){
export async function loadAfterStartupMigrations(lastVersion:api.ODVersion){
const migrations = (await import("./migration.js")).migrations
migrations.sort((a,b) => {
const comparison = a.version.compare(b.version)
@@ -140,10 +186,10 @@ export async function loadAllAfterInitVersionMigrations(lastVersion:api.ODVersio
for (const migration of migrations){
if (migration.version.compare(lastVersion) == "higher"){
const success = await migration.migrateAfterInit()
const success = await migration.migrateAfterStartup()
if (success) opendiscord.log("Migrated data to "+migration.version.toString()+"!","debug",[
{key:"success",value:success ? "true" : "false"},
{key:"afterInit",value:"true"}
{key:"type",value:"after-startup"}
])
else throw new api.ODSystemError("Migration Error: Unable to migrate database & config to the new version of the bot.")
}
+309 -105
View File
@@ -1,147 +1,351 @@
import {opendiscord, api, utilities} from "../../index"
import { opendiscord, api, utilities } from "../../index.js"
import fs from "fs"
import path from "path"
export const migrations = [
//MIGRATE TO v4.0.0
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.0"),async () => {},async () => {}),
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.0"),{}),
//MIGRATE TO v4.0.1
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.1"),async () => {},async () => {
//AFTER INIT MIGRATION
//add opendiscord:panel-message properties for all existing panels.
const globalDatabase = opendiscord.databases.get("opendiscord:global")
for (const panel of (await globalDatabase.getCategory("opendiscord:panel-update") ?? [])){
globalDatabase.set("opendiscord:panel-message",panel.key,panel.value)
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.1"),{
afterStartupMigrate:async () => {
//add opendiscord:panel-message properties for all existing panels.
const globalDatabase = opendiscord.databases.get("opendiscord:global")
for (const panel of (await globalDatabase.getCategory("opendiscord:panel-update") ?? [])){
globalDatabase.set("opendiscord:panel-message",panel.key,panel.value)
}
}
}),
//MIGRATE TO v4.0.2
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.2"),async () => {},async () => {}),
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.2"),{}),
//MIGRATE TO v4.0.3
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.3"),async () => {},async () => {}),
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.3"),{}),
//MIGRATE TO v4.0.4
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.4"),async () => {},async () => {}),
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.4"),{}),
//MIGRATE TO v4.0.5
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.5"),async () => {},async () => {}),
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.5"),{}),
//MIGRATE TO v4.0.6
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.6"),async () => {},async () => {}),
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.6"),{}),
//MIGRATE TO v4.0.7
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.7"),async () => {},async () => {}),
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.0.7"),{}),
//MIGRATE TO v4.1.0
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.1.0"),async () => {},async () => {
//AFTER INIT MIGRATION
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.1.0"),{
afterStartupMigrate:async () => {
//migrate config
const generalConfig = opendiscord.configs.get("opendiscord:general")
const optionConfig = opendiscord.configs.get("opendiscord:options")
//migrate config
const generalConfig = opendiscord.configs.get("opendiscord:general")
const optionConfig = opendiscord.configs.get("opendiscord:options")
if (!generalConfig.data.status.state){
//only migrate config when it hasn't been done manually by the user.
if (!generalConfig.data.status.state){
//only migrate config when it hasn't been done manually by the user.
if (!generalConfig.data["_INFO"]) throw new api.ODSystemError("Couldn't find general.json '_INFO' category.")
generalConfig.data["_INFO"].version = "open-ticket-v4.1.0"
if (!generalConfig.data._INFO) throw new api.ODSystemError("Couldn't find general.json '_INFO' category.")
generalConfig.data._INFO.version = "open-ticket-v4.1.0"
if (!generalConfig.data.status) throw new api.ODSystemError("Couldn't find general.json 'status' category.")
generalConfig.data.status.mode = generalConfig.data.status["status"] ?? "online"
generalConfig.data.status.state = ""
delete generalConfig.data.status["status"]
if (!generalConfig.data.status) throw new api.ODSystemError("Couldn't find general.json 'status' category.")
generalConfig.data.status.mode = generalConfig.data.status["status"] ?? "online"
generalConfig.data.status.state = ""
delete generalConfig.data.status["status"]
if (!generalConfig.data["system"]) throw new api.ODSystemError("Couldn't find general.json 'system' category.")
generalConfig.data["system"].displayFieldsWithQuestions = false
generalConfig.data["system"].showGlobalAdminsInPanelRoles = false
generalConfig.data["system"].alwaysShowReason = false
generalConfig.data["system"].pinEmoji = "📌"
generalConfig.data["system"].askPriorityOnTicketCreation = false
generalConfig.data["system"].disableAutocloseAfterReopen = true
generalConfig.data["system"].autodeleteRequiresClosedTicket = true
generalConfig.data["system"].adminOnlyDeleteWithoutTranscript = true
generalConfig.data["system"].allowCloseBeforeMessage = false
generalConfig.data["system"].allowCloseBeforeAdminMessage = true
generalConfig.data["system"].pinFirstTicketMessage = false
if (!generalConfig.data.system) throw new api.ODSystemError("Couldn't find general.json 'system' category.")
generalConfig.data.system.displayFieldsWithQuestions = false
generalConfig.data.system.showGlobalAdminsInPanelRoles = false
generalConfig.data.system.alwaysShowReason = false
generalConfig.data.system.pinEmoji = "📌"
generalConfig.data.system.askPriorityOnTicketCreation = false
generalConfig.data.system.disableAutocloseAfterReopen = true
generalConfig.data.system.autodeleteRequiresClosedTicket = true
generalConfig.data.system.adminOnlyDeleteWithoutTranscript = true
generalConfig.data.system.allowCloseBeforeMessage = false
generalConfig.data.system.allowCloseBeforeAdminMessage = true
generalConfig.data.system.pinFirstTicketMessage = false
generalConfig.data.system.channelTopic = {
showOptionName:true,
showOptionDescription:false,
showOptionTopic:true,
showPriority:false,
showClosed:true,
showClaimed:false,
showPinned:false,
showCreator:false,
showParticipants:false
}
if (!generalConfig.data.system.permissions) throw new api.ODSystemError("Couldn't find general.json 'system.permissions' category.")
generalConfig.data.system.permissions.transfer = "admin"
generalConfig.data.system.permissions.topic = "admin"
generalConfig.data.system.permissions.priority = "admin"
if (!generalConfig.data.system.messages) throw new api.ODSystemError("Couldn't find general.json 'system.messages' category.")
generalConfig.data.system.messages.transferring = {dm:false,logs:true}
generalConfig.data.system.messages.topicChange = {dm:false,logs:true}
generalConfig.data.system.messages.priorityChange = {dm:false,logs:true}
generalConfig.data.system.messages.reactionRole = generalConfig.data.system.messages["roleAdding"] ?? {dm:false,logs:true}
delete generalConfig.data.system.messages["roleAdding"]
delete generalConfig.data.system.messages["roleRemoving"]
for (const option of optionConfig.data){
if (option.type != "ticket") continue
option.channel.topic = option.channel["description"] ?? ""
delete option.channel["description"]
option.slowMode = {
enabled:false,
slowModeSeconds:20
generalConfig.data["system"].channelTopic = {
showOptionName:true,
showOptionDescription:false,
showOptionTopic:true,
showPriority:false,
showClosed:true,
showClaimed:false,
showPinned:false,
showCreator:false,
showParticipants:false
}
if (!generalConfig.data["system"].permissions) throw new api.ODSystemError("Couldn't find general.json 'system.permissions' category.")
generalConfig.data["system"].permissions.transfer = "admin"
generalConfig.data["system"].permissions.topic = "admin"
generalConfig.data["system"].permissions.priority = "admin"
if (!generalConfig.data["system"].messages) throw new api.ODSystemError("Couldn't find general.json 'system.messages' category.")
generalConfig.data["system"].messages.transferring = {dm:false,logs:true}
generalConfig.data["system"].messages.topicChange = {dm:false,logs:true}
generalConfig.data["system"].messages.priorityChange = {dm:false,logs:true}
generalConfig.data["system"].messages.reactionRole = generalConfig.data["system"].messages["roleAdding"] ?? {dm:false,logs:true}
delete generalConfig.data["system"].messages["roleAdding"]
delete generalConfig.data["system"].messages["roleRemoving"]
for (const option of optionConfig.data){
if (option.type != "ticket") continue
option.channel.topic = option.channel["description"] ?? ""
delete option.channel["description"]
option.slowMode = {
enabled:false,
slowModeSeconds:20
}
}
await generalConfig.save()
await optionConfig.save()
}
await generalConfig.save()
await optionConfig.save()
}
//migrate database
const optionDatabase = opendiscord.databases.get("opendiscord:options")
const ticketDatabase = opendiscord.databases.get("opendiscord:tickets")
//migrate database
const optionDatabase = opendiscord.databases.get("opendiscord:options")
const ticketDatabase = opendiscord.databases.get("opendiscord:tickets")
for (const option of (await optionDatabase.getCategory("opendiscord:used-option") ?? [])){
const optionData = option.value
const topicData = optionData.data.find((d) => d.id == "opendiscord:channel-description")
if (topicData) topicData.id = "opendiscord:channel-topic"
if (!optionData.data.find((d) => d.id == "opendiscord:slowmode-enabled")) optionData.data.push({id:"opendiscord:slowmode-enabled",value:false})
if (!optionData.data.find((d) => d.id == "opendiscord:slowmode-seconds")) optionData.data.push({id:"opendiscord:slowmode-seconds",value:20})
for (const option of (await optionDatabase.getCategory("opendiscord:used-option") ?? [])){
const optionData = option.value
const topicData = optionData.data.find((d) => d.id == "opendiscord:channel-description")
if (topicData) topicData.id = "opendiscord:channel-topic"
if (!optionData.data.find((d) => d.id == "opendiscord:slowmode-enabled")) optionData.data.push({id:"opendiscord:slowmode-enabled",value:false})
if (!optionData.data.find((d) => d.id == "opendiscord:slowmode-seconds")) optionData.data.push({id:"opendiscord:slowmode-seconds",value:20})
optionDatabase.set("opendiscord:used-option",option.key,optionData)
}
optionDatabase.set("opendiscord:used-option",option.key,optionData)
}
for (const ticket of (await ticketDatabase.getCategory("opendiscord:ticket") ?? [])){
const ticketData = ticket.value
if (!ticketData.data.find((d) => d.id == "opendiscord:previous-creators")) ticketData.data.push({id:"opendiscord:previous-creators",value:[]})
if (!ticketData.data.find((d) => d.id == "opendiscord:reopened")) ticketData.data.push({id:"opendiscord:reopened",value:false})
if (!ticketData.data.find((d) => d.id == "opendiscord:reopened-by")) ticketData.data.push({id:"opendiscord:reopened-by",value:null})
if (!ticketData.data.find((d) => d.id == "opendiscord:reopened-on")) ticketData.data.push({id:"opendiscord:reopened-on",value:null})
if (!ticketData.data.find((d) => d.id == "opendiscord:priority")) ticketData.data.push({id:"opendiscord:priority",value:-1})
if (!ticketData.data.find((d) => d.id == "opendiscord:topic")) ticketData.data.push({id:"opendiscord:topic",value:""})
if (!ticketData.data.find((d) => d.id == "opendiscord:message-sent")) ticketData.data.push({id:"opendiscord:message-sent",value:true})
if (!ticketData.data.find((d) => d.id == "opendiscord:admin-message-sent")) ticketData.data.push({id:"opendiscord:admin-message-sent",value:true})
for (const ticket of (await ticketDatabase.getCategory("opendiscord:ticket") ?? [])){
const ticketData = ticket.value
if (!ticketData.data.find((d) => d.id == "opendiscord:previous-creators")) ticketData.data.push({id:"opendiscord:previous-creators",value:[]})
if (!ticketData.data.find((d) => d.id == "opendiscord:reopened")) ticketData.data.push({id:"opendiscord:reopened",value:false})
if (!ticketData.data.find((d) => d.id == "opendiscord:reopened-by")) ticketData.data.push({id:"opendiscord:reopened-by",value:null})
if (!ticketData.data.find((d) => d.id == "opendiscord:reopened-on")) ticketData.data.push({id:"opendiscord:reopened-on",value:null})
if (!ticketData.data.find((d) => d.id == "opendiscord:priority")) ticketData.data.push({id:"opendiscord:priority",value:-1})
if (!ticketData.data.find((d) => d.id == "opendiscord:topic")) ticketData.data.push({id:"opendiscord:topic",value:""})
if (!ticketData.data.find((d) => d.id == "opendiscord:message-sent")) ticketData.data.push({id:"opendiscord:message-sent",value:true})
if (!ticketData.data.find((d) => d.id == "opendiscord:admin-message-sent")) ticketData.data.push({id:"opendiscord:admin-message-sent",value:true})
ticketDatabase.set("opendiscord:ticket",ticket.key,ticketData)
ticketDatabase.set("opendiscord:ticket",ticket.key,ticketData)
}
}
}),
//MIGRATE TO v4.1.1
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.1.1"),async () => {},async () => {}),
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.1.1"),{}),
//MIGRATE TO v4.1.2
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.1.2"),async () => {},async () => {}),
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.1.2"),{}),
//MIGRATE TO v4.1.3
new utilities.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.1.3"),async () => {},async () => {}),
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.1.3"),{}),
//MIGRATE TO v4.2.0
new api.ODVersionMigration(api.ODVersion.fromString("opendiscord:version","v4.2.0"),{
beforeStartupMigrate:async () => {
const isDevconfig = (process.argv.includes("--dev-config") || process.argv.includes("-dc"))
//transfer config files to .jsonc
const configDir = path.join(process.cwd(),(isDevconfig) ? "./devconfig/" : "./config/")
for (const file of fs.readdirSync(configDir).filter((f) => f.endsWith(".json"))){
try{
fs.copyFileSync(path.join(configDir,file),path.join(configDir,file.replace(".json",".jsonc")))
fs.rmSync(path.join(configDir,file))
}catch(err){
process.emit("uncaughtException",err)
}
}
},
afterStartupMigrate:async () => {
//migrate config
const generalConfig = opendiscord.configs.get("opendiscord:general")
const questionConfig = opendiscord.configs.get("opendiscord:questions")
const optionConfig = opendiscord.configs.get("opendiscord:options")
const panelConfig = opendiscord.configs.get("opendiscord:panels")
const transcriptConfig = opendiscord.configs.get("opendiscord:transcripts")
if (!generalConfig.data.ticketSystem){
//only migrate config when it hasn't been done manually by the user.
if (!generalConfig.data["_INFO"]) throw new api.ODSystemError("Couldn't find general.jsonc '_INFO' category.")
delete generalConfig.data["_INFO"]
generalConfig.data._CONFIG_VERSION = "open-ticket-v4.2.0"
if (!generalConfig.data["system"]) throw new api.ODSystemError("Couldn't find general.jsonc 'system' category.")
generalConfig.data.ticketSystem = generalConfig.data["system"]
generalConfig.data.ticketSystem.closeEmoji = "🔒"
generalConfig.data.ticketSystem.askPriorityOnTicketCreation = true
generalConfig.data.ticketSystem.enableCreateTicketForOtherUser = true
delete generalConfig.data["system"]
generalConfig.data.logs = generalConfig.data.ticketSystem["logs"]
delete generalConfig.data.ticketSystem["logs"]
generalConfig.data.logs.logMessages = generalConfig.data.ticketSystem["messages"]
delete generalConfig.data.ticketSystem["messages"]
generalConfig.data.permissions = generalConfig.data.ticketSystem["permissions"]
delete generalConfig.data.ticketSystem["permissions"]
generalConfig.data.permissions.transcripts = "admin"
//closed category
const closedCategory = {enabled:false,categoryId:"DISCORD_CATEGORY_ID"}
for (const option of optionConfig.data){
if (option.type != "ticket") continue
if (option.channel["closedCategory"] && /^\d+$/.test(option.channel["closedCategory"])){
closedCategory.enabled = true
closedCategory.categoryId = option.channel["closedCategory"]
}
}
generalConfig.data.ticketSystem.closedCategory = closedCategory
//backup category
const backupCategory = {enabled:false,categoryId:"DISCORD_CATEGORY_ID"}
for (const option of optionConfig.data){
if (option.type != "ticket") continue
if (option.channel["backupCategory"] && /^\d+$/.test(option.channel["backupCategory"])){
backupCategory.enabled = true
backupCategory.categoryId = option.channel["backupCategory"]
}
}
generalConfig.data.ticketSystem.backupCategory = backupCategory
//claimed categories
const claimedCategories: {user:string,category:string}[] = []
for (const option of optionConfig.data){
if (option.type != "ticket" || !Array.isArray(option.channel["claimedCategory"])) continue
for (const {user,category} of option.channel["claimedCategory"]){
if (typeof user == "string" && typeof category == "string" && /^\d+$/.test(user) && /^\d+$/.test(category) && !claimedCategories.find((c) => c.user == user)){
claimedCategories.push({user,category})
}
}
}
generalConfig.data.ticketSystem.claimedCategories = claimedCategories
//delete properties from options.jsonc
for (const option of optionConfig.data){
if (option.type != "ticket") continue
delete option.channel["closedCategory"]
delete option.channel["backupCategory"]
delete option.channel["claimedCategory"]
}
//update panels config:
for (const panel of panelConfig.data){
panel.settings.maximumButtonsPerRow = 5
}
//update questions config:
for (const question of questionConfig.data){
if (question.type !== "paragraph" && question.type !== "short") continue
question.description = ""
}
//add new sub-panel option example (for users to try)
optionConfig.data.push({
id:"example-sub-panel",
name:"Example Sub-Panel",
description:"This is an example of how to implement a sub-panel in Open Ticket.",
type:"sub-panel",
button:{
color:"gray",
label:"Sub-Panel Example",
emoji:"📋"
},
subPanelId:panelConfig.data[0]?.id ?? "example-panel"
})
//add new question examples (for users to try)
questionConfig.data.push(
{
id:"example-dropdown-question",
name:"Example Dropdown Question",
description:"This is a dropdown question.",
type:"dropdown",
required:false,
placeholder:"Choose your answer...",
choices:[
{title:"Choice A",description:"Apple",emoji:"🍎"},
{title:"Choice B",description:"Banana",emoji:"🍌"},
{title:"Choice C",description:"Orange",emoji:"🍊"},
{title:"Choice D",description:"Kiwi",emoji:"🥝"}
]
},
{
id:"example-radio-question",
name:"Example Radio Question",
description:"This is a radio select question.",
type:"radio-select",
required:true,
choices:[
{title:"Choice A",description:"Up",selectedByDefault:false},
{title:"Choice B",description:"Down",selectedByDefault:false},
{title:"Choice C",description:"Left",selectedByDefault:false},
{title:"Choice D",description:"Right",selectedByDefault:false}
]
},
{
id:"example-checkbox-question",
name:"Example Checkbox Question",
description:"This is a checkbox select question.",
type:"checkbox-select",
required:true,
limits:{
enabled:false,
min:0,
max:10
},
choices:[
{title:"Choice A",description:"Happiness",selectedByDefault:false},
{title:"Choice B",description:"Anger",selectedByDefault:false},
{title:"Choice C",description:"Sadness",selectedByDefault:false},
{title:"Choice D",description:"Fear",selectedByDefault:false}
]
},
{
id:"example-text-display-question",
type:"text-display",
textContents:"This is a text display. It isn't a question, but allows you to display a text, explaination or details."
}
)
await generalConfig.save()
await questionConfig.save()
await optionConfig.save()
await panelConfig.save()
await transcriptConfig.save()
}
//migrate database
const optionDatabase = opendiscord.databases.get("opendiscord:options")
const ticketDatabase = opendiscord.databases.get("opendiscord:tickets")
for (const option of (await optionDatabase.getCategory("opendiscord:used-option") ?? [])){
const optionData = option.value
optionData.data = optionData.data.filter((data) => (
data.id !== "opendiscord:channel-category-closed" &&
data.id !== "pendiscord:channel-category-backup" &&
data.id !== "opendiscord:channel-categories-claimed"
))
optionDatabase.set("opendiscord:used-option",option.key,optionData)
}
for (const ticket of (await ticketDatabase.getCategory("opendiscord:ticket") ?? [])){
const ticketData = ticket.value
if (!ticketData.data.find((d) => d.id == "opendiscord:channel-renamed")) ticketData.data.push({id:"opendiscord:channel-renamed",value:null})
ticketDatabase.set("opendiscord:ticket",ticket.key,ticketData)
}
}
}),
]
-260
View File
@@ -1,260 +0,0 @@
import {opendiscord, api, utilities} from "../../index"
import fs from "fs"
export const loadAllPlugins = async () => {
//start launching plugins
opendiscord.log("Loading plugins...","system")
let initPluginError: boolean = false
if (!fs.existsSync("./plugins")){
opendiscord.log("Couldn't find ./plugins directory, canceling all plugin execution!","error")
return
}
const plugins = fs.readdirSync("./plugins")
const pluginVersionRegex = /^(OT|OM)v(\d+)\.(\d+|x)\.(\d+|x)$/
//check & validate
plugins.forEach((p) => {
//prechecks
if (p === ".DS_Store") return //ignore MacOS DS_Store file
if (!fs.statSync("./plugins/"+p).isDirectory()) return opendiscord.log("Plugin is not a directory, canceling plugin execution...","plugin",[
{key:"plugin",value:"./plugins/"+p}
])
if (!fs.existsSync("./plugins/"+p+"/plugin.json")){
initPluginError = true
opendiscord.log("Plugin doesn't have a plugin.json, canceling plugin execution...","plugin",[
{key:"plugin",value:"./plugins/"+p}
])
return
}
//plugin loading
try {
const rawplugindata: api.ODPluginData = JSON.parse(fs.readFileSync("./plugins/"+p+"/plugin.json").toString())
if (typeof rawplugindata != "object") throw new api.ODPluginError("Failed to load plugin.json")
if (typeof rawplugindata.id != "string") throw new api.ODPluginError("Failed to load plugin.json/id")
if (typeof rawplugindata.name != "string") throw new api.ODPluginError("Failed to load plugin.json/name")
if (typeof rawplugindata.version != "string") throw new api.ODPluginError("Failed to load plugin.json/version")
if (typeof rawplugindata.startFile != "string") throw new api.ODPluginError("Failed to load plugin.json/startFile")
//only check "supportedVersions" if it exists (should be array)
if (rawplugindata.supportedVersions){
if (!Array.isArray(rawplugindata.supportedVersions)) throw new api.ODPluginError("Failed to load plugin.json/supportedVersions (must be array)")
for (const version of rawplugindata.supportedVersions){
if (typeof version !== "string"){
throw new api.ODPluginError("Failed to load plugin.json/supportedVersions (all items must be strings)")
}
//only OT (Open Ticket) & OM (Open Moderation) are supported at the moment
if (!pluginVersionRegex.test(version)){
throw new api.ODPluginError(`Failed to load plugin.json/supportedVersions (invalid format: "${version}", expected format like "OTv4.0.x" or "OMv1.0.0")`)
}
}
}
if (typeof rawplugindata.enabled != "boolean") throw new api.ODPluginError("Failed to load plugin.json/enabled")
if (typeof rawplugindata.priority != "number") throw new api.ODPluginError("Failed to load plugin.json/priority")
if (!Array.isArray(rawplugindata.events)) throw new api.ODPluginError("Failed to load plugin.json/events")
if (!Array.isArray(rawplugindata.npmDependencies)) throw new api.ODPluginError("Failed to load plugin.json/npmDependencies")
if (!Array.isArray(rawplugindata.requiredPlugins)) throw new api.ODPluginError("Failed to load plugin.json/requiredPlugins")
if (!Array.isArray(rawplugindata.incompatiblePlugins)) throw new api.ODPluginError("Failed to load plugin.json/incompatiblePlugins")
if (typeof rawplugindata.details != "object") throw new api.ODPluginError("Failed to load plugin.json/details")
if (typeof rawplugindata.details.author != "string") throw new api.ODPluginError("Failed to load plugin.json/details/author")
//only check "contributors" if it exists (should be array)
if (rawplugindata.details.contributors && !Array.isArray(rawplugindata.details.contributors)) throw new api.ODPluginError("Failed to load plugin.json/details/contributors (must be array)")
if (typeof rawplugindata.details.shortDescription != "string") throw new api.ODPluginError("Failed to load plugin.json/details/shortDescription")
if (typeof rawplugindata.details.longDescription != "string") throw new api.ODPluginError("Failed to load plugin.json/details/longDescription")
if (typeof rawplugindata.details.imageUrl != "string") throw new api.ODPluginError("Failed to load plugin.json/details/imageUrl")
if (typeof rawplugindata.details.projectUrl != "string") throw new api.ODPluginError("Failed to load plugin.json/details/projectUrl")
if (!Array.isArray(rawplugindata.details.tags)) throw new api.ODPluginError("Failed to load plugin.json/details/tags")
if (rawplugindata.id != p) throw new api.ODPluginError("Failed to load plugin, directory name is required to match the id")
if (opendiscord.plugins.exists(rawplugindata.id)) throw new api.ODPluginError("Failed to load plugin, this id already exists in another plugin")
//plugin.json is valid => load plugin
const plugin = new api.ODPlugin(p,rawplugindata)
opendiscord.plugins.add(plugin)
}catch(e){
//when any of the above errors happen, crash the bot when soft mode isn't enabled
initPluginError = true
opendiscord.log(e.message+", canceling plugin execution...","plugin",[
{key:"path",value:"./plugins/"+p}
])
opendiscord.log("You can see more about this error in the ./otdebug.txt file!","info")
opendiscord.debugfile.writeText(e.stack)
//try to get some crashed plugin data
try{
const rawplugindata: api.ODPluginData = JSON.parse(fs.readFileSync("./plugins/"+p+"/plugin.json").toString())
opendiscord.plugins.unknownCrashedPlugins.push({
name:rawplugindata.name ?? "./plugins/"+p,
description:(rawplugindata.details && rawplugindata.details.shortDescription) ? rawplugindata.details.shortDescription : "This plugin crashed :(",
})
}catch{}
}
})
//sorted plugins (sorted on priority. All plugins are loaded & enabled)
const sortedPlugins = opendiscord.plugins.getAll().sort((a,b) => {
return (b.priority - a.priority)
})
//check for incompatible & missing plugins/dependencies
const incompatibilities: {from:string,to:string}[] = []
const missingDependencies: {id:string,missing:string}[] = []
const missingPlugins: {id:string,missing:string}[] = []
const versionIncompatibilities: {id:string}[] = []
//go through all plugins for errors
sortedPlugins.filter((plugin) => plugin.enabled).forEach((plugin) => {
const from = plugin.id.value
plugin.dependenciesInstalled().forEach((missing) => missingDependencies.push({id:from,missing}))
plugin.pluginsIncompatible(opendiscord.plugins).forEach((incompatible) => incompatibilities.push({from,to:incompatible}))
plugin.pluginsInstalled(opendiscord.plugins).forEach((missing) => missingPlugins.push({id:from,missing}))
//check if plugins are compatible with version of bot
if (plugin.data.supportedVersions && plugin.data.supportedVersions.length > 0){
const currentVersion = opendiscord.versions.get("opendiscord:version")
let isCompatible = false
for (const versionStr of plugin.data.supportedVersions){
const match = versionStr.match(pluginVersionRegex)
if (!match) continue
const projectPrefix = match[1]
const primary = parseInt(match[2])
const secondary = (match[3] === "x") ? null : parseInt(match[3])
const tertiary = (match[4] === "x") ? null : parseInt(match[4])
if (projectPrefix !== "OT") continue
else if (primary !== currentVersion.primary) continue
else if (typeof secondary === "number" && secondary !== currentVersion.secondary) continue
else if (typeof tertiary === "number" && tertiary !== currentVersion.tertiary) continue
else{
isCompatible = true
break
}
}
if (!isCompatible) versionIncompatibilities.push({id:from})
}
})
//handle all incompatibilities
const alreadyLoggedCompatPlugins: string[] = []
incompatibilities.forEach((match) => {
if (alreadyLoggedCompatPlugins.includes(match.from) || alreadyLoggedCompatPlugins.includes(match.to)) return
else alreadyLoggedCompatPlugins.push(match.from,match.to)
const fromPlugin = opendiscord.plugins.get(match.from)
if (fromPlugin && !fromPlugin.crashed){
fromPlugin.crashed = true
fromPlugin.crashReason = "incompatible.plugin"
}
const toPlugin = opendiscord.plugins.get(match.to)
if (toPlugin && !toPlugin.crashed){
toPlugin.crashed = true
toPlugin.crashReason = "incompatible.plugin"
}
opendiscord.log(`Incompatible plugins => "${match.from}" & "${match.to}", canceling plugin execution...`,"plugin",[
{key:"path1",value:"./plugins/"+match.from},
{key:"path2",value:"./plugins/"+match.to}
])
initPluginError = true
})
//handle all missing dependencies
missingDependencies.forEach((match) => {
const plugin = opendiscord.plugins.get(match.id)
if (plugin && !plugin.crashed){
plugin.crashed = true
plugin.crashReason = "missing.dependency"
}
opendiscord.log(`Missing npm dependency "${match.missing}", canceling plugin execution...`,"plugin",[
{key:"path",value:"./plugins/"+match.id}
])
initPluginError = true
})
//handle all missing plugins
missingPlugins.forEach((match) => {
const plugin = opendiscord.plugins.get(match.id)
if (plugin && !plugin.crashed){
plugin.crashed = true
plugin.crashReason = "missing.plugin"
}
opendiscord.log(`Missing required plugin "${match.missing}", canceling plugin execution...`,"plugin",[
{key:"path",value:"./plugins/"+match.id}
])
initPluginError = true
})
//handle all bot version incompatibilities
versionIncompatibilities.forEach((match) => {
const plugin = opendiscord.plugins.get(match.id)
if (plugin && !plugin.crashed){
plugin.crashed = true
plugin.crashReason = "incompatible.version"
}
const versions = plugin?.data.supportedVersions?.join(", ") ?? "<unknown-version>"
const currentVersion = opendiscord.versions.get("opendiscord:version").toString()
opendiscord.log(`Plugin version incompatibility: plugin requires "${versions}" but current bot version is "${currentVersion}", canceling plugin execution...`,"plugin",[
{key:"path",value:"./plugins/"+match.id}
])
initPluginError = true
})
//exit on error (when soft mode disabled)
if (!opendiscord.defaults.getDefault("softPluginLoading") && initPluginError){
console.log("")
opendiscord.log("Please fix all plugin errors above & try again!","error")
process.exit(1)
}
//preload all events required for every plugin
for (const plugin of sortedPlugins){
if (plugin.enabled) plugin.data.events.forEach((event) => opendiscord.events.add(new api.ODEvent(event)))
}
//execute all working plugins
for (const plugin of sortedPlugins){
const status = await plugin.execute(opendiscord.debug,false)
//exit on error (when soft mode disabled)
if (!status && !opendiscord.defaults.getDefault("softPluginLoading")){
console.log("")
opendiscord.log("Please fix all plugin errors above & try again!","error")
process.exit(1)
}
}
for (const plugin of sortedPlugins){
const authors = [plugin.details.author,...(plugin.details.contributors ?? [])].join(", ")
if (plugin.enabled){
opendiscord.debug.debug("Plugin \""+plugin.id.value+"\" loaded",[
{key:"status",value:(plugin.crashed ? "crashed" : "success")},
{key:"crashReason",value:(plugin.crashed ? (plugin.crashReason ?? "/") : "/")},
{key:"authors",value:authors},
{key:"version",value:plugin.version.toString()},
{key:"priority",value:plugin.priority.toString()}
])
}else{
opendiscord.debug.debug("Plugin \""+plugin.id.value+"\" disabled",[
{key:"authors",value:authors},
{key:"version",value:plugin.version.toString()},
{key:"priority",value:plugin.priority.toString()}
])
}
}
}