Open Ticket v4 Beta

This commit is contained in:
DJj123dj
2024-08-21 13:24:56 +02:00
parent 9326d0fae8
commit 0c2aca7039
154 changed files with 33881 additions and 0 deletions
+60
View File
@@ -0,0 +1,60 @@
//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/startscreen"
//OPENTICKET DEFAULT MODULES
export * from "./defaults/base"
export * from "./defaults/event"
export * from "./defaults/config"
export * from "./defaults/database"
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/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"
+154
View File
@@ -0,0 +1,154 @@
///////////////////////////////////////
//DEFAULT ACTION MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODAction, ODActionManager } from "../modules/action"
import { ODWorkerManager_Default } from "./worker"
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, OTRoleUpdateMode, OTRoleUpdateResult } from "../openticket/role"
/**## ODActionManagerIds_Default `type`
* This type is an array of ids available in the `ODActionManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODActionManagerIds_Default {
"openticket:create-ticket-permissions":{
source:"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"|null,cooldownUntil?:Date},
workers:"openticket:check-blacklist"|"openticket:check-cooldown"|"openticket:check-global-limits"|"openticket:check-option-limits"|"openticket:valid"
},
"openticket:create-transcript":{
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},
result:{compiler:ODTranscriptCompiler<any>, success:boolean, result:ODTranscriptCompilerCompileResult<any>, errorReason:string|null, pendingMessage:ODMessageBuildSentResult<true>|null, participants:{user:discord.User,role:"creator"|"participant"|"admin"}[]},
workers:"openticket:select-compiler"|"openticket:init-transcript"|"openticket:compile-transcript"|"openticket:ready-transcript"|"openticket:logs"
},
"openticket:create-ticket":{
source:"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:"openticket:create-ticket"|"openticket:send-ticket-message"|"openticket:discord-logs"|"openticket:logs"
},
"openticket:close-ticket":{
source:"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},
result:{},
workers:"openticket:close-ticket"|"openticket:discord-logs"|"openticket:logs"
},
"openticket:delete-ticket":{
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,reason:string|null,sendMessage:boolean,withoutTranscript:boolean},
result:{},
workers:"openticket:delete-ticket"|"openticket:discord-logs"|"openticket:delete-channel"|"openticket:logs"
},
"openticket:reopen-ticket":{
source:"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},
result:{},
workers:"openticket:reopen-ticket"|"openticket:discord-logs"|"openticket:logs"
},
"openticket:claim-ticket":{
source:"slash"|"text"|"ticket-message"|"unclaim-message"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean},
result:{},
workers:"openticket:claim-ticket"|"openticket:discord-logs"|"openticket:logs"
},
"openticket:unclaim-ticket":{
source:"slash"|"text"|"ticket-message"|"claim-message"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean},
result:{},
workers:"openticket:unclaim-ticket"|"openticket:discord-logs"|"openticket:logs"
},
"openticket:pin-ticket":{
source:"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:"openticket:pin-ticket"|"openticket:discord-logs"|"openticket:logs"
},
"openticket:unpin-ticket":{
source:"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:"openticket:unpin-ticket"|"openticket:discord-logs"|"openticket:logs"
},
"openticket:rename-ticket":{
source:"slash"|"text"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean,data:string},
result:{},
workers:"openticket:rename-ticket"|"openticket:discord-logs"|"openticket:logs"
},
"openticket:move-ticket":{
source:"slash"|"text"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,sendMessage:boolean,data:ODTicketOption},
result:{},
workers:"openticket:move-ticket"|"openticket:discord-logs"|"openticket:logs"
},
"openticket:add-ticket-user":{
source:"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:"openticket:add-ticket-user"|"openticket:discord-logs"|"openticket:logs"
},
"openticket:remove-ticket-user":{
source:"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:"openticket:remove-ticket-user"|"openticket:discord-logs"|"openticket:logs"
},
"openticket:reaction-role":{
source:"panel-button"|"other",
params:{guild:discord.Guild,user:discord.User,option:ODRoleOption,overwriteMode:OTRoleUpdateMode|null},
result:{result:OTRoleUpdateResult[],role:ODRole},
workers:"openticket:reaction-role"|"openticket:logs"
},
"openticket:clear-tickets":{
source:"slash"|"text"|"other",
params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:ODTicket[]},
result:{list:string[]},
workers:"openticket:clear-tickets"|"openticket:discord-logs"|"openticket:logs"
}
}
/**## 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 `openticket.actions`!
*/
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>
}
+45
View File
@@ -0,0 +1,45 @@
///////////////////////////////////////
//BASE MODULE
///////////////////////////////////////
import { ODVersion, ODVersionManager, ODValidId } from "../modules/base"
/**## ODVersionManagerIds_Default `type`
* This type is an array of ids available in the `ODVersionManager` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODVersionManagerIds_Default {
"openticket:version":ODVersion,
"openticket:last-version":ODVersion,
"openticket:api":ODVersion,
"openticket:transcripts":ODVersion,
"openticket: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 `openticket.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)
}
}
+532
View File
@@ -0,0 +1,532 @@
///////////////////////////////////////
//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, OTRoleUpdateResult } from "../openticket/role"
/**## 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 `openticket.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 `type`
* This type is an array of ids available in the `ODButtonManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODButtonManagerIds_Default {
"openticket: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:"openticket:verifybar-success"},
"openticket: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:"openticket:verifybar-failure"},
"openticket:error-ticket-deprecated-transcript":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{},workers:"openticket:error-ticket-deprecated-transcript"},
"openticket:help-menu-previous":{source:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"openticket:help-menu-previous"},
"openticket:help-menu-next":{source:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"openticket:help-menu-next"},
"openticket:help-menu-page":{source:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"openticket:help-menu-page"}
"openticket:help-menu-switch":{source:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"openticket:help-menu-switch"},
"openticket:ticket-option":{source:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODTicketOption},workers:"openticket:ticket-option"},
"openticket:website-option":{source:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODWebsiteOption},workers:"openticket:website-option"},
"openticket:role-option":{source:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,option:ODRoleOption},workers:"openticket:role-option"}
"openticket:visit-ticket":{source:"ticket-created"|"dm"|"logs"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:visit-ticket"},
"openticket:close-ticket":{source:"ticket-message"|"reopen-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:close-ticket"},
"openticket: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:"openticket:delete-ticket"},
"openticket:reopen-ticket":{source:"ticket-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:reopen-ticket"},
"openticket:claim-ticket":{source:"ticket-message"|"unclaim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:claim-ticket"},
"openticket:unclaim-ticket":{source:"ticket-message"|"claim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:unclaim-ticket"},
"openticket:pin-ticket":{source:"ticket-message"|"unpin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:pin-ticket"},
"openticket:unpin-ticket":{source:"ticket-message"|"pin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:unpin-ticket"},
"openticket: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}>,result:ODTranscriptCompilerCompileResult<{url:string}>},workers:"openticket:transcript-html-visit"},
"openticket: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>,reason:string|null},workers:"openticket:transcript-error-retry"},
"openticket: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>,reason:string|null},workers:"openticket:transcript-error-continue"},
"openticket:clear-continue":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"openticket: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 `openticket.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 `type`
* This type is an array of ids available in the `ODDropdownManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODDropdownManagerIds_Default {
"openticket:panel-dropdown-tickets":{source:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel,options:ODTicketOption[]},workers:"openticket: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 `openticket.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 `type`
* This type is an array of ids available in the `ODFileManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODFileManagerIds_Default {
"openticket: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>,result:ODTranscriptCompilerCompileResult<any>},workers:"openticket: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 `openticket.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 `type`
* This type is an array of ids available in the `ODEmbedManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODEmbedManagerIds_Default {
"openticket:error":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:string,layout:"simple"|"advanced"},workers:"openticket:error"},
"openticket:error-option-missing":{source:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:ODTextCommandErrorMissingOption},workers:"openticket:error-option-missing"},
"openticket:error-option-invalid":{source:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:ODTextCommandErrorInvalidOption},workers:"openticket:error-option-invalid"},
"openticket:error-unknown-command":{source:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:ODTextCommandErrorUnknownCommand},workers:"openticket:error-unknown-command"},
"openticket:error-no-permissions":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,permissions:ODPermissionEmbedType[]},workers:"openticket:error-no-permissions"},
"openticket: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:"openticket:error-no-permissions-cooldown"},
"openticket:error-no-permissions-blacklisted":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-no-permissions-blacklisted"},
"openticket: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:"openticket:error-no-permissions-limits"},
"openticket:error-responder-timeout":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-responder-timeout"},
"openticket:error-ticket-unknown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-ticket-unknown"},
"openticket:error-ticket-deprecated":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-ticket-deprecated"},
"openticket:error-option-unknown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-option-unknown"},
"openticket:error-panel-unknown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-panel-unknown"},
"openticket:error-not-in-guild":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-not-in-guild"},
"openticket:error-channel-rename":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"ticket-pin"|"ticket-unpin"|"ticket-rename"|"ticket-move"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,originalName:string,newName:string},workers:"openticket:error-channel-rename"},
"openticket:error-ticket-busy":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-ticket-busy"},
"openticket:help-menu":{source:"text"|"slash"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"openticket:help-menu"},
"openticket:stats-global":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:stats-global"},
"openticket:stats-ticket":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,scopeData:ODTicket},workers:"openticket:stats-ticket"},
"openticket:stats-user":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,scopeData:discord.User},workers:"openticket:stats-user"|"openticket:easter-egg"},
"openticket:stats-reset":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,reason:string|null},workers:"openticket:stats-reset"},
"openticket:stats-ticket-unknown":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,id:string},workers:"openticket:stats-ticket-unknown"},
"openticket:panel":{source:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel},workers:"openticket:panel"},
"openticket:ticket-created":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:ticket-created"},
"openticket:ticket-created-dm":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:ticket-created-dm"},
"openticket:ticket-created-logs":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:ticket-created-logs"},
"openticket:ticket-message":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:ticket-message"},
"openticket: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:"openticket:close-message"},
"openticket: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:"openticket:reopen-message"},
"openticket: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:"openticket:delete-message"},
"openticket: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:"openticket:claim-message"},
"openticket: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:"openticket:unclaim-message"},
"openticket: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:"openticket:pin-message"},
"openticket: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:"openticket:unpin-message"},
"openticket:rename-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:string},workers:"openticket:rename-message"},
"openticket:move-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:ODTicketOption},workers:"openticket:move-message"},
"openticket: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:"openticket:add-message"},
"openticket: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:"openticket:remove-message"},
"openticket: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:"openticket:ticket-action-dm"},
"openticket: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:"openticket:ticket-action-logs"},
"openticket:blacklist-view":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:blacklist-view"},
"openticket:blacklist-get":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User},workers:"openticket:blacklist-get"},
"openticket:blacklist-add":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User,reason:string|null},workers:"openticket:blacklist-add"},
"openticket:blacklist-remove":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User,reason:string|null},workers:"openticket:blacklist-remove"}
"openticket: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:"openticket:blacklist-dm"},
"openticket: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:"openticket:blacklist-logs"},
"openticket: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}>,result:ODTranscriptCompilerCompileResult<{contents:string}>},workers:"openticket:transcript-text-ready"},
"openticket: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}>,result:ODTranscriptCompilerCompileResult<{url:string}>},workers:"openticket:transcript-html-ready"},
"openticket:transcript-html-progress":{source:"channel"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string}>,remaining:number},workers:"openticket:transcript-html-progress"},
"openticket: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>,reason:string|null},workers:"openticket:transcript-error"},
"openticket:reaction-role":{source:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:OTRoleUpdateResult[]},workers:"openticket:reaction-role"},
"openticket:clear-verify-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"openticket:clear-verify-message"},
"openticket:clear-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"openticket:clear-message"},
"openticket:clear-logs":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"openticket:clear-logs"},
"openticket:autoclose-message":{source:"timeout"|"leave"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:autoclose-message"},
"openticket:autodelete-message":{source:"timeout"|"leave"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:autodelete-message"},
"openticket:autoclose-enable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,time:number,reason:string|null},workers:"openticket:autoclose-enable"},
"openticket:autodelete-enable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,time:number,reason:string|null},workers:"openticket:autodelete-enable"},
"openticket:autoclose-disable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"openticket:autoclose-disable"},
"openticket:autodelete-disable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"openticket:autodelete-disable"},
}
/**## 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 `openticket.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 `type`
* This type is an array of ids available in the `ODMessageManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODMessageManagerIds_Default {
"openticket:verifybar-ticket-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"openticket:verifybar-ticket-message"},
"openticket:verifybar-close-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"openticket:verifybar-close-message"},
"openticket:verifybar-reopen-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"openticket:verifybar-reopen-message"},
"openticket:verifybar-claim-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"openticket:verifybar-claim-message"},
"openticket:verifybar-unclaim-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"openticket:verifybar-unclaim-message"},
"openticket:verifybar-pin-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"openticket:verifybar-pin-message"},
"openticket:verifybar-unpin-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"openticket:verifybar-unpin-message"}
"openticket:verifybar-autoclose-message":{source:"verifybar",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>},workers:"openticket:verifybar-autoclose-message"}
"openticket:error":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:string,layout:"simple"|"advanced"},workers:"openticket:error"},
"openticket:error-option-missing":{source:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:ODTextCommandErrorMissingOption},workers:"openticket:error-option-missing"},
"openticket:error-option-invalid":{source:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:ODTextCommandErrorInvalidOption},workers:"openticket:error-option-invalid"},
"openticket:error-unknown-command":{source:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,error:ODTextCommandErrorUnknownCommand},workers:"openticket:error-unknown-command"},
"openticket:error-no-permissions":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,permissions:ODPermissionEmbedType[]},workers:"openticket:error-no-permissions"},
"openticket: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:"openticket:error-no-permissions-cooldown"},
"openticket:error-no-permissions-blacklisted":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-no-permissions-blacklisted"},
"openticket: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:"openticket:error-no-permissions-limits"},
"openticket:error-responder-timeout":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-responder-timeout"},
"openticket:error-ticket-unknown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-ticket-unknown"},
"openticket:error-ticket-deprecated":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-ticket-deprecated"},
"openticket:error-option-unknown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-option-unknown"},
"openticket:error-panel-unknown":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-panel-unknown"},
"openticket:error-not-in-guild":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-not-in-guild"},
"openticket:error-channel-rename":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"ticket-pin"|"ticket-unpin"|"ticket-rename"|"ticket-move"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,originalName:string,newName:string},workers:"openticket:error-channel-rename"},
"openticket:error-ticket-busy":{source:"slash"|"text"|"button"|"dropdown"|"modal"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:error-ticket-busy"},
"openticket:help-menu":{source:"slash"|"text"|"button"|"other",params:{mode:"slash"|"text",page:number},workers:"openticket:help-menu"},
"openticket:stats-global":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:stats-global"},
"openticket:stats-ticket":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,scopeData:ODTicket},workers:"openticket:stats-ticket"},
"openticket:stats-user":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,scopeData:discord.User},workers:"openticket:stats-user"|"openticket:easter-egg"},
"openticket:stats-reset":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,reason:string|null},workers:"openticket:stats-reset"},
"openticket:stats-ticket-unknown":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,id:string},workers:"openticket:stats-ticket-unknown"},
"openticket:panel":{source:"slash"|"text"|"auto-update"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel},workers:"openticket:panel-layout"|"openticket:panel-components"},
"openticket:panel-ready":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,panel:ODPanel},workers:"openticket:panel-ready"},
"openticket:ticket-created":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:ticket-created"},
"openticket:ticket-created-dm":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:ticket-created-dm"},
"openticket:ticket-created-logs":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:ticket-created-logs"},
"openticket:ticket-message":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:ticket-message-layout"|"openticket:ticket-message-components"|"openticket:ticket-message-disable-components"},
"openticket: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:"openticket:close-message"},
"openticket: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:"openticket:reopen-message"},
"openticket: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:"openticket:delete-message"},
"openticket: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:"openticket:claim-message"},
"openticket: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:"openticket:unclaim-message"},
"openticket: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:"openticket:pin-message"},
"openticket: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:"openticket:unpin-message"},
"openticket:rename-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:string},workers:"openticket:rename-message"},
"openticket:move-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null,data:ODTicketOption},workers:"openticket:move-message"},
"openticket: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:"openticket:add-message"},
"openticket: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:"openticket:remove-message"},
"openticket: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:"openticket:ticket-action-dm"},
"openticket: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:"openticket:ticket-action-logs"},
"openticket:blacklist-view":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User},workers:"openticket:blacklist-view"},
"openticket:blacklist-get":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User},workers:"openticket:blacklist-get"},
"openticket:blacklist-add":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User,reason:string|null},workers:"openticket:blacklist-add"},
"openticket:blacklist-remove":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,data:discord.User,reason:string|null},workers:"openticket:blacklist-remove"},
"openticket: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:"openticket:blacklist-dm"},
"openticket: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:"openticket:blacklist-logs"},
"openticket: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}>,result:ODTranscriptCompilerCompileResult<{contents:string}>},workers:"openticket:transcript-text-ready"},
"openticket: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}>,result:ODTranscriptCompilerCompileResult<{url:string}>},workers:"openticket:transcript-html-ready"},
"openticket:transcript-html-progress":{source:"channel"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,compiler:ODTranscriptCompiler<{url:string}>,remaining:number},workers:"openticket:transcript-html-progress"},
"openticket: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>,reason:string|null},workers:"openticket:transcript-error"},
"openticket:reaction-role":{source:"panel-button"|"other",params:{guild:discord.Guild,user:discord.User,role:ODRole,result:OTRoleUpdateResult[]},workers:"openticket:reaction-role"},
"openticket:clear-verify-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"openticket:clear-verify-message"},
"openticket:clear-message":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"openticket:clear-message"},
"openticket:clear-logs":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,filter:ODTicketClearFilter,list:string[]},workers:"openticket:clear-logs"},
"openticket:autoclose-message":{source:"timeout"|"leave"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:autoclose-message"},
"openticket:autodelete-message":{source:"timeout"|"leave"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:autodelete-message"},
"openticket:autoclose-enable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,time:number,reason:string|null},workers:"openticket:autoclose-enable"},
"openticket:autodelete-enable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,time:number,reason:string|null},workers:"openticket:autodelete-enable"},
"openticket:autoclose-disable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"openticket:autoclose-disable"},
"openticket:autodelete-disable":{source:"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.GuildTextBasedChannel,user:discord.User,ticket:ODTicket,reason:string|null},workers:"openticket:autodelete-disable"},
}
/**## 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 `openticket.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 `type`
* This type is an array of ids available in the `ODModalManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODModalManagerIds_Default {
"openticket:ticket-questions":{source:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,option:ODTicketOption},workers:"openticket:ticket-questions"}
"openticket:close-ticket-reason":{source:"ticket-message"|"reopen-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:close-ticket-reason"}
"openticket:reopen-ticket-reason":{source:"ticket-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:reopen-ticket-reason"}
"openticket: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:"openticket:delete-ticket-reason"}
"openticket:claim-ticket-reason":{source:"ticket-message"|"unclaim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:claim-ticket-reason"}
"openticket:unclaim-ticket-reason":{source:"ticket-message"|"claim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:unclaim-ticket-reason"}
"openticket:pin-ticket-reason":{source:"ticket-message"|"unpin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket:pin-ticket-reason"}
"openticket:unpin-ticket-reason":{source:"ticket-message"|"pin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket},workers:"openticket: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 `openticket.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>
}
+378
View File
@@ -0,0 +1,378 @@
///////////////////////////////////////
//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 `type`
* This type is an array of ids available in the `ODCheckerManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODCheckerManagerIds_Default {
"openticket:general":ODChecker,
"openticket:options":ODChecker,
"openticket:messages":ODChecker,
"openticket: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 `openticket.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 `openticket.checkers.renderer`!
*/
export class ODCheckerRenderer_Default extends ODCheckerRenderer {
extraHeaderText: string[] = []
extraFooterText: string[] = []
extraTopText: string[] = []
extraBottomText: string[] = []
horizontalFiller: string = "="
verticalFiller: string = "|"
descriptionSeparator: 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","openticket:header-openticket") ?? "OPEN TICKET",
headerConfigchecker:tm.get("other","openticket:header-configchecker") ?? "CONFIG CHECKER",
headerDescription:tm.get("other","openticket:header-description") ?? "check for errors in you config files!",
footerError:tm.get("other","openticket:footer-error") ?? "the bot won't start until all {0}'s are fixed!",
footerWarning:tm.get("other","openticket:footer-warning") ?? "it's recommended to fix all {0}'s before starting!",
footerSupport:tm.get("other","openticket:footer-support") ?? "SUPPORT: {0} - DOCS: {1}",
error:tm.get("other","openticket:type-error") ?? "[ERROR]",
warning:tm.get("other","openticket:type-warning") ?? "[WARNING]",
info:tm.get("other","openticket:type-info") ?? "[INFO]",
compactInfo:tm.get("other","openticket:compact-information") ?? "use {0} for more information!",
dataPath:tm.get("other","openticket:data-path") ?? "path",
dataDocs:tm.get("other","openticket:data-docs") ?? "docs",
dataMessage:tm.get("other","openticket: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+" => "+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(text:string[]): number {
let finalLength = 0
text.forEach((t) => {
const l = ansis.strip(t).length
if (l > finalLength) finalLength = l
})
return finalLength
}
/**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 `type`
* This type is an array of ids available in the `ODCheckerTranslationRegister_Default` class.
* It's used to generate typescript declarations for this class.
*/
export type ODCheckerTranslationRegisterOtherIds_Default = (
"openticket:header-openticket"|
"openticket:header-configchecker"|
"openticket:header-description"|
"openticket:type-error"|
"openticket:type-warning"|
"openticket:type-info"|
"openticket:data-path"|
"openticket:data-docs"|
"openticket:data-message"|
"openticket:compact-information"|
"openticket:footer-error"|
"openticket:footer-warning"|
"openticket:footer-support"
)
/**## ODCheckerTranslationRegisterMessageIds_Default `type`
* This type is an array of ids available in the `ODCheckerTranslationRegister_Default` class.
* It's used to generate typescript declarations for this class.
*/
export type ODCheckerTranslationRegisterMessageIds_Default = (
"openticket:invalid-type"|
"openticket:property-missing"|
"openticket:property-optional"|
"openticket:object-disabled"|
"openticket:null-invalid"|
"openticket:switch-invalid-type"|
"openticket:object-switch-invalid-type"|
"openticket:string-too-short"|
"openticket:string-too-long"|
"openticket:string-length-invalid"|
"openticket:string-starts-with"|
"openticket:string-ends-with"|
"openticket:string-contains"|
"openticket:string-choices"|
"openticket:string-regex"|
"openticket:number-too-short"|
"openticket:number-too-long"|
"openticket:number-length-invalid"|
"openticket:number-too-small"|
"openticket:number-too-large"|
"openticket:number-not-equal"|
"openticket:number-step"|
"openticket:number-step-offset"|
"openticket:number-starts-with"|
"openticket:number-ends-with"|
"openticket:number-contains"|
"openticket:number-choices"|
"openticket:number-float"|
"openticket:number-negative"|
"openticket:number-positive"|
"openticket:number-zero"|
"openticket:boolean-true"|
"openticket:boolean-false"|
"openticket:array-empty-disabled"|
"openticket:array-empty-required"|
"openticket:array-too-short"|
"openticket:array-too-long"|
"openticket:array-length-invalid"|
"openticket:array-invalid-types"|
"openticket:array-double"|
"openticket:discord-invalid-id"|
"openticket:discord-invalid-id-options"|
"openticket:discord-invalid-token"|
"openticket:color-invalid"|
"openticket:emoji-too-short"|
"openticket:emoji-too-long"|
"openticket:emoji-custom"|
"openticket:emoji-invalid"|
"openticket:url-invalid"|
"openticket:url-invalid-http"|
"openticket:url-invalid-protocol"|
"openticket:url-invalid-hostname"|
"openticket:url-invalid-extension"|
"openticket:url-invalid-path"|
"openticket:id-not-unique"|
"openticket:id-non-existent"|
"openticket:invalid-language"|
"openticket:invalid-button"|
"openticket:unused-option"|
"openticket:unused-question"|
"openticket: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 `openticket.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 `type`
* This type is an array of ids available in the `ODCheckerFunctionManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODCheckerFunctionManagerIds_Default {
"openticket:unused-options":ODCheckerFunction,
"openticket: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 `openticket.checkers.functions`!
*/
export class ODCheckerFunctionManager_Default extends ODCheckerFunctionManager {
get<CheckerFunctionId extends keyof ODCheckerManagerIds_Default>(id:CheckerFunctionId): ODCheckerManagerIds_Default[CheckerFunctionId]
get(id:ODValidId): ODCheckerFunction|null
get(id:ODValidId): ODCheckerFunction|null {
return super.get(id)
}
remove<CheckerFunctionId extends keyof ODCheckerManagerIds_Default>(id:CheckerFunctionId): ODCheckerManagerIds_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)
}
}
+147
View File
@@ -0,0 +1,147 @@
///////////////////////////////////////
//DEFAULT CLIENT MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODClientManager, ODSlashCommand, ODTextCommand, ODSlashCommandManager, ODTextCommandManager, ODSlashCommandInteractionCallback, ODTextCommandInteractionCallback } from "../modules/client"
/**## 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 `openticket.client`!
*/
export class ODClientManager_Default extends ODClientManager {
declare slashCommands: ODSlashCommandManager_Default
declare textCommands: ODTextCommandManager_Default
}
/**## ODSlashCommandManagerIds_Default `type`
* This type is an array of ids available in the `ODSlashCommandManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODSlashCommandManagerIds_Default {
"openticket:help":ODSlashCommand,
"openticket:panel":ODSlashCommand,
"openticket:ticket":ODSlashCommand,
"openticket:close":ODSlashCommand,
"openticket:delete":ODSlashCommand,
"openticket:reopen":ODSlashCommand,
"openticket:claim":ODSlashCommand,
"openticket:unclaim":ODSlashCommand,
"openticket:pin":ODSlashCommand,
"openticket:unpin":ODSlashCommand,
"openticket:move":ODSlashCommand,
"openticket:rename":ODSlashCommand,
"openticket:add":ODSlashCommand,
"openticket:remove":ODSlashCommand,
"openticket:blacklist":ODSlashCommand,
"openticket:stats":ODSlashCommand,
"openticket:clear":ODSlashCommand,
"openticket:autoclose":ODSlashCommand,
"openticket:autodelete":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 `openticket.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 `type`
* This type is an array of ids available in the `ODTextCommandManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODTextCommandManagerIds_Default {
"openticket:help":ODTextCommand,
"openticket:panel":ODTextCommand,
"openticket:close":ODTextCommand,
"openticket:delete":ODTextCommand,
"openticket:reopen":ODTextCommand,
"openticket:claim":ODTextCommand,
"openticket:unclaim":ODTextCommand,
"openticket:pin":ODTextCommand,
"openticket:unpin":ODTextCommand,
"openticket:move":ODTextCommand,
"openticket:rename":ODTextCommand,
"openticket:add":ODTextCommand,
"openticket:remove":ODTextCommand,
"openticket:blacklist-view":ODTextCommand,
"openticket:blacklist-add":ODTextCommand,
"openticket:blacklist-remove":ODTextCommand,
"openticket:blacklist-get":ODTextCommand,
"openticket:stats-global":ODTextCommand,
"openticket:stats-reset":ODTextCommand,
"openticket:stats-ticket":ODTextCommand,
"openticket:stats-user":ODTextCommand,
"openticket:clear":ODTextCommand,
"openticket:autoclose-disable":ODTextCommand,
"openticket:autoclose-enable":ODTextCommand,
"openticket:autodelete-disable":ODTextCommand,
"openticket:autodelete-enable":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 `openticket.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(prefix:string, id:keyof ODTextCommandManagerIds_Default, callback:ODTextCommandInteractionCallback): void
onInteraction(commandPrefix:string, commandName:string|RegExp, callback:ODTextCommandInteractionCallback): void
onInteraction(commandPrefix:string, commandName:string|RegExp, callback:ODTextCommandInteractionCallback): void {
return super.onInteraction(commandPrefix,commandName,callback)
}
}
+56
View File
@@ -0,0 +1,56 @@
///////////////////////////////////////
//DEFAULT CODE MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODCode, ODCodeManager } from "../modules/code"
/**## ODCodeManagerIds_Default `type`
* This type is an array of ids available in the `ODCodeManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODCodeManagerIds_Default {
"openticket:command-error-handling":ODCode,
"openticket:start-listening-interactions":ODCode,
"openticket:panel-database-cleaner":ODCode,
"openticket:suffix-database-cleaner":ODCode,
"openticket:option-database-cleaner":ODCode,
"openticket:user-database-cleaner":ODCode,
"openticket:ticket-database-cleaner":ODCode,
"openticket:panel-auto-update":ODCode,
"openticket:ticket-saver":ODCode,
"openticket:blacklist-saver":ODCode,
"openticket:auto-role-on-join":ODCode,
"openticket:autoclose-timeout":ODCode,
"openticket:autoclose-leave":ODCode,
"openticket:autodelete-timeout":ODCode,
"openticket:autodelete-leave":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 `openticket.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)
}
}
+470
View File
@@ -0,0 +1,470 @@
///////////////////////////////////////
//DEFAULT CONFIG MODULE
///////////////////////////////////////
import { ODValidButtonColor, ODValidId } from "../modules/base"
import * as discord from "discord.js"
import { ODConfigManager, ODConfig, ODJsonConfig } from "../modules/config"
import { ODClientActivityStatus, ODClientActivityType } from "../modules/client"
import { OTRoleUpdateMode } from "../openticket/role"
/**## ODConfigManagerIds_Default `type`
* This type is an array of ids available in the `ODConfigManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODConfigManagerIds_Default {
"openticket:general":ODJsonConfig_DefaultGeneral,
"openticket:options":ODJsonConfig_DefaultOptions,
"openticket:panels":ODJsonConfig_DefaultPanels,
"openticket:questions":ODJsonConfig_DefaultQuestions,
"openticket:transcripts":ODJsonConfig_DefaultTranscripts
}
/**## 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 `openticket.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)
}
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!
*/
export interface ODJsonConfig_DefaultStatusType {
enabled:boolean,
type:Exclude<ODClientActivityType,false>,
text:string,
status:ODClientActivityStatus
}
/**## ODJsonConfig_DefaultMessageSettingsType `interface`
* This interface is an object which has all properties for the system/messages/... object in the `general.json` config!
*/
export interface ODJsonConfig_DefaultMessageSettingsType {
dm:boolean,
logs:boolean
}
/**## ODJsonConfig_DefaultCmdPermissionSettingsType `type`
* This type is a collection of command permission settings for the system/permissions/... object in the `general.json` config!
*/
export type ODJsonConfig_DefaultCmdPermissionSettingsType = "admin"|"everyone"|"none"|string
/**## 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: {
_INFO:{
support:string,
discord:string,
version:string
},
token:string,
tokenFromENV:boolean,
mainColor:discord.ColorResolvable,
language:string,
prefix:string,
serverId:string,
globalAdmins:string[],
slashCommands:boolean,
textCommands:boolean,
status:ODJsonConfig_DefaultStatusType,
system:{
removeParticipantsOnClose:boolean,
replyOnTicketCreation:boolean,
replyOnReactionRole:boolean,
useTranslatedConfigChecker:boolean,
preferSlashOverText:boolean,
sendErrorOnUnknownCommand:boolean,
questionFieldsInCodeBlock:boolean,
disableVerifyBars:boolean,
useRedErrorEmbeds:boolean,
emojiStyle:"before"|"after"|"double"|"disabled",
enableTicketClaimButtons:boolean,
enableTicketCloseButtons:boolean,
enableTicketPinButtons:boolean,
enableTicketDeleteButtons:boolean,
enableTicketActionWithReason:boolean,
enableDeleteWithoutTranscript:boolean,
logs:{
enabled:boolean,
channel:string
},
limits:{
enabled:boolean,
globalMaximum:number,
userMaximum:number
},
permissions:{
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
},
messages:{
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,
roleAdding:ODJsonConfig_DefaultMessageSettingsType,
roleRemoving:ODJsonConfig_DefaultMessageSettingsType
}
}
}
}
/**## ODJsonConfig_DefaultOptionType `interface`
* This interface is an object which has all basic properties for options in the `options.json` config!
*/
export interface ODJsonConfig_DefaultOptionType {
id:string,
name:string,
description:string,
type:"ticket"|"website"|"role",
button:{
emoji:string,
label:string
}
}
/**## ODJsonConfig_DefaultOptionButtonSettingsType `interface`
* This interface is an object which has all button settings for ticket options in the `options.json` config!
*/
export interface ODJsonConfig_DefaultOptionButtonSettingsType {
emoji:string,
label:string,
color:ODValidButtonColor
}
/**## ODJsonConfig_DefaultOptionEmbedSettingsType `interface`
* This interface is an object which has all message embed settings for ticket options in the `options.json` config!
*/
export interface ODJsonConfig_DefaultOptionEmbedSettingsType {
enabled:boolean,
title:string,
description:string,
customColor:string,
image:string,
thumbnail:string,
fields:{name:string, value:string, inline:boolean}[],
timestamp:boolean
}
/**## ODJsonConfig_DefaultOptionPingSettingsType `interface`
* This interface is an object which has all message ping settings for ticket options in the `options.json` config!
*/
export interface ODJsonConfig_DefaultOptionPingSettingsType {
"@here":boolean,
"@everyone":boolean,
custom:string[]
}
/**## ODJsonConfig_DefaultOptionTicketType `interface`
* This interface is an object which has all ticket properties for options in the `options.json` config!
*/
export interface ODJsonConfig_DefaultOptionTicketType extends ODJsonConfig_DefaultOptionType {
type:"ticket",
button:ODJsonConfig_DefaultOptionButtonSettingsType,
ticketAdmins:string[],
readonlyAdmins:string[],
allowCreationByBlacklistedUsers:boolean,
questions:string[],
channel:{
prefix:string,
suffix:"user-name"|"user-id"|"random-number"|"random-hex"|"counter-dynamic"|"counter-fixed",
category:string,
closedCategory:string,
backupCategory:string,
claimedCategory:{user:string, category:string}[],
description:string
},
dmMessage:{
enabled:boolean,
text:string,
embed:ODJsonConfig_DefaultOptionEmbedSettingsType
},
ticketMessage:{
enabled:boolean,
text:string,
embed:ODJsonConfig_DefaultOptionEmbedSettingsType,
ping:ODJsonConfig_DefaultOptionPingSettingsType
},
autoclose:{
enableInactiveHours:boolean,
inactiveHours:number,
enableUserLeave:boolean,
disableOnClaim:boolean
},
autodelete:{
enableInactiveDays:boolean,
inactiveDays:number,
enableUserLeave:boolean,
disableOnClaim:boolean
},
cooldown:{
enabled:boolean,
cooldownMinutes:number
},
limits:{
enabled:boolean,
globalMaximum:number,
userMaximum:number
}
}
/**## ODJsonConfig_DefaultOptionWebsiteType `interface`
* This interface is an object which has all website properties for options in the `options.json` config!
*/
export interface ODJsonConfig_DefaultOptionWebsiteType extends ODJsonConfig_DefaultOptionType {
type:"website",
url:string
}
/**## ODJsonConfig_DefaultOptionRoleType `interface`
* This interface is an object which has all reaction role properties for options in the `options.json` config!
*/
export interface ODJsonConfig_DefaultOptionRoleType extends ODJsonConfig_DefaultOptionType {
type:"role",
button:ODJsonConfig_DefaultOptionButtonSettingsType,
roles:string[],
mode:OTRoleUpdateMode,
removeRolesOnAdd:string[],
addOnMemberJoin:boolean
}
/**## 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_DefaultOptionTicketType|
ODJsonConfig_DefaultOptionWebsiteType|
ODJsonConfig_DefaultOptionRoleType
)[]
}
/**## ODJsonConfig_DefaultPanelEmbedSettingsType `interface`
* This interface is an object which has all message embed settings for panels in the `panels.json` config!
*/
export interface ODJsonConfig_DefaultPanelEmbedSettingsType {
enabled:boolean,
title:string,
description:string,
customColor:string,
url:string,
image:string,
thumbnail:string,
footer:string,
fields:{name:string,value:string,inline:boolean}[],
timestamp:boolean
}
/**## ODJsonConfig_DefaultPanelType `interface`
* This interface is an object which has all properties for panels in the `panels.json` config!
*/
export interface ODJsonConfig_DefaultPanelType {
id:string,
name:string,
dropdown:boolean,
options:string[],
text:string,
embed:ODJsonConfig_DefaultPanelEmbedSettingsType,
settings:{
dropdownPlaceholder:string,
enableMaxTicketsWarningInText:boolean,
enableMaxTicketsWarningInEmbed:boolean,
describeOptionsLayout:"simple"|"normal"|"detailed",
describeOptionsCustomTitle:string,
describeOptionsInText:boolean,
describeOptionsInEmbedFields:boolean,
describeOptionsInEmbedDescription:boolean
}
}
/**## 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_DefaultPanelType[]
}
/**## ODJsonConfig_DefaultShortQuestionType `interface`
* This interface is an object which has all properties for short questions in the `questions.json` config!
*/
export interface ODJsonConfig_DefaultShortQuestionType {
id:string,
name:string,
type:"short",
required:boolean,
placeholder:string,
length:{
enabled:boolean,
min:number,
max:number
}
}
/**## ODJsonConfig_DefaultParagraphQuestionType `interface`
* This interface is an object which has all properties for paragraph questions in the `questions.json` config!
*/
export interface ODJsonConfig_DefaultParagraphQuestionType {
id:string,
name:string,
type:"paragraph",
required:boolean,
placeholder:string,
length:{
enabled:boolean,
min:number,
max:number
}
}
/**## 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_DefaultShortQuestionType|
ODJsonConfig_DefaultParagraphQuestionType
)[]
}
/**## 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!
*/
export class ODJsonConfig_DefaultTranscripts extends ODJsonConfig {
declare data: {
general:{
enabled:boolean,
enableChannel:boolean,
enableCreatorDM:boolean,
enableParticipantDM:boolean,
enableActiveAdminDM:boolean,
enableEveryAdminDM:boolean,
channel:string,
mode:"html"|"text"
},
embedSettings:{
customColor:string,
listAllParticipants:boolean,
includeTicketStats:boolean
},
textTranscriptStyle:{
layout:"simple"|"normal"|"detailed",
includeStats:boolean,
includeIds:boolean,
includeEmbeds:boolean,
includeFiles:boolean,
includeBotMessages:boolean,
fileMode:"custom"|"channel-name"|"channel-id"|"user-name"|"user-id",
customFileName:string
},
htmlTranscriptStyle:{
background:{
enableCustomBackground:boolean,
backgroundColor:string,
backgroundImage:string
},
header:{
enableCustomHeader:boolean,
backgroundColor:string,
decoColor:string,
textColor:string
},
stats:{
enableCustomStats:false,
backgroundColor:string,
keyTextColor:string,
valueTextColor:string,
hideBackgroundColor:string,
hideTextColor:string
},
favicon:{
enableCustomFavicon:boolean,
imageUrl:string
}
}
}
}
+42
View File
@@ -0,0 +1,42 @@
///////////////////////////////////////
//DEFAULT CONSOLE MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODLiveStatusUrlSource, ODLiveStatusManager, ODLiveStatusSource } from "../modules/console"
/**## ODLiveStatusManagerIds_Default `type`
* This type is an array of ids available in the `ODLiveStatusManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODLiveStatusManagerIds_Default {
"openticket: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 `openticket.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
@@ -0,0 +1,42 @@
///////////////////////////////////////
//DEFAULT COOLDOWN MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODCooldown, ODCooldownManager } from "../modules/cooldown"
/**## ODCooldownManagerIds_Default `type`
* This type is an array 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 `openticket.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)
}
}
+256
View File
@@ -0,0 +1,256 @@
///////////////////////////////////////
//DEFAULT DATABASE MODULE
///////////////////////////////////////
import { ODValidId, ODValidJsonType } from "../modules/base"
import { ODDatabaseManager, ODDatabase, ODFormattedJsonDatabase } from "../modules/database"
import { ODTicketJson } from "../openticket/ticket"
import { ODOptionJson } from "../openticket/option"
/**## ODDatabaseManagerIds_Default `type`
* This type is an array of ids available in the `ODDatabaseManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODDatabaseManagerIds_Default {
"openticket:global":ODFormattedJsonDatabase_DefaultGlobal,
"openticket:stats":ODFormattedJsonDatabase,
"openticket:tickets":ODFormattedJsonDatabase_DefaultTickets,
"openticket:users":ODFormattedJsonDatabase_DefaultUsers,
"openticket: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 `openticket.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 type is an array of ids available in the `ODFormattedJsonDatabase_DefaultGlobal` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODFormattedJsonDatabaseIds_DefaultGlobal {
"openticket:panel-update":string,
"openticket:option-suffix-counter":number,
"openticket:option-suffix-history":string[],
"openticket: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]): boolean
set(category:string, key:string, value:ODValidJsonType): boolean
set(category:string, key:string, value:ODValidJsonType): boolean {
return super.set(category,key,value)
}
get<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultGlobal>(category:CategoryId, key:string): ODFormattedJsonDatabaseIds_DefaultGlobal[CategoryId]|undefined
get(category:string, key:string): ODValidJsonType|undefined
get(category:string, key:string): ODValidJsonType|undefined {
return super.get(category,key)
}
delete<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultGlobal>(category:CategoryId, key:string): boolean
delete(category:string, key:string): boolean
delete(category:string, key:string): boolean {
return super.delete(category,key)
}
exists(category:keyof ODFormattedJsonDatabaseIds_DefaultGlobal, key:string): boolean
exists(category:string, key:string): boolean
exists(category:string, key:string): boolean {
return super.exists(category,key)
}
getCategory<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultGlobal>(category:CategoryId): {key:string, value:ODFormattedJsonDatabaseIds_DefaultGlobal[CategoryId]}[]|undefined
getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined
getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined {
return super.getCategory(category)
}
}
/**## ODFormattedJsonDatabaseIds_DefaultTickets `type`
* This type is an array of ids available in the `ODDatabaseManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODFormattedJsonDatabaseIds_DefaultTickets {
"openticket: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]): boolean
set(category:string, key:string, value:ODValidJsonType): boolean
set(category:string, key:string, value:ODValidJsonType): boolean {
return super.set(category,key,value)
}
get<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultTickets>(category:CategoryId, key:string): ODFormattedJsonDatabaseIds_DefaultTickets[CategoryId]|undefined
get(category:string, key:string): ODValidJsonType|undefined
get(category:string, key:string): ODValidJsonType|undefined {
return super.get(category,key)
}
delete<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultTickets>(category:CategoryId, key:string): boolean
delete(category:string, key:string): boolean
delete(category:string, key:string): boolean {
return super.delete(category,key)
}
exists(category:keyof ODFormattedJsonDatabaseIds_DefaultTickets, key:string): boolean
exists(category:string, key:string): boolean
exists(category:string, key:string): boolean {
return super.exists(category,key)
}
getCategory<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultTickets>(category:CategoryId): {key:string, value:ODFormattedJsonDatabaseIds_DefaultTickets[CategoryId]}[]|undefined
getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined
getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined {
return super.getCategory(category)
}
}
/**## ODFormattedJsonDatabaseIds_DefaultUsers `type`
* This type is an array of ids available in the `ODDatabaseManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODFormattedJsonDatabaseIds_DefaultUsers {
"openticket: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]): boolean
set(category:string, key:string, value:ODValidJsonType): boolean
set(category:string, key:string, value:ODValidJsonType): boolean {
return super.set(category,key,value)
}
get<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultUsers>(category:CategoryId, key:string): ODFormattedJsonDatabaseIds_DefaultUsers[CategoryId]|undefined
get(category:string, key:string): ODValidJsonType|undefined
get(category:string, key:string): ODValidJsonType|undefined {
return super.get(category,key)
}
delete<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultUsers>(category:CategoryId, key:string): boolean
delete(category:string, key:string): boolean
delete(category:string, key:string): boolean {
return super.delete(category,key)
}
exists(category:keyof ODFormattedJsonDatabaseIds_DefaultUsers, key:string): boolean
exists(category:string, key:string): boolean
exists(category:string, key:string): boolean {
return super.exists(category,key)
}
getCategory<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultUsers>(category:CategoryId): {key:string, value:ODFormattedJsonDatabaseIds_DefaultUsers[CategoryId]}[]|undefined
getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined
getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined {
return super.getCategory(category)
}
}
/**## ODFormattedJsonDatabaseIds_DefaultOptions `type`
* This type is an array of ids available in the `ODDatabaseManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODFormattedJsonDatabaseIds_DefaultOptions {
"openticket: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]): boolean
set(category:string, key:string, value:ODValidJsonType): boolean
set(category:string, key:string, value:ODValidJsonType): boolean {
return super.set(category,key,value)
}
get<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultOptions>(category:CategoryId, key:string): ODFormattedJsonDatabaseIds_DefaultOptions[CategoryId]|undefined
get(category:string, key:string): ODValidJsonType|undefined
get(category:string, key:string): ODValidJsonType|undefined {
return super.get(category,key)
}
delete<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultOptions>(category:CategoryId, key:string): boolean
delete(category:string, key:string): boolean
delete(category:string, key:string): boolean {
return super.delete(category,key)
}
exists(category:keyof ODFormattedJsonDatabaseIds_DefaultOptions, key:string): boolean
exists(category:string, key:string): boolean
exists(category:string, key:string): boolean {
return super.exists(category,key)
}
getCategory<CategoryId extends keyof ODFormattedJsonDatabaseIds_DefaultOptions>(category:CategoryId): {key:string, value:ODFormattedJsonDatabaseIds_DefaultOptions[CategoryId]}[]|undefined
getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined
getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined {
return super.getCategory(category)
}
}
+331
View File
@@ -0,0 +1,331 @@
///////////////////////////////////////
//DEFAULT EVENT MODULE
///////////////////////////////////////
//BASE MODULES
import { ODPromiseVoid, ODValidId } from "../modules/base"
import { ODPluginClassManager, ODPluginEventManager, ODPluginManager } from "../modules/plugin"
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 { ODVersionManager_Default } from "./base"
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, ODSlashCommandManager_Default, ODTextCommandManager_Default } from "./client"
import { ODBuilderManager_Default, ODButtonManager_Default, ODDropdownManager_Default, ODEmbedManager_Default, ODFileManager_Default, ODMessageManager_Default, ODModalManager_Default } from "./builder"
import { ODButtonResponderManager_Default, ODCommandResponderManager_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"
//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"
/**## ODEventIds_Default `type`
* This type is an array 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) => ODPromiseVoid>
"onPluginClassLoad": ODEvent_Default<(classes:ODPluginClassManager, plugins:ODPluginManager) => ODPromiseVoid>
"afterPluginClassesLoaded": ODEvent_Default<(classes:ODPluginClassManager, plugins:ODPluginManager) => ODPromiseVoid>
"onPluginEventLoad": ODEvent_Default<(classes:ODPluginEventManager, plugins:ODPluginManager) => ODPromiseVoid>
"afterPluginEventsLoaded": ODEvent_Default<(classes:ODPluginEventManager, plugins:ODPluginManager) => ODPromiseVoid>
"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>
//configs
"onConfigLoad": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid>
"afterConfigsLoaded": ODEvent_Default<(configs:ODConfigManager_Default) => ODPromiseVoid>
//databases
"onDatabaseLoad": ODEvent_Default<(databases:ODDatabaseManager_Default) => ODPromiseVoid>
"afterDatabasesLoaded": ODEvent_Default<(databases:ODDatabaseManager_Default) => ODPromiseVoid>
//languages
"onLanguageLoad": ODEvent_Default<(languages:ODLanguageManager_Default) => ODPromiseVoid>
"afterLanguagesLoaded": 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>
//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>
//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 text commands
"onTextCommandLoad": ODEvent_Default<(text:ODTextCommandManager_Default, client:ODClientManager_Default,) => ODPromiseVoid>
"afterTextCommandsLoaded": ODEvent_Default<(text:ODTextCommandManager_Default, client:ODClientManager_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>
//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>
//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>
//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>
//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>
//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>
}
/**## 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 `openticket.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 `openticket.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)
}
}
+53
View File
@@ -0,0 +1,53 @@
///////////////////////////////////////
//DEFAULT PROCESS MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODFlagManager, ODFlag } from "../modules/flag"
/**## ODFlagManagerIds_Default `type`
* This type is an array of ids available in the `ODFlagManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODFlagManagerIds_Default {
"openticket:no-migration":ODFlag,
"openticket:dev-config":ODFlag,
"openticket:dev-database":ODFlag,
"openticket:debug":ODFlag,
"openticket:crash":ODFlag,
"openticket:no-transcripts":ODFlag,
"openticket:no-checker":ODFlag,
"openticket:checker":ODFlag,
"openticket:no-easter":ODFlag,
"openticket:no-plugins":ODFlag,
"openticket:soft-plugins":ODFlag,
"openticket:force-slash-update":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 `openticket.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)
}
}
+323
View File
@@ -0,0 +1,323 @@
///////////////////////////////////////
//DEFAULT HELP MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODHelpMenuCategory, ODHelpMenuCommandComponent, ODHelpMenuComponent, ODHelpMenuManager } from "../modules/helpmenu"
/**## ODHelpMenuManagerIds_Default `type`
* This type is an array of ids available in the `ODHelpMenuManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerIds_Default {
"openticket:general":ODHelpMenuCategory_DefaultGeneral,
"openticket:ticket-basic":ODHelpMenuCategory_DefaultTicketBasic,
"openticket:ticket-advanced":ODHelpMenuCategory_DefaultTicketAdvanced,
"openticket:ticket-user":ODHelpMenuCategory_DefaultTicketUser,
"openticket:admin":ODHelpMenuCategory_DefaultAdmin,
"openticket:advanced":ODHelpMenuCategory_DefaultAdvanced,
"openticket: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 `openticket.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 type is an array of ids available in the `ODHelpMenuCategory_DefaultGeneral` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultGeneral {
"openticket:help":ODHelpMenuCommandComponent,
"openticket: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 `openticket:general` category in `openticket.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 type is an array of ids available in the `ODHelpMenuCategory_DefaultTicketBasic` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultTicketBasic {
"openticket:close":ODHelpMenuCommandComponent,
"openticket:delete":ODHelpMenuCommandComponent,
"openticket: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 `openticket:ticket` category in `openticket.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 type is an array of ids available in the `ODHelpMenuCategory_DefaultTicketAdvanced` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultTicketAdvanced {
"openticket:pin":ODHelpMenuCommandComponent,
"openticket:unpin":ODHelpMenuCommandComponent,
"openticket:move":ODHelpMenuCommandComponent,
"openticket: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 `openticket:ticket` category in `openticket.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 type is an array of ids available in the `ODHelpMenuCategory_DefaultTicketUser` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultTicketUser {
"openticket:claim":ODHelpMenuCommandComponent,
"openticket:unclaim":ODHelpMenuCommandComponent,
"openticket:add":ODHelpMenuCommandComponent,
"openticket:remove":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 `openticket:ticket` category in `openticket.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 type is an array of ids available in the `ODHelpMenuCategory_DefaultAdmin` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultAdmin {
"openticket:panel":ODHelpMenuCommandComponent,
"openticket:blacklist-view":ODHelpMenuCommandComponent,
"openticket:blacklist-add":ODHelpMenuCommandComponent,
"openticket:blacklist-remove":ODHelpMenuCommandComponent,
"openticket: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 `openticket:admin` category in `openticket.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 type is an array of ids available in the `ODHelpMenuCategory_DefaultAdvanced` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODHelpMenuManagerCategoryIds_DefaultAdvanced {
"openticket:stats-global":ODHelpMenuCommandComponent,
"openticket:stats-reset":ODHelpMenuCommandComponent,
"openticket:stats-ticket":ODHelpMenuCommandComponent,
"openticket:stats-user":ODHelpMenuCommandComponent,
"openticket:autoclose-disable":ODHelpMenuCommandComponent,
"openticket:autoclose-enable":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 `openticket:advanced` category in `openticket.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 type is an array 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 `openticket:general` category in `openticket.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)
}
}
+510
View File
@@ -0,0 +1,510 @@
///////////////////////////////////////
//DEFAULT LANGUAGE MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODLanguageManager, ODLanguage } from "../modules/language"
/**## ODLanguageManagerTranslations_Default `type`
* This type is an array of ids available in the `ODLanguageManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export type ODLanguageManagerTranslations_Default = (
"checker.system.headerOpenTicket"|
"checker.system.typeError"|
"checker.system.typeWarning"|
"checker.system.typeInfo"|
"checker.system.headerConfigChecker"|
"checker.system.headerDescription"|
"checker.system.footerError"|
"checker.system.footerWarning"|
"checker.system.footerSupport"|
"checker.system.compactInformation"|
"checker.system.dataPath"|
"checker.system.dataDocs"|
"checker.system.dataMessages"|
"checker.messages.invalidType"|
"checker.messages.propertyMissing"|
"checker.messages.propertyOptional"|
"checker.messages.objectDisabled"|
"checker.messages.nullInvalid"|
"checker.messages.switchInvalidType"|
"checker.messages.objectSwitchInvalid"|
"checker.messages.stringTooShort"|
"checker.messages.stringTooLong"|
"checker.messages.stringLengthInvalid"|
"checker.messages.stringStartsWith"|
"checker.messages.stringEndsWith"|
"checker.messages.stringContains"|
"checker.messages.stringChoices"|
"checker.messages.stringRegex"|
"checker.messages.numberTooShort"|
"checker.messages.numberTooLong"|
"checker.messages.numberLengthInvalid"|
"checker.messages.numberTooSmall"|
"checker.messages.numberTooLarge"|
"checker.messages.numberNotEqual"|
"checker.messages.numberStep"|
"checker.messages.numberStepOffset"|
"checker.messages.numberStartsWith"|
"checker.messages.numberEndsWith"|
"checker.messages.numberContains"|
"checker.messages.numberChoices"|
"checker.messages.numberFloat"|
"checker.messages.numberNegative"|
"checker.messages.numberPositive"|
"checker.messages.numberZero"|
"checker.messages.booleanTrue"|
"checker.messages.booleanFalse"|
"checker.messages.arrayEmptyDisabled"|
"checker.messages.arrayEmptyRequired"|
"checker.messages.arrayTooShort"|
"checker.messages.arrayTooLong"|
"checker.messages.arrayLengthInvalid"|
"checker.messages.arrayInvalidTypes"|
"checker.messages.arrayDouble"|
"checker.messages.discordInvalidId"|
"checker.messages.discordInvalidIdOptions"|
"checker.messages.discordInvalidToken"|
"checker.messages.colorInvalid"|
"checker.messages.emojiTooShort"|
"checker.messages.emojiTooLong"|
"checker.messages.emojiCustom"|
"checker.messages.emojiInvalid"|
"checker.messages.urlInvalid"|
"checker.messages.urlInvalidHttp"|
"checker.messages.urlInvalidProtocol"|
"checker.messages.urlInvalidHostname"|
"checker.messages.urlInvalidExtension"|
"checker.messages.urlInvalidPath"|
"checker.messages.idNotUnique"|
"checker.messages.idNonExistent"|
"checker.messages.invalidLanguage"|
"checker.messages.invalidButton"|
"checker.messages.unusedOption"|
"checker.messages.unusedQuestion"|
"checker.messages.dropdownOption"|
"actions.buttons.create"|
"actions.buttons.close"|
"actions.buttons.delete"|
"actions.buttons.reopen"|
"actions.buttons.claim"|
"actions.buttons.unclaim"|
"actions.buttons.pin"|
"actions.buttons.unpin"|
"actions.buttons.clear"|
"actions.buttons.helpSwitchSlash"|
"actions.buttons.helpSwitchText"|
"actions.buttons.helpPage"|
"actions.buttons.withReason"|
"actions.buttons.withoutTranscript"|
"actions.titles.created"|
"actions.titles.close"|
"actions.titles.delete"|
"actions.titles.reopen"|
"actions.titles.claim"|
"actions.titles.unclaim"|
"actions.titles.pin"|
"actions.titles.unpin"|
"actions.titles.rename"|
"actions.titles.move"|
"actions.titles.add"|
"actions.titles.remove"|
"actions.titles.help"|
"actions.titles.statsReset"|
"actions.titles.blacklistAdd"|
"actions.titles.blacklistRemove"|
"actions.titles.blacklistGet"|
"actions.titles.blacklistView"|
"actions.titles.blacklistAddDm"|
"actions.titles.blacklistRemoveDm"|
"actions.titles.clear"|
"actions.titles.roles"|
"actions.titles.autoclose"|
"actions.titles.autocloseEnabled"|
"actions.titles.autocloseDisabled"|
"actions.titles.autodelete"|
"actions.titles.autodeleteEnabled"|
"actions.titles.autodeleteDisabled"|
"actions.descriptions.create"|
"actions.descriptions.close"|
"actions.descriptions.delete"|
"actions.descriptions.reopen"|
"actions.descriptions.claim"|
"actions.descriptions.unclaim"|
"actions.descriptions.pin"|
"actions.descriptions.unpin"|
"actions.descriptions.rename"|
"actions.descriptions.move"|
"actions.descriptions.add"|
"actions.descriptions.remove"|
"actions.descriptions.helpExplanation"|
"actions.descriptions.statsReset"|
"actions.descriptions.statsError"|
"actions.descriptions.blacklistAdd"|
"actions.descriptions.blacklistRemove"|
"actions.descriptions.blacklistGetSuccess"|
"actions.descriptions.blacklistGetEmpty"|
"actions.descriptions.blacklistViewEmpty"|
"actions.descriptions.blacklistViewTip"|
"actions.descriptions.clearVerify"|
"actions.descriptions.clearReady"|
"actions.descriptions.rolesEmpty"|
"actions.descriptions.autocloseLeave"|
"actions.descriptions.autocloseTimeout"|
"actions.descriptions.autodeleteLeave"|
"actions.descriptions.autodeleteTimeout"|
"actions.descriptions.autocloseEnabled"|
"actions.descriptions.autocloseDisabled"|
"actions.descriptions.autodeleteEnabled"|
"actions.descriptions.autodeleteDisabled"|
"actions.descriptions.ticketMessageLimit"|
"actions.descriptions.ticketMessageAutoclose"|
"actions.descriptions.ticketMessageAutodelete"|
"actions.descriptions.panelReady"|
"actions.modal.closePlaceholder"|
"actions.modal.deletePlaceholder"|
"actions.modal.reopenPlaceholder"|
"actions.modal.claimPlaceholder"|
"actions.modal.unclaimPlaceholder"|
"actions.modal.pinPlaceholder"|
"actions.modal.unpinPlaceholder"|
"actions.logs.createLog"|
"actions.logs.closeLog"|
"actions.logs.closeDm"|
"actions.logs.deleteLog"|
"actions.logs.deleteDm"|
"actions.logs.reopenLog"|
"actions.logs.reopenDm"|
"actions.logs.claimLog"|
"actions.logs.claimDm"|
"actions.logs.unclaimLog"|
"actions.logs.unclaimDm"|
"actions.logs.pinLog"|
"actions.logs.pinDm"|
"actions.logs.unpinLog"|
"actions.logs.unpinDm"|
"actions.logs.renameLog"|
"actions.logs.renameDm"|
"actions.logs.moveLog"|
"actions.logs.moveDm"|
"actions.logs.addLog"|
"actions.logs.addDm"|
"actions.logs.removeLog"|
"actions.logs.removeDm"|
"actions.logs.blacklistAddLog"|
"actions.logs.blacklistRemoveLog"|
"actions.logs.blacklistAddDm"|
"actions.logs.blacklistRemoveDm"|
"actions.logs.clearLog"|
"transcripts.success.visit"|
"transcripts.success.ready"|
"transcripts.success.textFileDescription"|
"transcripts.success.htmlProgress"|
"transcripts.success.createdChannel"|
"transcripts.success.createdCreator"|
"transcripts.success.createdParticipant"|
"transcripts.success.createdActiveAdmin"|
"transcripts.success.createdEveryAdmin"|
"transcripts.success.createdOther"|
"transcripts.errors.retry"|
"transcripts.errors.continue"|
"transcripts.errors.backup"|
"transcripts.errors.error"|
"errors.titles.internalError"|
"errors.titles.optionMissing"|
"errors.titles.optionInvalid"|
"errors.titles.unknownCommand"|
"errors.titles.noPermissions"|
"errors.titles.unknownTicket"|
"errors.titles.deprecatedTicket"|
"errors.titles.unknownOption"|
"errors.titles.unknownPanel"|
"errors.titles.notInGuild"|
"errors.titles.channelRename"|
"errors.titles.busy"|
"errors.descriptions.askForInfo"|
"errors.descriptions.askForInfoResolve"|
"errors.descriptions.internalError"|
"errors.descriptions.optionMissing"|
"errors.descriptions.optionInvalid"|
"errors.descriptions.optionInvalidChoose"|
"errors.descriptions.unknownCommand"|
"errors.descriptions.noPermissions"|
"errors.descriptions.noPermissionsList"|
"errors.descriptions.noPermissionsCooldown"|
"errors.descriptions.noPermissionsBlacklist"|
"errors.descriptions.noPermissionsLimitGlobal"|
"errors.descriptions.noPermissionsLimitGlobalUser"|
"errors.descriptions.noPermissionsLimitOption"|
"errors.descriptions.noPermissionsLimitOptionUser"|
"errors.descriptions.unknownTicket"|
"errors.descriptions.deprecatedTicket"|
"errors.descriptions.notInGuild"|
"errors.descriptions.channelRename"|
"errors.descriptions.channelRenameSource"|
"errors.descriptions.busy"|
"errors.optionInvalidReasons.stringRegex"|
"errors.optionInvalidReasons.stringMinLength"|
"errors.optionInvalidReasons.stringMaxLength"|
"errors.optionInvalidReasons.numberInvalid"|
"errors.optionInvalidReasons.numberMin"|
"errors.optionInvalidReasons.numberMax"|
"errors.optionInvalidReasons.numberDecimal"|
"errors.optionInvalidReasons.numberNegative"|
"errors.optionInvalidReasons.numberPositive"|
"errors.optionInvalidReasons.numberZero"|
"errors.optionInvalidReasons.channelNotFound"|
"errors.optionInvalidReasons.userNotFound"|
"errors.optionInvalidReasons.roleNotFound"|
"errors.optionInvalidReasons.memberNotFound"|
"errors.optionInvalidReasons.mentionableNotFound"|
"errors.optionInvalidReasons.channelType"|
"errors.optionInvalidReasons.notInGuild"|
"errors.permissions.developer"|
"errors.permissions.owner"|
"errors.permissions.admin"|
"errors.permissions.moderator"|
"errors.permissions.support"|
"errors.permissions.member"|
"errors.permissions.discord-administrator"|
"errors.actionInvalid.close"|
"errors.actionInvalid.reopen"|
"errors.actionInvalid.claim"|
"errors.actionInvalid.unclaim"|
"errors.actionInvalid.pin"|
"errors.actionInvalid.unpin"|
"errors.actionInvalid.add"|
"errors.actionInvalid.remove"|
"params.uppercase.ticket"|
"params.uppercase.tickets"|
"params.uppercase.reason"|
"params.uppercase.creator"|
"params.uppercase.remaining"|
"params.uppercase.added"|
"params.uppercase.removed"|
"params.uppercase.filter"|
"params.uppercase.claimedBy"|
"params.uppercase.method"|
"params.uppercase.type"|
"params.uppercase.blacklisted"|
"params.uppercase.panel"|
"params.uppercase.command"|
"params.uppercase.system"|
"params.uppercase.true"|
"params.uppercase.false"|
"params.uppercase.syntax"|
"params.uppercase.originalName"|
"params.uppercase.newName"|
"params.uppercase.until"|
"params.uppercase.validOptions"|
"params.uppercase.validPanels"|
"params.uppercase.autoclose"|
"params.uppercase.autodelete"|
"params.uppercase.startupDate"|
"params.uppercase.version"|
"params.uppercase.name"|
"params.uppercase.role"|
"params.uppercase.status"|
"params.uppercase.claimed"|
"params.uppercase.pinned"|
"params.uppercase.creationDate"|
"params.lowercase.text"|
"params.lowercase.html"|
"params.lowercase.command"|
"params.lowercase.modal"|
"params.lowercase.button"|
"params.lowercase.dropdown"|
"params.lowercase.method"|
"commands.reason"|
"commands.help"|
"commands.panel"|
"commands.panelId"|
"commands.panelAutoUpdate"|
"commands.ticket"|
"commands.ticketId"|
"commands.close"|
"commands.delete"|
"commands.deleteNoTranscript"|
"commands.reopen"|
"commands.claim"|
"commands.claimUser"|
"commands.unclaim"|
"commands.pin"|
"commands.unpin"|
"commands.move"|
"commands.moveId"|
"commands.rename"|
"commands.renameName"|
"commands.add"|
"commands.addUser"|
"commands.remove"|
"commands.removeUser"|
"commands.blacklist"|
"commands.blacklistView"|
"commands.blacklistAdd"|
"commands.blacklistRemove"|
"commands.blacklistGet"|
"commands.blacklistGetUser"|
"commands.stats"|
"commands.statsReset"|
"commands.statsGlobal"|
"commands.statsUser"|
"commands.statsUserUser"|
"commands.statsTicket"|
"commands.statsTicketTicket"|
"commands.clear"|
"commands.clearFilter"|
"commands.clearFilters.all"|
"commands.clearFilters.open"|
"commands.clearFilters.close"|
"commands.clearFilters.claim"|
"commands.clearFilters.unclaim"|
"commands.clearFilters.pin"|
"commands.clearFilters.unpin"|
"commands.clearFilters.autoclose"|
"commands.autoclose"|
"commands.autocloseDisable"|
"commands.autocloseEnable"|
"commands.autocloseEnableTime"|
"commands.autodelete"|
"commands.autodeleteDisable"|
"commands.autodeleteEnable"|
"commands.autodeleteEnableTime"|
"helpMenu.help"|
"helpMenu.ticket"|
"helpMenu.close"|
"helpMenu.delete"|
"helpMenu.reopen"|
"helpMenu.pin"|
"helpMenu.unpin"|
"helpMenu.move"|
"helpMenu.rename"|
"helpMenu.claim"|
"helpMenu.unclaim"|
"helpMenu.add"|
"helpMenu.remove"|
"helpMenu.panel"|
"helpMenu.blacklistView"|
"helpMenu.blacklistAdd"|
"helpMenu.blacklistRemove"|
"helpMenu.blacklistGet"|
"helpMenu.statsGlobal"|
"helpMenu.statsTicket"|
"helpMenu.statsUser"|
"helpMenu.statsReset"|
"helpMenu.autocloseDisable"|
"helpMenu.autocloseEnable"|
"helpMenu.autodeleteDisable"|
"helpMenu.autodeleteEnable"|
"stats.scopes.global"|
"stats.scopes.system"|
"stats.scopes.user"|
"stats.scopes.ticket"|
"stats.scopes.participants"|
"stats.properties.ticketsCreated"|
"stats.properties.ticketsClosed"|
"stats.properties.ticketsDeleted"|
"stats.properties.ticketsReopened"|
"stats.properties.ticketsAutoclosed"|
"stats.properties.ticketsClaimed"|
"stats.properties.ticketsPinned"|
"stats.properties.ticketsMoved"|
"stats.properties.usersBlacklisted"|
"stats.properties.transcriptsCreated"
)
/**## ODLanguageManagerIds_Default `type`
* This type is an array of ids available in the `ODLanguageManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODLanguageManagerIds_Default {
"openticket:custom":ODLanguage,
"openticket:english":ODLanguage,
"openticket:dutch":ODLanguage,
"openticket:portuguese":ODLanguage,
"openticket:czech":ODLanguage,
//ADD NEW LANGUAGES HERE!!!
}
/**## 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 `openticket.languages`!
*/
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)
}
}
+30
View File
@@ -0,0 +1,30 @@
///////////////////////////////////////
//DEFAULT PERMISSION MODULE
///////////////////////////////////////
import { ODDebugger } from "../modules/console"
import { ODPermissionManager } from "../modules/permission"
/**## 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 `openticket.permissions`!
*/
export class ODPermissionManager_Default extends ODPermissionManager {
constructor(debug:ODDebugger){
super(debug,true)
}
}
/**## ODPermissionEmbedType `type`
* This type contains all types available in the `openticket:no-permissions` embed.
*/
export type ODPermissionEmbedType = (
"developer"|
"owner"|
"admin"|
"moderator"|
"support"|
"member"|
"discord-administrator"
)
+44
View File
@@ -0,0 +1,44 @@
///////////////////////////////////////
//DEFAULT POST MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODPost, ODPostManager } from "../modules/post"
import * as discord from "discord.js"
/**## ODPostManagerIds_Default `type`
* This type is an array of ids available in the `ODPostManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODPostManagerIds_Default {
"openticket:logs":ODPost<discord.GuildTextBasedChannel>|null,
"openticket: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 `openticket.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)
}
}
+255
View File
@@ -0,0 +1,255 @@
///////////////////////////////////////
//DEFAULT RESPONDER MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODButtonResponder, ODButtonResponderInstance, ODButtonResponderManager, ODCommandResponder, ODCommandResponderInstance, ODCommandResponderManager, 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 `openticket.responders`!
*/
export class ODResponderManager_Default extends ODResponderManager {
declare commands: ODCommandResponderManager_Default
declare buttons: ODButtonResponderManager_Default
declare dropdowns: ODDropdownResponderManager_Default
declare modals: ODModalResponderManager_Default
}
/**## ODCommandResponderManagerIds_Default `type`
* This type is an array of ids available in the `ODCommandResponderManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODCommandResponderManagerIds_Default {
"openticket:help":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:help"|"openticket:logs"},
"openticket:stats":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:stats"|"openticket:logs"},
"openticket:panel":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:panel"|"openticket:logs"},
"openticket:ticket":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:ticket"|"openticket:logs"},
"openticket:blacklist":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:blacklist"|"openticket:discord-logs"|"openticket:logs"},
"openticket:close":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:close"|"openticket:logs"},
"openticket:reopen":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:reopen"|"openticket:logs"},
"openticket:delete":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:delete"|"openticket:logs"},
"openticket:claim":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:claim"|"openticket:logs"},
"openticket:unclaim":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:unclaim"|"openticket:logs"},
"openticket:pin":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:pin"|"openticket:logs"},
"openticket:unpin":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:unpin"|"openticket:logs"},
"openticket:rename":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:rename"|"openticket:logs"},
"openticket:move":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:move"|"openticket:logs"},
"openticket:add":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:add"|"openticket:logs"},
"openticket:remove":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:remove"|"openticket:logs"},
"openticket:clear":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:clear"|"openticket:logs"},
"openticket:autoclose":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:autoclose"|"openticket:logs"},
"openticket:autodelete":{source:"slash"|"text",params:{},workers:"openticket:permissions"|"openticket:autodelete"|"openticket: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 `openticket.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 `type`
* This type is an array of ids available in the `ODButtonResponderManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODButtonResponderManagerIds_Default {
"openticket:verifybar-success":{source:"button",params:{},workers:"openticket:handle-verifybar"},
"openticket:verifybar-failure":{source:"button",params:{},workers:"openticket:handle-verifybar"},
"openticket:help-menu-switch":{source:"button",params:{},workers:"openticket:update-help-menu"},
"openticket:help-menu-previous":{source:"button",params:{},workers:"openticket:update-help-menu"},
"openticket:help-menu-next":{source:"button",params:{},workers:"openticket:update-help-menu"},
"openticket:ticket-option":{source:"button",params:{},workers:"openticket:ticket-option"},
"openticket:role-option":{source:"button",params:{},workers:"openticket:role-option"},
"openticket:claim-ticket":{source:"button",params:{},workers:"openticket:claim-ticket"},
"openticket:unclaim-ticket":{source:"button",params:{},workers:"openticket:unclaim-ticket"},
"openticket:pin-ticket":{source:"button",params:{},workers:"openticket:pin-ticket"},
"openticket:unpin-ticket":{source:"button",params:{},workers:"openticket:unpin-ticket"},
"openticket:close-ticket":{source:"button",params:{},workers:"openticket:close-ticket"},
"openticket:reopen-ticket":{source:"button",params:{},workers:"openticket:reopen-ticket"},
"openticket:delete-ticket":{source:"button",params:{},workers:"openticket:delete-ticket"},
"openticket:transcript-error-retry":{source:"button",params:{},workers:"openticket:permissions"|"openticket:delete-ticket"|"openticket:logs"},
"openticket:transcript-error-continue":{source:"button",params:{},workers:"openticket:permissions"|"openticket:delete-ticket"|"openticket:logs"},
"openticket:clear-continue":{source:"button",params:{},workers:"openticket: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 `openticket.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 `type`
* This type is an array of ids available in the `ODDropdownResponderManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODDropdownResponderManagerIds_Default {
"openticket:panel-dropdown-tickets":{source:"dropdown",params:{},workers:"openticket: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 `openticket.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 `type`
* This type is an array of ids available in the `ODModalResponderManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODModalResponderManagerIds_Default {
"openticket:ticket-questions":{source:"modal",params:{},workers:"openticket:ticket-questions"},
"openticket:close-ticket-reason":{source:"modal",params:{},workers:"openticket:close-ticket-reason"},
"openticket:reopen-ticket-reason":{source:"modal",params:{},workers:"openticket:reopen-ticket-reason"},
"openticket:delete-ticket-reason":{source:"modal",params:{},workers:"openticket:delete-ticket-reason"},
"openticket:claim-ticket-reason":{source:"modal",params:{},workers:"openticket:claim-ticket-reason"},
"openticket:unclaim-ticket-reason":{source:"modal",params:{},workers:"openticket:unclaim-ticket-reason"},
"openticket:pin-ticket-reason":{source:"modal",params:{},workers:"openticket:pin-ticket-reason"},
"openticket:unpin-ticket-reason":{source:"modal",params:{},workers:"openticket: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 `openticket.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>
}
+42
View File
@@ -0,0 +1,42 @@
///////////////////////////////////////
//DEFAULT SESSION MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODSession, ODSessionManager } from "../modules/session"
/**## ODSessionManagerIds_Default `type`
* This type is an array 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 `openticket.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
@@ -0,0 +1,48 @@
///////////////////////////////////////
//DEFAULT STARTSCREEN MODULE
///////////////////////////////////////
import { ODValidId } from "../modules/base"
import { ODStartScreenCategoryComponent, ODStartScreenComponent, ODStartScreenFlagsCategoryComponent, ODStartScreenHeaderComponent, ODStartScreenLiveStatusCategoryComponent, ODStartScreenLogoComponent, ODStartScreenManager, ODStartScreenPluginsCategoryComponent, ODStartScreenPropertiesCategoryComponent } from "../modules/startscreen"
/**## ODStartScreenManagerIds_Default `type`
* This type is an array of ids available in the `ODStartScreenManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStartScreenManagerIds_Default {
"openticket:logo":ODStartScreenLogoComponent,
"openticket:header":ODStartScreenHeaderComponent,
"openticket:flags":ODStartScreenFlagsCategoryComponent,
"openticket:plugins":ODStartScreenPluginsCategoryComponent,
"openticket:stats":ODStartScreenPropertiesCategoryComponent,
"openticket:livestatus":ODStartScreenLiveStatusCategoryComponent,
"openticket: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 `openticket.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)
}
}
+363
View File
@@ -0,0 +1,363 @@
///////////////////////////////////////
//DEFAULT SESSION MODULE
///////////////////////////////////////
import { Guild, TextBasedChannel, User } from "discord.js"
import { ODValidId } from "../modules/base"
import { ODStatScope, ODStatGlobalScope, ODStatsManager, ODStat, ODBasicStat, ODDynamicStat, ODValidStatValue, ODStatScopeSetMode } from "../modules/stat"
/**## ODStatsManagerIds_Default `type`
* This type is an array of ids available in the `ODStatsManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatsManagerIds_Default {
"openticket:global":ODStatGlobalScope_DefaultGlobal,
"openticket:system":ODStatGlobalScope_DefaultSystem,
"openticket:user":ODStatScope_DefaultUser,
"openticket:ticket":ODStatScope_DefaultTicket,
"openticket:participants":ODStatScope_DefaultParticipants
}
/**## 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 `openticket.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 type is an array of ids available in the `ODStatGlobalScope_DefaultGlobal` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatGlobalScopeIds_DefaultGlobal {
"openticket:tickets-created":ODBasicStat,
"openticket:tickets-closed":ODBasicStat,
"openticket:tickets-deleted":ODBasicStat,
"openticket:tickets-reopened":ODBasicStat,
"openticket:tickets-autoclosed":ODBasicStat,
"openticket:tickets-autodeleted":ODBasicStat,
"openticket:tickets-claimed":ODBasicStat,
"openticket:tickets-pinned":ODBasicStat,
"openticket:tickets-moved":ODBasicStat,
"openticket:users-blacklisted":ODBasicStat,
"openticket:transcripts-created":ODBasicStat
}
/**## 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 `openticket:global` category in `openticket.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): ODValidStatValue|null
getStat(id:ODValidId): ODValidStatValue|null
getStat(id:ODValidId): ODValidStatValue|null {
return super.getStat(id)
}
setStat<StatsId extends keyof ODStatGlobalScopeIds_DefaultGlobal>(id:StatsId, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean
setStat(id:ODValidId, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean
setStat(id:ODValidId, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean {
return super.setStat(id,value,mode)
}
resetStat<StatsId extends keyof ODStatGlobalScopeIds_DefaultGlobal>(id:ODValidId): ODValidStatValue|null
resetStat(id:ODValidId): ODValidStatValue|null
resetStat(id:ODValidId): ODValidStatValue|null {
return super.resetStat(id)
}
}
/**## ODStatGlobalScopeIds_DefaultSystem `type`
* This type is an array of ids available in the `ODStatScope_DefaultSystem` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatGlobalScopeIds_DefaultSystem {
"openticket:startup-date":ODDynamicStat,
"openticket: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 `openticket:system` category in `openticket.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): ODValidStatValue|null
getStat(id:ODValidId): ODValidStatValue|null
getStat(id:ODValidId): ODValidStatValue|null {
return super.getStat(id)
}
setStat<StatsId extends keyof ODStatGlobalScopeIds_DefaultSystem>(id:StatsId, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean
setStat(id:ODValidId, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean
setStat(id:ODValidId, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean {
return super.setStat(id,value,mode)
}
resetStat<StatsId extends keyof ODStatGlobalScopeIds_DefaultSystem>(id:ODValidId): ODValidStatValue|null
resetStat(id:ODValidId): ODValidStatValue|null
resetStat(id:ODValidId): ODValidStatValue|null {
return super.resetStat(id)
}
}
/**## ODStatScopeIds_DefaultUser `type`
* This type is an array of ids available in the `ODStatScope_DefaultUser` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatScopeIds_DefaultUser {
"openticket:name":ODDynamicStat,
"openticket:role":ODDynamicStat,
"openticket:tickets-created":ODBasicStat,
"openticket:tickets-closed":ODBasicStat,
"openticket:tickets-deleted":ODBasicStat,
"openticket:tickets-reopened":ODBasicStat,
"openticket:tickets-claimed":ODBasicStat,
"openticket:tickets-pinned":ODBasicStat,
"openticket:tickets-moved":ODBasicStat,
"openticket:users-blacklisted":ODBasicStat,
"openticket:transcripts-created":ODBasicStat
}
/**## 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 `openticket:user` category in `openticket.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): ODValidStatValue|null
getStat(id:ODValidId, scopeId:string): ODValidStatValue|null
getStat(id:ODValidId, scopeId:string): ODValidStatValue|null {
return super.getStat(id,scopeId)
}
setStat<StatsId extends keyof ODStatScopeIds_DefaultUser>(id:StatsId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean {
return super.setStat(id,scopeId,value,mode)
}
resetStat<StatsId extends keyof ODStatScopeIds_DefaultUser>(id:ODValidId, scopeId:string): ODValidStatValue|null
resetStat(id:ODValidId, scopeId:string): ODValidStatValue|null
resetStat(id:ODValidId, scopeId:string): ODValidStatValue|null {
return super.resetStat(id,scopeId)
}
}
/**## ODStatScopeIds_DefaultTicket `type`
* This type is an array of ids available in the `ODStatScope_DefaultTicket` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatScopeIds_DefaultTicket {
"openticket:name":ODDynamicStat,
"openticket:status":ODDynamicStat,
"openticket:claimed":ODDynamicStat,
"openticket:pinned":ODDynamicStat,
"openticket:creation-date":ODDynamicStat,
"openticket:creator":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 `openticket:ticket` category in `openticket.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): ODValidStatValue|null
getStat(id:ODValidId, scopeId:string): ODValidStatValue|null
getStat(id:ODValidId, scopeId:string): ODValidStatValue|null {
return super.getStat(id,scopeId)
}
setStat<StatsId extends keyof ODStatScopeIds_DefaultTicket>(id:StatsId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean {
return super.setStat(id,scopeId,value,mode)
}
resetStat<StatsId extends keyof ODStatScopeIds_DefaultTicket>(id:ODValidId, scopeId:string): ODValidStatValue|null
resetStat(id:ODValidId, scopeId:string): ODValidStatValue|null
resetStat(id:ODValidId, scopeId:string): ODValidStatValue|null {
return super.resetStat(id,scopeId)
}
}
/**## ODStatScopeIds_DefaultParticipants `type`
* This type is an array of ids available in the `ODStatScope_DefaultParticipants` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODStatScopeIds_DefaultParticipants {
"openticket: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 `openticket:participants` category in `openticket.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): ODValidStatValue|null
getStat(id:ODValidId, scopeId:string): ODValidStatValue|null
getStat(id:ODValidId, scopeId:string): ODValidStatValue|null {
return super.getStat(id,scopeId)
}
setStat<StatsId extends keyof ODStatScopeIds_DefaultParticipants>(id:StatsId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean {
return super.setStat(id,scopeId,value,mode)
}
resetStat<StatsId extends keyof ODStatScopeIds_DefaultParticipants>(id:ODValidId, scopeId:string): ODValidStatValue|null
resetStat(id:ODValidId, scopeId:string): ODValidStatValue|null
resetStat(id:ODValidId, scopeId:string): ODValidStatValue|null {
return super.resetStat(id,scopeId)
}
}
+72
View File
@@ -0,0 +1,72 @@
///////////////////////////////////////
//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 `type`
* This type is an array of ids available in the `ODVerifyBarManager_Default` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODVerifyBarManagerIds_Default {
"openticket:claim-ticket-ticket-message":{successWorkerIds:"openticket:permissions"|"openticket:claim-ticket",failureWorkerIds:"openticket:back-to-ticket-message"},
"openticket:claim-ticket-unclaim-message":{successWorkerIds:"openticket:permissions"|"openticket:claim-ticket",failureWorkerIds:"openticket:back-to-unclaim-message"},
"openticket:unclaim-ticket-ticket-message":{successWorkerIds:"openticket:permissions"|"openticket:unclaim-ticket",failureWorkerIds:"openticket:back-to-ticket-message"},
"openticket:unclaim-ticket-claim-message":{successWorkerIds:"openticket:permissions"|"openticket:unclaim-ticket",failureWorkerIds:"openticket:back-to-claim-message"},
"openticket:pin-ticket-ticket-message":{successWorkerIds:"openticket:permissions"|"openticket:pin-ticket",failureWorkerIds:"openticket:back-to-ticket-message"},
"openticket:pin-ticket-unpin-message":{successWorkerIds:"openticket:permissions"|"openticket:pin-ticket",failureWorkerIds:"openticket:back-to-unpin-message"},
"openticket:unpin-ticket-ticket-message":{successWorkerIds:"openticket:permissions"|"openticket:unpin-ticket",failureWorkerIds:"openticket:back-to-ticket-message"},
"openticket:unpin-ticket-pin-message":{successWorkerIds:"openticket:permissions"|"openticket:unpin-ticket",failureWorkerIds:"openticket:back-to-pin-message"},
"openticket:close-ticket-ticket-message":{successWorkerIds:"openticket:permissions"|"openticket:close-ticket",failureWorkerIds:"openticket:back-to-ticket-message"},
"openticket:close-ticket-reopen-message":{successWorkerIds:"openticket:permissions"|"openticket:close-ticket",failureWorkerIds:"openticket:back-to-reopen-message"},
"openticket:reopen-ticket-ticket-message":{successWorkerIds:"openticket:permissions"|"openticket:reopen-ticket",failureWorkerIds:"openticket:back-to-ticket-message"},
"openticket:reopen-ticket-close-message":{successWorkerIds:"openticket:permissions"|"openticket:reopen-ticket",failureWorkerIds:"openticket:back-to-close-message"},
"openticket:reopen-ticket-autoclose-message":{successWorkerIds:"openticket:permissions"|"openticket:reopen-ticket",failureWorkerIds:"openticket:back-to-autoclose-message"},
"openticket:delete-ticket-ticket-message":{successWorkerIds:"openticket:permissions"|"openticket:delete-ticket",failureWorkerIds:"openticket:back-to-ticket-message"}
"openticket:delete-ticket-close-message":{successWorkerIds:"openticket:permissions"|"openticket:delete-ticket",failureWorkerIds:"openticket:back-to-close-message"}
"openticket:delete-ticket-reopen-message":{successWorkerIds:"openticket:permissions"|"openticket:delete-ticket",failureWorkerIds:"openticket:back-to-reopen-message"}
"openticket:delete-ticket-autoclose-message":{successWorkerIds:"openticket:permissions"|"openticket:delete-ticket",failureWorkerIds:"openticket: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 `openticket.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
@@ -0,0 +1,35 @@
///////////////////////////////////////
//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)
}
}
+180
View File
@@ -0,0 +1,180 @@
//BASE MODULES
import { ODEnvHelper, ODVersion } from "./modules/base"
import { ODPluginManager } from "./modules/plugin"
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 { 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 { 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"
/**## 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 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
/**The manager that manages & checks all the console flags of the bot. (like `--debug`) */
flags: ODFlagManager_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
constructor(){
this.versions = new ODVersionManager_Default()
this.versions.add(ODVersion.fromString("openticket:version","v4.0.0"))
this.versions.add(ODVersion.fromString("openticket:api","v1.0.0"))
this.versions.add(ODVersion.fromString("openticket:transcripts","v2.0.0"))
this.versions.add(ODVersion.fromString("openticket:livestatus","v2.0.0"))
this.debugfile = new ODDebugFileManager("./","otdebug.txt",5000,this.versions.get("openticket: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(this.debug)
this.flags = new ODFlagManager_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.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.roles = new ODRoleManager(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
@@ -0,0 +1,58 @@
///////////////////////////////////////
//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
}
}
+749
View File
@@ -0,0 +1,749 @@
///////////////////////////////////////
//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>
/**## 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>>
/**## ODId `class`
* This is an open ticket identifier.
*
* It can only contain the following characters: `a-z`, `A-Z`, `0-9`, `:`, `-` & `_`
*
* You will use this class to assign a unique id when creating configs, databases, languages & more!
* @example
* const id = new api.ODId("openticket:test-id") //this is valid
* const id = new api.ODId("example%id?") //this is invalid
*/
export class ODId {
/**The full value of this `ODId` as a `string` */
value: string
/**The source of the id (part before `:`). For example `openticket` for all built-in ids! */
source: string
/**The identifier of the id (part after `:`). */
identifier: string
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+")'")
const splitted = this.value.split(":")
if (splitted.length > 1){
this.source = splitted[0]
splitted.shift()
this.identifier = splitted.join(":")
}else{
this.identifier = splitted.join(":")
this.source = ""
}
}else{
//id is ODId
this.value = id.value
this.source = id.source
this.identifier = id.identifier
}
}
/**Returns a string representation of this id. (same as `this.value`) */
toString(){
return this.value
}
}
/**## ODManagerChangeHelper `class`
* This is an open ticket manager change helper.
*
* It is used to let the "onChange" event in the `ODManager` class work.
* You will probably use this class when extending your own `ODManager`
*/
export class ODManagerChangeHelper {
#change: (() => void)|null = null
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
}
}
/**## ODManagerRedirectHelper `class`
* This is open ticket ticket manager redirect helper.
*
* It is used to redirect a source to another source when the id isn't found.
*
* It will be used in **Open Discord** to allow plugins from all projects to work seamlessly!
* ## **(❌ SYSTEM ONLY!!)**
*/
export class ODManagerRedirectHelper {
#data: {fromSource:string,toSource:string}[] = []
/****(❌ SYSTEM ONLY!!)** Add a redirect to this manager. Returns `true` when overwritten. */
add(fromSource:string, toSource:string){
const index = this.#data.findIndex((data) => data.fromSource === fromSource)
if (index > -1){
//already exists
this.#data[index] = {fromSource,toSource}
return true
}else{
//doesn't exist
this.#data.push({fromSource,toSource})
return false
}
}
/****(❌ SYSTEM ONLY!!)** Remove a redirect from this manager. Returns `true` when it existed. */
remove(fromSource:string, toSource:string){
const index = this.#data.findIndex((data) => data.fromSource === fromSource && data.toSource == toSource)
if (index > -1){
//already exists
this.#data.splice(index,1)
return true
}else return false
}
/**List all redirects from this manager. */
list(){
return [...this.#data]
}
}
/**## 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 different aspects of the bot!
* You will probably to extend this class when creating your own classes & managers.
*
* This class has many useful functions based on `ODId` (add, get, remove, getAll, getFiltered, exists)
*/
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
/**An array storing all data classes ❌ **(don't edit unless really needed!)***/
#data: DataType[] = []
/**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>[] = []
/**Handle all redirects in this `ODManager` */
redirects: ODManagerRedirectHelper = new ODManagerRedirectHelper()
constructor(debug?:ODDebugger, debugname?:string){
super()
this.#debug = debug
this.#debugname = debugname
}
/**Add data to the manager. The id will be fetched from the data class! 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 data
const existIndex = this.#data.findIndex((d) => d.id.value === data.id.value)
if (existIndex < 0){
this.#data.push(data)
if (this.#debug) this.#debug.debug("Added new "+this.#debugname+" to manager",[{key:"id",value:data.id.value},{key:"overwrite",value:"false"}])
//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)
}
})
})
//add listeners
this.#addListeners.forEach((cb) => {
try{
cb(data,false)
}catch(err){
throw new ODSystemError("Failed to run manager onAdd() listener.\n"+err)
}
})
//notify change in upper-manager (because data added)
this._change()
return false
}else{
if (!overwrite) throw new ODSystemError("Id '"+data.id.value+"' already exists in "+this.#debugname+" manager. Use 'overwrite:true' to allow overwriting!")
this.#data[existIndex] = data
if (this.#debug) this.#debug.debug("Added new "+this.#debugname+" to manager",[{key:"id",value:data.id.value},{key:"overwrite",value:"true"}])
//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)
}
})
})
//add listeners
this.#addListeners.forEach((cb) => {
try{
cb(data,true)
}catch(err){
throw new ODSystemError("Failed to run manager onAdd() listener.\n"+err)
}
})
//notify change in upper-manager (because data added)
this._change()
return true
}
}
/**Get data that matches the `ODId`. Returns the found data.*/
get(id:ODValidId): DataType|null {
const newId = new ODId(id)
const d = this.#data.find((a) => a.id.value == newId.value)
if (d) return d
else{
const redirect = this.redirects.list().find((redirect) => redirect.fromSource === newId.source)
if (!redirect) return null
else{
const redirectId = new ODId(redirect.toSource+":"+newId.identifier)
return this.get(redirectId)
}
}
}
/**Remove data that matches the `ODId`. Returns the removed data.*/
remove(id:ODValidId): DataType|null {
const newId = new ODId(id)
const index = this.#data.findIndex((a) => a.id.value == newId.value)
if (index < 0){
const redirect = this.redirects.list().find((redirect) => redirect.fromSource === newId.source)
if (!redirect){
if (this.#debug) this.#debug.debug("Removed "+this.#debugname+" from manager",[{key:"id",value:newId.value},{key:"found",value:"false"}])
return null
}else{
const redirectId = new ODId(redirect.toSource+":"+newId.identifier)
return this.remove(redirectId)
}
}
if (this.#debug) this.#debug.debug("Removed "+this.#debugname+" from manager",[{key:"id",value:newId.value},{key:"found",value:"true"}])
const data = this.#data.splice(index,1)[0]
//change listeners
data.changed(null)
//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)
const d = this.#data.find((a) => a.id.value == newId.value)
if (d) return true
else{
const redirect = this.redirects.list().find((redirect) => redirect.fromSource === newId.source)
if (!redirect) return false
else{
const redirectId = new ODId(redirect.toSource+":"+newId.identifier)
return this.exists(redirectId)
}
}
}
/**Get all data inside this manager*/
getAll(): DataType[] {
return [...this.#data]
}
/**Get all data that matches inside the filter function*/
getFiltered(predicate:(value:DataType, index:number, array:DataType[]) => unknown): DataType[] {
return this.#data.filter(predicate)
}
/**Get all data that matches the regex*/
getRegex(regex:RegExp): DataType[] {
return this.#data.filter((data) => regex.test(data.id.value))
}
/**Get the length of the data inside this manager*/
getLength(){
return this.#data.length
}
/**Get a list of all the ids inside this manager*/
getIds(): ODId[] {
return this.#data.map((d) => d.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())
})
}
}
/**## 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"
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"
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
+55
View File
@@ -0,0 +1,55 @@
///////////////////////////////////////
//CODE MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODValidId } from "./base"
import { ODDebugger } from "./console"
/**## ODCode `class`
* This is an open ticket code runner.
*
* It is just a function that will run just before the bot has started completely!
* This can be used for code that needs to run at startup, but isn't really time dependent.
*
* - It has an `id` for identification of the function
* - A `priority` to know when to execute this function (related to others)
*/
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.
*
* You will probably register a function/code in this class for something that doesn't really need to be timed.
*/
export class ODCodeManager extends ODManager<ODCode> {
constructor(debug:ODDebugger){
super(debug,"code")
}
/**Execute all functions or code. */
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)
}
}
}
}
+96
View File
@@ -0,0 +1,96 @@
///////////////////////////////////////
//CONFIG MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODSystemError, ODValidId } from "./base"
import nodepath from "path"
import { ODDebugger } from "./console"
/**## 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 will use this class to get/add a config file (`ODConfig`) in your plugin!
* @example
* //get ./config/general.json => ODConfig class
* const generalConfig = openticket.configs.get("openticket:general")
*
* //add a new config with id "test" => ./config/test.json
* const testConfig = new api.ODConfig("test","test.json")
* openticket.configs.add(testConfig)
*/
export class ODConfigManager extends ODManager<ODConfig> {
constructor(debug:ODDebugger){
super(debug,"config")
}
/**Add data to the manager. The id will be fetched from the data class! You can optionally select to overwrite existing data!
* @example
* //add a new config with id "test" => ./config/test.json
* const testConfig = new api.ODConfig("test","test.json")
* openticket.configs.add(testConfig)
*/
add(data:ODConfig, overwrite?:boolean): boolean {
return super.add(data,overwrite)
}
/**Get data that matches the `ODId`. Returns the found data.
* @example
* //get "./config/general.json" (ot-general) => ODConfig class
* const generalConfig = openticket.configs.get("openticket:general")
*/
get(id:ODValidId): ODConfig|null {
return super.get(id)
}
/**Remove data that matches the `ODId`. Returns the removed data.
* @example
* //remove the "test" config
* openticket.configs.remove("test") //returns null if non-existing
*/
remove(id:ODValidId): ODConfig|null {
return super.remove(id)
}
/**Check if data that matches the `ODId` exists. Returns a boolean.
* @example
* //check if "./config/general.json" (ot-general) exists => boolean
* const exists = openticket.configs.exists("openticket:general")
*/
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## 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 will only use this class if you want to create your own config implementation (e.g. `yml`, `xml`,...)!
*/
export class ODConfig extends ODManagerData {
/**The full path to this config with extension */
file: string = ""
/**An object/array of the entire config file! Variables inside it can be edited while the bot is running! */
data: any = undefined
}
/**## ODJsonConfig `class`
* This is an open ticket config helper.
* You will use this class to get & edit variables from the config files or to create your own 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 {
constructor(id:ODValidId, file:string, customPath?:string){
super(id)
try {
const filename = (file.endsWith(".json")) ? file : file+".json"
this.file = customPath ? nodepath.join("./",customPath,filename) : nodepath.join("./config/",filename)
this.data = customPath ? require(nodepath.join("../../../../",customPath,filename)) : require(nodepath.join("../../../../config",filename))
}catch{
throw new ODSystemError("config \""+nodepath.join("./",customPath ?? "",file)+"\" doesn't exist!")
}
}
}
+663
View File
@@ -0,0 +1,663 @@
///////////////////////////////////////
//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()}/${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
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){
message.render()
if (this.debugfile) this.debugfile.writeConsoleMessage(message)
this.history.push(message)
}else if (message instanceof ODError){
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)
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()}/${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 `[NODE]:`) */
writeNote(text:string){
this.#writeDebugFile("[NODE]: "+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("openticket:version").toString(true)
const usingSlashCommands: boolean = main.configs.get("openticket: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 will probably use this to customise or add stuff to the LiveStatus system.
* Access it in the global `openticket.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 "openticket.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
@@ -0,0 +1,348 @@
///////////////////////////////////////
//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(() => {
this.data.getAll().forEach((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(() => {
this.data.getAll().forEach((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
}
}
+316
View File
@@ -0,0 +1,316 @@
///////////////////////////////////////
//DATABASE MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, 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 will use this class to get/add a database (`ODDatabase`) in your plugin!
* @example
* //get ./database/ot-global.json => ODDatabase class
* const globalDB = openticket.databases.get("openticket:global")
*
* //add a new database with id "test" => ./database/idk-test.json
* const testDatabase = new api.ODDatabase("test","idk-test.json")
* openticket.databases.add(testDatabase)
*/
export class ODDatabaseManager extends ODManager<ODDatabase> {
constructor(debug:ODDebugger){
super(debug,"database")
}
/**Add data to the manager. The id will be fetched from the data class! You can optionally select to overwrite existing data!
* @example
* //add a new database with id "test" => ./database/idk-test.json
* const testDatabase = new api.ODDatabase("test","idk-test.json")
* openticket.databases.add(testDatabase)
*/
add(data:ODDatabase, overwrite?:boolean): boolean {
return super.add(data,overwrite)
}
/**Get data that matches the `ODId`. Returns the found data.
* @example
* //get ./database/ot-global.json => ODDatabase class
* const globalDB = openticket.databases.get("openticket:global")
*/
get(id:ODValidId): ODDatabase|null {
return super.get(id)
}
/**Remove data that matches the `ODId`. Returns the removed data.
* @example
* //remove the "test" database
* openticket.databases.remove("test") //returns null if non-existing
*/
remove(id:ODValidId): ODDatabase|null {
return super.remove(id)
}
/**Check if data that matches the `ODId` exists. Returns a boolean.
* @example
* //check if "./database/idk-test.json" (test) exists => boolean
* const exists = openticket.databases.exists("test")
*/
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
/**## 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 will only use this class if you want to create your own database implementation (e.g. `mongodb`, `mysql`,...)!
* @example
* class SomeDatabase extends ODDatabase {
* //override this method
* setData(category:string, key:string, value:ODValidJsonType): boolean {
* return false
* }
* //override this method
* getData(category:string, key:string): ODValidJsonType|undefined {
* return undefined
* }
* //override this method
* deleteData(category:string, key:string): boolean {
* return false
* }
* }
*/
export class ODDatabase extends ODManagerData {
/**The full path to this database with extension */
file: string = ""
/**Add/Overwrite a specific category & key in the database. Returns `true` when overwritten. */
set(category:string, key:string, value:ODValidJsonType): boolean {
return false
}
/**Get a specific category & key in the database */
get(category:string, key:string): ODValidJsonType|undefined {
return undefined
}
/**Delete a specific category & key in the database */
delete(category:string, key:string): boolean {
return false
}
/**Check if a specific category & key exists in the database */
exists(category:string, key:string): boolean {
return false
}
/**Get a specific category in the database */
getCategory(category:string): {key:string, value:ODValidJsonType}[]|undefined {
return undefined
}
/**Get all values in the database */
getAll(): 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 will only use this class if you want to create your own database or use an existing one!
* @example
* //get,set & delete data
* const data = database.getData("category","key") //data will be the value
* const didOverwrite = database.setData("category","key","value") //value can be any of the valid types
* const didExist = database.deleteData("category","key") //delete this value
* //You need an ODJsonDatabase class named "database" for this example to work!
*/
export class ODJsonDatabase extends ODDatabase {
constructor(id:ODValidId, file:string, customPath?:string){
super(id)
const filename = (file.endsWith(".json")) ? file : file+".json"
this.file = customPath ? nodepath.join("./",customPath,filename) : nodepath.join("./database/",filename)
//init file if it doesn't exist yet
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): 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): 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): 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): 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): {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(): ODJsonDatabaseStructure {
return this.#system.getData()
}
#system = {
/**Read parsed data from the json file */
getData: (): ODJsonDatabaseStructure => {
if (fs.existsSync(this.file)){
return JSON.parse(fs.readFileSync(this.file).toString())
}else{
fs.writeFileSync(this.file,"[]")
return []
}
},
/**Write parsed data to the json file */
setData: (data:ODJsonDatabaseStructure) => {
fs.writeFileSync(this.file,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)
const filename = (file.endsWith(".json")) ? file : file+".json"
this.file = customPath ? nodepath.join("./",customPath,filename) : nodepath.join("./database/",filename)
this.formatter = formatter
//init file if it doesn't exist yet
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): 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): 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): 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): 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): {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(): ODJsonDatabaseStructure {
return this.#system.getData()
}
#system = {
/**Read parsed data from the json file */
getData: (): ODJsonDatabaseStructure => {
if (fs.existsSync(this.file)){
return JSON.parse(fs.readFileSync(this.file).toString())
}else{
fs.writeFileSync(this.file,"[]")
return []
}
},
/**Write parsed data to the json file */
setData: (data:ODJsonDatabaseStructure) => {
fs.writeFileSync(this.file,this.formatter.stringify(data))
}
}
}
+319
View File
@@ -0,0 +1,319 @@
///////////////////////////////////////
//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 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 plugin events. */
pluginEventLoading:boolean,
/**Load the default open ticket flags. */
flagLoading:boolean,
/**Enable the default initializer for open ticket flags. */
flagInitiating:boolean,
/**Load the default open ticket configs. */
configLoading:boolean,
/**Load the default open ticket databases. */
databaseLoading:boolean,
/**Load the default open ticket sessions. */
sessionLoading:boolean,
/**Load the default open ticket languages. */
languageLoading: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,
/****[NOD 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 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,
/**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,
/**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,
/**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,
pluginLoading:true,
softPluginLoading:false,
pluginClassLoading:true,
pluginEventLoading:true,
flagLoading:true,
flagInitiating:true,
configLoading:true,
databaseLoading:true,
sessionLoading:true,
languageLoading:true,
languageSelection:true,
backupLanguage:"openticket:english",
languageList:["custom","english","dutch","portuguese","czech"],
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,
slashCommandLoading:true,
slashCommandRegistering:true,
forceSlashCommandRegistration:false,
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,
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,
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
@@ -0,0 +1,99 @@
///////////////////////////////////////
//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`
*
* You will probably not create this class yourself, but use it globaly instead!
* Check out the `openticket.events` class!
*/
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
@@ -0,0 +1,73 @@
///////////////////////////////////////
//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. */
init(){
this.getAll().forEach((flag) => {
flag.detectProcessParams(false)
})
}
}
+216
View File
@@ -0,0 +1,216 @@
///////////////////////////////////////
//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 succesfully.
*
* 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
}
}
+107
View File
@@ -0,0 +1,107 @@
///////////////////////////////////////
//LANGUAGE MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODSystemError, ODValidId } from "./base"
import nodepath from "path"
import { ODDebugger } from "./console"
export class ODLanguage extends ODManagerData {
file: string
data: any
metadata: {
otversion:string,
language:string,
translator:string,
lastedited:string
}|null = null
constructor(id:ODValidId, file:string, customPath?:string){
super(id)
this.file = file
try{
const filename = (file.endsWith(".json")) ? file : file+".json"
this.data = customPath ? require(nodepath.join("../../../../",customPath,filename)) : require(nodepath.join("../../../../languages",filename))
}catch{
throw new ODSystemError("[API ERROR] Language \""+file+"\" doesn't exist!")
}
if (this.data["_TRANSLATION"]) this.metadata = this.data["_TRANSLATION"]
}
}
export class ODLanguageManager extends ODManager<ODLanguage> {
current: ODLanguage|null = null
backup: ODLanguage|null = null
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
}
setCurrentLanguage(id:ODValidId){
this.current = this.get(id)
}
getCurrentLanguage(){
return (this.current) ? this.current : null
}
setBackupLanguage(id:ODValidId){
this.backup = this.get(id)
}
getBackupLanguage(){
return (this.backup) ? this.backup : null
}
getLanguageMetadata(frombackup?:boolean){
if (frombackup) return (this.backup) ? this.backup.metadata : null
return (this.current) ? this.current.metadata : null
}
getCurrentLanguageId(){
return (this.current) ? this.current.id.value : ""
}
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)
}
#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
}
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
}
}
+211
View File
@@ -0,0 +1,211 @@
///////////////////////////////////////
//PERMISSION MODULE
///////////////////////////////////////
import { ODId, ODValidId, ODManager, ODSystemError, ODManagerData } from "./base"
import * as discord from "discord.js"
import { ODDebugger } from "./console"
export type ODPermissionType = "member"|"support"|"moderator"|"admin"|"owner"|"developer"
export type ODPermissionScope = "global-user"|"channel-user"|"global-role"|"channel-role"
export interface ODPermissionResult {
type:ODPermissionType
scope:ODPermissionScope|"default"
level:ODPermissionLevel,
source:ODPermission|null
}
export enum ODPermissionLevel {
member,
support,
moderator,
admin,
owner,
developer
}
export class ODPermission extends ODManagerData {
readonly scope: ODPermissionScope
readonly permission: ODPermissionType
readonly value: discord.Role|discord.User
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
}
}
export interface ODPermissionSettings {
allowGlobalUserScope?:boolean,
allowGlobalRoleScope?:boolean,
allowChannelUserScope?:boolean,
allowChannelRoleScope?:boolean,
idRegex?:RegExp
}
export type ODPermissionCalculationCallback = (user:discord.User, channel?:discord.Channel|null, guild?:discord.Guild|null, settings?:ODPermissionSettings|null) => Promise<ODPermissionResult>
export class ODPermissionManager extends ODManager<ODPermission> {
#calculation: ODPermissionCalculationCallback|null
defaultResult: ODPermissionResult = {
level:ODPermissionLevel["member"],
scope:"default",
type:"member",
source:null
}
constructor(debug:ODDebugger, useDefaultCalculation?:boolean){
super(debug,"permission")
this.#calculation = useDefaultCalculation ? this.#defaultCalculation : null
}
setCalculation(calculation:ODPermissionCalculationCallback){
this.#calculation = calculation
}
setDefaultResult(result:ODPermissionResult){
this.defaultResult = 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")
}
}
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()")
}
async #defaultCalculation(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
const allowGlobalUserScope = (settings && typeof settings.allowGlobalUserScope != "undefined") ? settings.allowGlobalUserScope : true
const allowGlobalRoleScope = (settings && typeof settings.allowGlobalRoleScope != "undefined") ? settings.allowGlobalRoleScope : 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 guild.members.fetch(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
}
}
}
}
}
//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 guild.members.fetch(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}
}
}
+233
View File
@@ -0,0 +1,233 @@
///////////////////////////////////////
//PLUGIN MODULE
///////////////////////////////////////
import { ODId, ODManager, ODManagerData, ODSystemError, ODValidId, ODVersion } from "./base"
import nodepath from "path"
import { ODConsolePluginMessage, ODConsoleWarningMessage, ODDebugger } from "./console"
export interface ODUnknownCrashedPlugin {
name:string,
description:string
}
export class ODPluginManager extends ODManager<ODPlugin> {
events: ODPluginEventManager
classes: ODPluginClassManager
unknownCrashedPlugins: ODUnknownCrashedPlugin[] = []
constructor(debug:ODDebugger){
super(debug,"plugin")
this.events = new ODPluginEventManager(debug)
this.classes = new ODPluginClassManager(debug)
}
/**Check if a plugin has loaded successfully.*/
isPluginLoaded(id:ODValidId){
const newId = new ODId(id)
const plugin = this.get(newId)
return (plugin && plugin.executed)
}
}
export interface ODPluginData {
name:string,
id:string,
version:string,
startFile:string,
enabled:boolean,
priority:number,
events:string[]
npmDependencies:string[],
requiredPlugins:string[],
incompatiblePlugins:string[],
details:ODPluginDetails
}
export interface ODPluginDetails {
author:string,
shortDescription:string,
longDescription:string,
imageUrl:string,
projectUrl:string,
tags:string[]
}
export class ODPlugin extends ODManagerData {
dir: string
data: ODPluginData
name: string
priority: number
version: ODVersion
details: ODPluginDetails
enabled: boolean
executed: boolean
crashed: boolean
crashReason: null|"incompatible.plugin"|"missing.plugin"|"missing.dependency"|"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
getStartFile(){
return nodepath.join(this.dir,this.data.startFile)
}
/**Execute this plugin. Returns `false` on crash. */
async execute(debug:ODDebugger,force?:boolean): Promise<boolean> {
if ((this.enabled && !this.crashed) || force){
try{
await require(nodepath.join("../../../../plugins/",this.getStartFile()))
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
}
#checkDependency(id:string){
try{
require.resolve(id)
return true
}catch{
return false
}
}
dependenciesInstalled(){
const missing: string[] = []
this.data.npmDependencies.forEach((d) => {
if (!this.#checkDependency(d)){
missing.push(d)
}
})
return missing
}
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
}
}
export class ODPluginEvent extends ODManagerData {
listeners: Function[] = []
oncelisteners: Function[] = []
getCurrentListeners(){
const final: Function[] = []
this.oncelisteners.forEach((l) => final.push(l))
this.listeners.forEach((l) => final.push(l))
this.oncelisteners = []
return final
}
}
export class ODPluginEventManager extends ODManager<ODPluginEvent> {
#debug: ODDebugger
listenerLimit: number = 25
constructor(debug:ODDebugger){
super(debug,"plugin event")
this.#debug = debug
}
setListenerLimit(limit:number){
this.listenerLimit = limit
}
on(event:string, callback:Function){
const eventdata = this.get(event)
if (eventdata){
eventdata.listeners.push(callback)
if (eventdata.listeners.length > this.listenerLimit){
this.#debug.console.log(new ODConsoleWarningMessage("Possible plugin event memory leak detected!",[
{key:"event",value:event},
{key:"listeners",value:eventdata.listeners.length.toString()}
]))
}
}else{
throw new ODSystemError("unknown plugin event \""+event+"\"")
}
}
once(event:string, callback:Function){
const eventdata = this.get(event)
if (eventdata){
eventdata.oncelisteners.push(callback)
}else{
throw new ODSystemError("unknown plugin event \""+event+"\"")
}
}
wait(event:string): Promise<any[]> {
return new Promise((resolve,reject) => {
const eventdata = this.get(event)
if (eventdata){
eventdata.oncelisteners.push((...args:any) => {resolve(args)})
}else{
reject("unknown plugin event \""+event+"\"")
}
})
}
emit(event:string, params:any[]): Promise<void> {
return new Promise(async (resolve,reject) => {
const eventdata = this.get(event)
if (eventdata){
const listeners = eventdata.getCurrentListeners()
for (const listener of listeners){
try {
await listener(...params)
}catch(err){
process.emit("uncaughtException",err)
}
}
resolve()
}else{
reject("unknown plugin event \""+event+"\"")
}
})
}
}
export class ODPluginClassManager extends ODManager<ODManagerData> {
constructor(debug:ODDebugger){
super(debug,"plugin class")
}
}
+90
View File
@@ -0,0 +1,90 @@
///////////////////////////////////////
//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 will probably 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}
}
}
}
+884
View File
@@ -0,0 +1,884 @@
///////////////////////////////////////
//RESPONDER MODULE
///////////////////////////////////////
import { ODId, ODManager, ODValidId, ODSystemError, ODManagerData } from "./base"
import * as discord from "discord.js"
import { ODWorkerManager, ODWorkerCallback, ODWorker } from "./worker"
import { ODDebugger } from "./console"
import { ODClientManager, ODSlashCommand, ODTextCommand, ODTextCommandInteractionOption } from "./client"
import { ODDropdownData, ODMessageBuildResult, ODMessageBuildSentResult, ODModalBuildResult } from "./builder"
/**## ODResponderImplementation `class`
* This is an open ticket responder implementation.
*
* It is a basic implementation of the `ODWorkerManager` used by all `ODResponder` classes.
*
* This class can't be used stand-alone & needs to be extended from!
*/
export class ODResponderImplementation<Instance,Source extends string,Params> extends ODManagerData {
/**The manager that has all workers of this implementation */
workers: ODWorkerManager<Instance,Source,Params>
/**The `commandName` or `customId` needs to match this string or regex for this responder to be executed. */
match: string|RegExp
constructor(id:ODValidId, match:string|RegExp, callback?:ODWorkerCallback<Instance,Source,Params>, priority?:number, callbackId?:ODValidId){
super(id)
this.match = match
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 respond(instance:Instance, source:Source, params:Params): Promise<void> {
throw new ODSystemError("Tried to build an unimplemented ODResponderImplementation")
}
}
export type ODResponderTimeoutErrorCallback<Instance, Source extends "slash"|"text"|"button"|"dropdown"|"modal"|"other"> = (instance:Instance, source:Source) => void|Promise<void>
export class ODResponderManager {
commands: ODCommandResponderManager
buttons: ODButtonResponderManager
dropdowns: ODDropdownResponderManager
modals: ODModalResponderManager
constructor(debug:ODDebugger, client:ODClientManager){
this.commands = new ODCommandResponderManager(debug,"command responder",client)
this.buttons = new ODButtonResponderManager(debug,"button responder",client)
this.dropdowns = new ODDropdownResponderManager(debug,"dropdown responder",client)
this.modals = new ODModalResponderManager(debug,"modal responder",client)
}
}
export class ODCommandResponderManager extends ODManager<ODCommandResponder<"slash"|"text",any>> {
#client: ODClientManager
#timeoutErrorCallback: ODResponderTimeoutErrorCallback<ODCommandResponderInstance,"slash"|"text">|null = null
#timeoutMs: number|null = null
constructor(debug:ODDebugger, debugname:string, client:ODClientManager){
super(debug,debugname)
this.#client = client
}
/**Set the message to send when the response times out! */
setTimeoutErrorCallback(callback:ODResponderTimeoutErrorCallback<ODCommandResponderInstance,"slash"|"text">|null, ms:number|null){
this.#timeoutErrorCallback = callback
this.#timeoutMs = ms
}
add(data:ODCommandResponder<"slash"|"text",any>, overwrite?:boolean){
const res = super.add(data,overwrite)
//add the callback to the slash command manager
this.#client.slashCommands.onInteraction(data.match,(interaction,cmd) => {
const newData = this.get(data.id)
if (!newData) return
newData.respond(new ODCommandResponderInstance(interaction,cmd,this.#timeoutErrorCallback,this.#timeoutMs),"slash",{})
})
//add the callback to the text command manager
this.#client.textCommands.onInteraction(data.prefix,data.match,(interaction,cmd,options) => {
const newData = this.get(data.id)
if (!newData) return
newData.respond(new ODCommandResponderInstance(interaction,cmd,this.#timeoutErrorCallback,this.#timeoutMs,options),"text",{})
})
return res
}
}
export class ODCommandResponderInstanceOptions {
#interaction:discord.ChatInputCommandInteraction|discord.Message
#cmd:ODSlashCommand|ODTextCommand
#options: ODTextCommandInteractionOption[]
constructor(interaction:discord.ChatInputCommandInteraction|discord.Message, cmd:ODSlashCommand|ODTextCommand, options?:ODTextCommandInteractionOption[]){
this.#interaction = interaction
this.#cmd = cmd
this.#options = options ?? []
}
getString(name:string,required:true): string
getString(name:string,required:false): string|null
getString(name:string,required:boolean){
if (this.#interaction instanceof discord.ChatInputCommandInteraction){
try {
return this.#interaction.options.getString(name,required)
}catch{
throw new ODSystemError("ODCommandResponderInstanceOptions:getString() slash command option not found!")
}
}else if (this.#interaction instanceof discord.Message){
const opt = this.#options.find((opt) => opt.type == "string" && opt.name == name)
if (opt && typeof opt.value == "string") return opt.value
else return null
}else return null
}
getBoolean(name:string,required:true): boolean
getBoolean(name:string,required:false): boolean|null
getBoolean(name:string,required:boolean){
if (this.#interaction instanceof discord.ChatInputCommandInteraction){
try {
return this.#interaction.options.getBoolean(name,required)
}catch{
throw new ODSystemError("ODCommandResponderInstanceOptions:getBoolean() slash command option not found!")
}
}else if (this.#interaction instanceof discord.Message){
const opt = this.#options.find((opt) => opt.type == "boolean" && opt.name == name)
if (opt && typeof opt.value == "boolean") return opt.value
else return null
}else return null
}
getNumber(name:string,required:true): number
getNumber(name:string,required:false): number|null
getNumber(name:string,required:boolean){
if (this.#interaction instanceof discord.ChatInputCommandInteraction){
try {
return this.#interaction.options.getNumber(name,required)
}catch{
throw new ODSystemError("ODCommandResponderInstanceOptions:getNumber() slash command option not found!")
}
}else if (this.#interaction instanceof discord.Message){
const opt = this.#options.find((opt) => opt.type == "number" && opt.name == name)
if (opt && typeof opt.value == "number") return opt.value
else return null
}else return null
}
getChannel(name:string,required:true): discord.TextChannel|discord.VoiceChannel|discord.StageChannel|discord.NewsChannel|discord.MediaChannel|discord.ForumChannel|discord.CategoryChannel
getChannel(name:string,required:false): discord.TextChannel|discord.VoiceChannel|discord.StageChannel|discord.NewsChannel|discord.MediaChannel|discord.ForumChannel|discord.CategoryChannel|null
getChannel(name:string,required:boolean){
if (this.#interaction instanceof discord.ChatInputCommandInteraction){
try {
return this.#interaction.options.getChannel(name,required)
}catch{
throw new ODSystemError("ODCommandResponderInstanceOptions:getChannel() slash command option not found!")
}
}else if (this.#interaction instanceof discord.Message){
const opt = this.#options.find((opt) => opt.type == "channel" && opt.name == name)
if (opt && (opt.value instanceof discord.TextChannel || opt.value instanceof discord.VoiceChannel || opt.value instanceof discord.StageChannel || opt.value instanceof discord.NewsChannel || opt.value instanceof discord.MediaChannel || opt.value instanceof discord.ForumChannel || opt.value instanceof discord.CategoryChannel)) return opt.value
else return null
}else return null
}
getRole(name:string,required:true): discord.Role
getRole(name:string,required:false): discord.Role|null
getRole(name:string,required:boolean){
if (this.#interaction instanceof discord.ChatInputCommandInteraction){
try {
return this.#interaction.options.getRole(name,required)
}catch{
throw new ODSystemError("ODCommandResponderInstanceOptions:getRole() slash command option not found!")
}
}else if (this.#interaction instanceof discord.Message){
const opt = this.#options.find((opt) => opt.type == "role" && opt.name == name)
if (opt && opt.value instanceof discord.Role) return opt.value
else return null
}else return null
}
getUser(name:string,required:true): discord.User
getUser(name:string,required:false): discord.User|null
getUser(name:string,required:boolean){
if (this.#interaction instanceof discord.ChatInputCommandInteraction){
try {
return this.#interaction.options.getUser(name,required)
}catch{
throw new ODSystemError("ODCommandResponderInstanceOptions:getUser() slash command option not found!")
}
}else if (this.#interaction instanceof discord.Message){
const opt = this.#options.find((opt) => opt.type == "user" && opt.name == name)
if (opt && opt.value instanceof discord.User) return opt.value
else return null
}else return null
}
getGuildMember(name:string,required:true): discord.GuildMember
getGuildMember(name:string,required:false): discord.GuildMember|null
getGuildMember(name:string,required:boolean){
if (this.#interaction instanceof discord.ChatInputCommandInteraction){
try {
const member = this.#interaction.options.getMember(name)
if (!member && required) throw new ODSystemError("ODCommandResponderInstanceOptions:getGuildMember() slash command option not found!")
return member
}catch{
throw new ODSystemError("ODCommandResponderInstanceOptions:getGuildMember() slash command option not found!")
}
}else if (this.#interaction instanceof discord.Message){
const opt = this.#options.find((opt) => opt.type == "guildmember" && opt.name == name)
if (opt && opt.value instanceof discord.GuildMember) return opt.value
else return null
}else return null
}
getMentionable(name:string,required:true): discord.User|discord.Role
getMentionable(name:string,required:false): discord.User|discord.Role|null
getMentionable(name:string,required:boolean){
if (this.#interaction instanceof discord.ChatInputCommandInteraction){
try {
return this.#interaction.options.getMentionable(name,required)
}catch{
throw new ODSystemError("ODCommandResponderInstanceOptions:getGuildMember() slash command option not found!")
}
}else if (this.#interaction instanceof discord.Message){
const opt = this.#options.find((opt) => opt.type == "mentionable" && opt.name == name)
if (opt && (opt.value instanceof discord.User || opt.value instanceof discord.Role)) return opt.value
else return null
}else return null
}
getSubGroup(): string|null
getSubGroup(){
if (this.#interaction instanceof discord.ChatInputCommandInteraction){
try {
return this.#interaction.options.getSubcommandGroup(true)
}catch{
throw new ODSystemError("ODCommandResponderInstanceOptions:getSubGroup() slash command option not found!")
}
}else if (this.#interaction instanceof discord.Message && this.#cmd instanceof ODTextCommand){
//0: name, 1:sub/group, 2:sub
const splittedName: string[] = this.#cmd.builder.name.split(" ")
return splittedName[1] ?? null
}else return null
}
getSubCommand(): string|null
getSubCommand(){
if (this.#interaction instanceof discord.ChatInputCommandInteraction){
try {
return this.#interaction.options.getSubcommand(true)
}catch{
throw new ODSystemError("ODCommandResponderInstanceOptions:getSubCommand() slash command option not found!")
}
}else if (this.#interaction instanceof discord.Message && this.#cmd instanceof ODTextCommand){
//0: name, 1:sub/group, 2:sub
const splittedName: string[] = this.#cmd.builder.name.split(" ")
//return the second subcommand when there is a subgroup
if (splittedName.length > 2){
return splittedName[2] ?? null
}else return splittedName[1] ?? null
}else return null
}
}
export class ODCommandResponderInstance {
interaction:discord.ChatInputCommandInteraction|discord.Message
cmd:ODSlashCommand|ODTextCommand
type: "message"|"interaction"
didReply: boolean = false
options: ODCommandResponderInstanceOptions
user: discord.User
member: discord.GuildMember|null
guild: discord.Guild|null
channel: discord.TextBasedChannel
constructor(interaction:discord.ChatInputCommandInteraction|discord.Message, cmd:ODSlashCommand|ODTextCommand, errorCallback:ODResponderTimeoutErrorCallback<ODCommandResponderInstance,"slash"|"text">|null, timeoutMs:number|null, options?:ODTextCommandInteractionOption[]){
if (!interaction.channel) throw new ODSystemError("ODCommandResponderInstance: Unable to find interaction channel!")
this.interaction = interaction
this.cmd = cmd
this.type = (interaction instanceof discord.Message) ? "message" : "interaction"
this.options = new ODCommandResponderInstanceOptions(interaction,cmd,options)
this.user = (interaction instanceof discord.Message) ? interaction.author : interaction.user
this.member = (interaction.member instanceof discord.GuildMember) ? interaction.member : null
this.guild = interaction.guild
this.channel = interaction.channel
setTimeout(async () => {
if (!this.didReply){
try {
if (!errorCallback){
this.reply({id:new ODId("looks-like-we-got-an-error-here"), ephemeral:true, message:{
content:":x: **Something went wrong while replying to this command!**"
}})
}else{
await errorCallback(this,(this.type == "interaction") ? "slash" : "text")
}
}catch(err){
process.emit("uncaughtException",err)
}
}
},timeoutMs ?? 2500)
}
async reply(msg:ODMessageBuildResult): Promise<ODMessageBuildSentResult<boolean>> {
try {
if (this.type == "interaction" && this.interaction instanceof discord.ChatInputCommandInteraction){
if (this.interaction.replied || this.interaction.deferred){
const sent = await this.interaction.editReply(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:sent}
}else{
const sent = await this.interaction.reply(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:await sent.fetch()}
}
}else if (this.type == "message" && this.interaction instanceof discord.Message){
const sent = await this.interaction.channel.send(msg.message)
this.didReply = true
return {success:true,message:sent}
}else return {success:false,message:null}
}catch{
return {success:false,message:null}
}
}
async defer(ephemeral:boolean){
if (this.type != "interaction" || !(this.interaction instanceof discord.ChatInputCommandInteraction)) return false
if (this.interaction.deferred) return false
await this.interaction.deferReply({ephemeral})
this.didReply = true
return true
}
async modal(modal:ODModalBuildResult){
if (this.type != "interaction" || !(this.interaction instanceof discord.ChatInputCommandInteraction)) return false
this.interaction.showModal(modal.modal)
this.didReply = true
return true
}
}
export class ODCommandResponder<Source extends "slash"|"text",Params> extends ODResponderImplementation<ODCommandResponderInstance,Source,Params> {
/**The prefix of the text command needs to match this */
prefix: string
constructor(id:ODValidId, prefix:string, match:string|RegExp, callback?:ODWorkerCallback<ODCommandResponderInstance,Source,Params>, priority?:number, callbackId?:ODValidId){
super(id,match,callback,priority,callbackId)
this.prefix = prefix
}
/**Respond to this command */
async respond(instance:ODCommandResponderInstance, source:Source, params:Params){
//wait for workers to finish
await this.workers.executeWorkers(instance,source,params)
}
}
export class ODButtonResponderManager extends ODManager<ODButtonResponder<"button",any>> {
#client: ODClientManager
#timeoutErrorCallback: ODResponderTimeoutErrorCallback<ODButtonResponderInstance,"button">|null = null
#timeoutMs: number|null = null
#listeners: ((interaction:discord.ButtonInteraction) => void)[] = []
constructor(debug:ODDebugger, debugname:string, client:ODClientManager){
super(debug,debugname)
this.#client = client
this.#client.client.on("interactionCreate",(interaction) => {
if (!interaction.isButton()) return
this.#listeners.forEach((cb) => cb(interaction))
})
}
/**Set the message to send when the response times out! */
setTimeoutErrorCallback(callback:ODResponderTimeoutErrorCallback<ODButtonResponderInstance,"button">|null, ms:number|null){
this.#timeoutErrorCallback = callback
this.#timeoutMs = ms
}
add(data:ODButtonResponder<"button",any>, overwrite?:boolean){
const res = super.add(data,overwrite)
this.#listeners.push((interaction) => {
const newData = this.get(data.id)
if (!newData) return
if ((typeof newData.match == "string") ? interaction.customId == newData.match : newData.match.test(interaction.customId)) newData.respond(new ODButtonResponderInstance(interaction,this.#timeoutErrorCallback,this.#timeoutMs),"button",{})
})
return res
}
}
export class ODButtonResponderInstance {
interaction:discord.ButtonInteraction
didReply: boolean = false
user: discord.User
member: discord.GuildMember|null
guild: discord.Guild|null
channel: discord.TextBasedChannel
message: discord.Message
constructor(interaction:discord.ButtonInteraction, errorCallback:ODResponderTimeoutErrorCallback<ODButtonResponderInstance,"button">|null, timeoutMs:number|null){
if (!interaction.channel) throw new ODSystemError("ODButtonResponderInstance: Unable to find interaction channel!")
this.interaction = interaction
this.user = interaction.user
this.member = (interaction.member instanceof discord.GuildMember) ? interaction.member : null
this.guild = interaction.guild
this.channel = interaction.channel
this.message = interaction.message
setTimeout(async () => {
if (!this.didReply){
try {
if (!errorCallback){
this.reply({id:new ODId("looks-like-we-got-an-error-here"), ephemeral:true, message:{
content:":x: **Something went wrong while replying to this button!**"
}})
}else{
await errorCallback(this,"button")
}
}catch(err){
process.emit("uncaughtException",err)
}
}
},timeoutMs ?? 2500)
}
async reply(msg:ODMessageBuildResult): Promise<ODMessageBuildSentResult<boolean>> {
try{
if (this.interaction.replied || this.interaction.deferred){
const sent = await this.interaction.editReply(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:sent}
}else{
const sent = await this.interaction.reply(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:await sent.fetch()}
}
}catch{
return {success:false,message:null}
}
}
async update(msg:ODMessageBuildResult): Promise<ODMessageBuildSentResult<boolean>> {
try{
if (this.interaction.replied || this.interaction.deferred){
const sent = await this.interaction.editReply(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:await sent.fetch()}
}else{
const sent = await this.interaction.update(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:await sent.fetch()}
}
}catch{
return {success:false,message:null}
}
}
async defer(type:"reply"|"update", ephemeral:boolean){
if (this.interaction.deferred) return false
if (type == "reply"){
await this.interaction.deferReply({ephemeral})
}else{
await this.interaction.deferUpdate()
}
this.didReply = true
return true
}
async modal(modal:ODModalBuildResult){
this.interaction.showModal(modal.modal)
this.didReply = true
return true
}
getMessageComponent(type:"button",id:string|RegExp): discord.ButtonComponent|null
getMessageComponent(type:"string-dropdown",id:string|RegExp): discord.StringSelectMenuComponent|null
getMessageComponent(type:"user-dropdown",id:string|RegExp): discord.UserSelectMenuComponent|null
getMessageComponent(type:"channel-dropdown",id:string|RegExp): discord.ChannelSelectMenuComponent|null
getMessageComponent(type:"role-dropdown",id:string|RegExp): discord.RoleSelectMenuComponent|null
getMessageComponent(type:"mentionable-dropdown",id:string|RegExp): discord.MentionableSelectMenuComponent|null
getMessageComponent(type:"button"|"string-dropdown"|"user-dropdown"|"channel-dropdown"|"role-dropdown"|"mentionable-dropdown", id:string|RegExp): discord.ButtonComponent|discord.StringSelectMenuComponent|discord.RoleSelectMenuComponent|discord.ChannelSelectMenuComponent|discord.MentionableSelectMenuComponent|discord.UserSelectMenuComponent|null {
let result: discord.ButtonComponent|discord.StringSelectMenuComponent|discord.RoleSelectMenuComponent|discord.ChannelSelectMenuComponent|discord.MentionableSelectMenuComponent|discord.UserSelectMenuComponent|null = null
this.message.components.forEach((row) => {
row.components.forEach((component) => {
if (type == "button" && component.type == discord.ComponentType.Button && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
else if (type == "string-dropdown" && component.type == discord.ComponentType.StringSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
else if (type == "user-dropdown" && component.type == discord.ComponentType.UserSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
else if (type == "channel-dropdown" && component.type == discord.ComponentType.ChannelSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
else if (type == "role-dropdown" && component.type == discord.ComponentType.RoleSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
else if (type == "mentionable-dropdown" && component.type == discord.ComponentType.MentionableSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
})
})
return result
}
getMessageEmbed(): discord.Embed|null {
return this.message.embeds[0] ?? null
}
}
export class ODButtonResponder<Source extends string,Params> extends ODResponderImplementation<ODButtonResponderInstance,Source,Params> {
/**Respond to this button */
async respond(instance:ODButtonResponderInstance, source:Source, params:Params){
//wait for workers to finish
await this.workers.executeWorkers(instance,source,params)
}
}
export class ODDropdownResponderManager extends ODManager<ODDropdownResponder<"dropdown",any>> {
#client: ODClientManager
#timeoutErrorCallback: ODResponderTimeoutErrorCallback<ODDropdownResponderInstance,"dropdown">|null = null
#timeoutMs: number|null = null
#listeners: ((interaction:discord.AnySelectMenuInteraction) => void)[] = []
constructor(debug:ODDebugger, debugname:string, client:ODClientManager){
super(debug,debugname)
this.#client = client
this.#client.client.on("interactionCreate",(interaction) => {
if (!interaction.isAnySelectMenu()) return
this.#listeners.forEach((cb) => cb(interaction))
})
}
/**Set the message to send when the response times out! */
setTimeoutErrorCallback(callback:ODResponderTimeoutErrorCallback<ODDropdownResponderInstance,"dropdown">|null, ms:number|null){
this.#timeoutErrorCallback = callback
this.#timeoutMs = ms
}
add(data:ODDropdownResponder<"dropdown",any>, overwrite?:boolean){
const res = super.add(data,overwrite)
this.#listeners.push((interaction) => {
const newData = this.get(data.id)
if (!newData) return
if ((typeof newData.match == "string") ? interaction.customId == newData.match : newData.match.test(interaction.customId)) newData.respond(new ODDropdownResponderInstance(interaction,this.#timeoutErrorCallback,this.#timeoutMs),"dropdown",{})
})
return res
}
}
export class ODDropdownResponderInstanceValues {
#interaction:discord.AnySelectMenuInteraction
#type: ODDropdownData["type"]
constructor(interaction:discord.AnySelectMenuInteraction, type:ODDropdownData["type"]){
this.#interaction = interaction
this.#type = type
if (interaction.isChannelSelectMenu()){
interaction.values
}
}
getStringValues(): string[] {
try {
return this.#interaction.values
}catch{
throw new ODSystemError("ODDropdownResponderInstanceValues:getStringValues() invalid values!")
}
}
async getRoleValues(): Promise<discord.Role[]> {
if (this.#type != "role") throw new ODSystemError("ODDropdownResponderInstanceValues:getRoleValues() dropdown type isn't role!")
try {
const result: discord.Role[] = []
for (const id of this.#interaction.values){
if (!this.#interaction.guild) break
const role = await this.#interaction.guild.roles.fetch(id)
if (role) result.push(role)
}
return result
}catch{
throw new ODSystemError("ODDropdownResponderInstanceValues:getRoleValues() invalid values!")
}
}
async getUserValues(): Promise<discord.User[]> {
if (this.#type != "role") throw new ODSystemError("ODDropdownResponderInstanceValues:getUserValues() dropdown type isn't user!")
try {
const result: discord.User[] = []
for (const id of this.#interaction.values){
const user = await this.#interaction.client.users.fetch(id)
if (user) result.push(user)
}
return result
}catch{
throw new ODSystemError("ODDropdownResponderInstanceValues:getUserValues() invalid values!")
}
}
async getChannelValues(): Promise<discord.GuildBasedChannel[]> {
if (this.#type != "role") throw new ODSystemError("ODDropdownResponderInstanceValues:getChannelValues() dropdown type isn't channel!")
try {
const result: discord.GuildBasedChannel[] = []
for (const id of this.#interaction.values){
if (!this.#interaction.guild) break
const guild = await this.#interaction.guild.channels.fetch(id)
if (guild) result.push(guild)
}
return result
}catch{
throw new ODSystemError("ODDropdownResponderInstanceValues:getChannelValues() invalid values!")
}
}
}
export class ODDropdownResponderInstance {
interaction:discord.AnySelectMenuInteraction
didReply: boolean = false
type: ODDropdownData["type"]
values: ODDropdownResponderInstanceValues
user: discord.User
member: discord.GuildMember|null
guild: discord.Guild|null
channel: discord.TextBasedChannel
message: discord.Message
constructor(interaction:discord.AnySelectMenuInteraction, errorCallback:ODResponderTimeoutErrorCallback<ODDropdownResponderInstance,"dropdown">|null, timeoutMs:number|null){
if (!interaction.channel) throw new ODSystemError("ODDropdownResponderInstance: Unable to find interaction channel!")
this.interaction = interaction
if (interaction.isStringSelectMenu()){
this.type = "string"
}else if (interaction.isRoleSelectMenu()){
this.type = "role"
}else if (interaction.isUserSelectMenu()){
this.type = "user"
}else if (interaction.isChannelSelectMenu()){
this.type = "channel"
}else if (interaction.isMentionableSelectMenu()){
this.type = "mentionable"
}else throw new ODSystemError("ODDropdownResponderInstance: invalid dropdown type!")
this.values = new ODDropdownResponderInstanceValues(interaction,this.type)
this.user = interaction.user
this.member = (interaction.member instanceof discord.GuildMember) ? interaction.member : null
this.guild = interaction.guild
this.channel = interaction.channel
this.message = interaction.message
setTimeout(async () => {
if (!this.didReply){
try {
if (!errorCallback){
this.reply({id:new ODId("looks-like-we-got-an-error-here"), ephemeral:true, message:{
content:":x: **Something went wrong while replying to this dropdown!**"
}})
}else{
await errorCallback(this,"dropdown")
}
}catch(err){
process.emit("uncaughtException",err)
}
}
},timeoutMs ?? 2500)
}
async reply(msg:ODMessageBuildResult): Promise<ODMessageBuildSentResult<boolean>> {
try {
if (this.interaction.replied || this.interaction.deferred){
const sent = await this.interaction.editReply(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:sent}
}else{
const sent = await this.interaction.reply(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:await sent.fetch()}
}
}catch{
return {success:false,message:null}
}
}
async update(msg:ODMessageBuildResult): Promise<ODMessageBuildSentResult<boolean>> {
try{
if (this.interaction.replied || this.interaction.deferred){
const sent = await this.interaction.editReply(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:await sent.fetch()}
}else{
const sent = await this.interaction.update(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:await sent.fetch()}
}
}catch{
return {success:false,message:null}
}
}
async defer(type:"reply"|"update", ephemeral:boolean){
if (this.interaction.deferred) return false
if (type == "reply"){
await this.interaction.deferReply({ephemeral})
}else{
await this.interaction.deferUpdate()
}
this.didReply = true
return true
}
async modal(modal:ODModalBuildResult){
this.interaction.showModal(modal.modal)
this.didReply = true
return true
}
getMessageComponent(type:"button",id:string|RegExp): discord.ButtonComponent|null
getMessageComponent(type:"string-dropdown",id:string|RegExp): discord.StringSelectMenuComponent|null
getMessageComponent(type:"user-dropdown",id:string|RegExp): discord.UserSelectMenuComponent|null
getMessageComponent(type:"channel-dropdown",id:string|RegExp): discord.ChannelSelectMenuComponent|null
getMessageComponent(type:"role-dropdown",id:string|RegExp): discord.RoleSelectMenuComponent|null
getMessageComponent(type:"mentionable-dropdown",id:string|RegExp): discord.MentionableSelectMenuComponent|null
getMessageComponent(type:"button"|"string-dropdown"|"user-dropdown"|"channel-dropdown"|"role-dropdown"|"mentionable-dropdown", id:string|RegExp): discord.ButtonComponent|discord.StringSelectMenuComponent|discord.RoleSelectMenuComponent|discord.ChannelSelectMenuComponent|discord.MentionableSelectMenuComponent|discord.UserSelectMenuComponent|null {
let result: discord.ButtonComponent|discord.StringSelectMenuComponent|discord.RoleSelectMenuComponent|discord.ChannelSelectMenuComponent|discord.MentionableSelectMenuComponent|discord.UserSelectMenuComponent|null = null
this.message.components.forEach((row) => {
row.components.forEach((component) => {
if (type == "button" && component.type == discord.ComponentType.Button && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
else if (type == "string-dropdown" && component.type == discord.ComponentType.StringSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
else if (type == "user-dropdown" && component.type == discord.ComponentType.UserSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
else if (type == "channel-dropdown" && component.type == discord.ComponentType.ChannelSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
else if (type == "role-dropdown" && component.type == discord.ComponentType.RoleSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
else if (type == "mentionable-dropdown" && component.type == discord.ComponentType.MentionableSelect && component.customId && ((typeof id == "string") ? component.customId == id : id.test(component.customId))) result = component
})
})
return result
}
getMessageEmbed(): discord.Embed|null {
return this.message.embeds[0] ?? null
}
}
export class ODDropdownResponder<Source extends string,Params> extends ODResponderImplementation<ODDropdownResponderInstance,Source,Params> {
/**Respond to this dropdown */
async respond(instance:ODDropdownResponderInstance, source:Source, params:Params){
//wait for workers to finish
await this.workers.executeWorkers(instance,source,params)
}
}
export class ODModalResponderManager extends ODManager<ODModalResponder<"modal",any>> {
#client: ODClientManager
#timeoutErrorCallback: ODResponderTimeoutErrorCallback<ODModalResponderInstance,"modal">|null = null
#timeoutMs: number|null = null
#listeners: ((interaction:discord.ModalSubmitInteraction) => void)[] = []
constructor(debug:ODDebugger, debugname:string, client:ODClientManager){
super(debug,debugname)
this.#client = client
this.#client.client.on("interactionCreate",(interaction) => {
if (!interaction.isModalSubmit()) return
this.#listeners.forEach((cb) => cb(interaction))
})
}
/**Set the message to send when the response times out! */
setTimeoutErrorCallback(callback:ODResponderTimeoutErrorCallback<ODModalResponderInstance,"modal">|null, ms:number|null){
this.#timeoutErrorCallback = callback
this.#timeoutMs = ms
}
add(data:ODModalResponder<"modal",any>, overwrite?:boolean){
const res = super.add(data,overwrite)
this.#listeners.push((interaction) => {
const newData = this.get(data.id)
if (!newData) return
if ((typeof newData.match == "string") ? interaction.customId == newData.match : newData.match.test(interaction.customId)) newData.respond(new ODModalResponderInstance(interaction,this.#timeoutErrorCallback,this.#timeoutMs),"modal",{})
})
return res
}
}
export class ODModalResponderInstanceValues {
#interaction:discord.ModalSubmitInteraction
constructor(interaction:discord.ModalSubmitInteraction){
this.#interaction = interaction
}
getTextField(name:string,required:true): string
getTextField(name:string,required:false): string|null
getTextField(name:string,required:boolean){
try {
const data = this.#interaction.fields.getField(name,discord.ComponentType.TextInput)
if (!data && required) throw new ODSystemError("ODModalResponderInstanceValues:getTextField() field not found!")
return (data) ? data.value : null
}catch{
throw new ODSystemError("ODModalResponderInstanceValues:getTextField() field not found!")
}
}
}
export class ODModalResponderInstance {
interaction:discord.ModalSubmitInteraction
didReply: boolean = false
values: ODModalResponderInstanceValues
user: discord.User
member: discord.GuildMember|null
guild: discord.Guild|null
channel: discord.TextBasedChannel|null
constructor(interaction:discord.ModalSubmitInteraction, errorCallback:ODResponderTimeoutErrorCallback<ODModalResponderInstance,"modal">|null, timeoutMs:number|null){
this.interaction = interaction
this.values = new ODModalResponderInstanceValues(interaction)
this.user = interaction.user
this.member = (interaction.member instanceof discord.GuildMember) ? interaction.member : null
this.guild = interaction.guild
this.channel = interaction.channel
setTimeout(async () => {
if (!this.didReply){
try {
if (!errorCallback){
this.reply({id:new ODId("looks-like-we-got-an-error-here"), ephemeral:true, message:{
content:":x: **Something went wrong while replying to this modal!**"
}})
}else{
await errorCallback(this,"modal")
}
}catch(err){
process.emit("uncaughtException",err)
}
}
},timeoutMs ?? 2500)
}
async reply(msg:ODMessageBuildResult): Promise<ODMessageBuildSentResult<boolean>> {
try{
if (this.interaction.replied || this.interaction.deferred){
const sent = await this.interaction.editReply(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:sent}
}else{
const sent = await this.interaction.reply(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:await sent.fetch()}
}
}catch{
return {success:false,message:null}
}
}
async update(msg:ODMessageBuildResult): Promise<ODMessageBuildSentResult<boolean>> {
try{
if (this.interaction.replied || this.interaction.deferred){
const sent = await this.interaction.editReply(Object.assign(msg.message,{ephemeral:msg.ephemeral}))
this.didReply = true
return {success:true,message:await sent.fetch()}
}else throw new ODSystemError()
}catch{
return {success:false,message:null}
}
}
async defer(type:"reply"|"update", ephemeral:boolean){
if (this.interaction.deferred) return false
if (type == "reply"){
await this.interaction.deferReply({ephemeral})
}else{
await this.interaction.deferUpdate()
}
this.didReply = true
return true
}
}
export class ODModalResponder<Source extends string,Params> extends ODResponderImplementation<ODModalResponderInstance,Source,Params> {
/**Respond to this modal */
async respond(instance:ODModalResponderInstance, source:Source, params:Params){
//wait for workers to finish
await this.workers.executeWorkers(instance,source,params)
}
}
+155
View File
@@ -0,0 +1,155 @@
///////////////////////////////////////
//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)
}
}
+219
View File
@@ -0,0 +1,219 @@
///////////////////////////////////////
//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"
export type ODStartScreenComponentRenderCallback = (location:number) => string|Promise<string>
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++
}
}
}
export class ODStartScreenComponent extends ODManagerData {
priority: number
renderBefore: ODStartScreenComponentRenderCallback|null = null
render: ODStartScreenComponentRenderCallback
renderAfter: ODStartScreenComponentRenderCallback|null = null
constructor(id:ODValidId, priority:number, render:ODStartScreenComponentRenderCallback){
super(id)
this.priority = priority
this.render = render
}
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 : "")
}
}
export interface ODStartScreenProperty {
key:string,
value:string
}
export class ODStartScreenLogoComponent extends ODStartScreenComponent {
logo: string[]
topPadding: boolean
bottomPadding: boolean
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"
}
}
export interface ODStartScreenHeaderAlignmentSettings {
align:"center"|"left"|"right",
width:number|ODStartScreenComponent
}
export class ODStartScreenHeaderComponent extends ODStartScreenComponent {
properties: ODStartScreenProperty[]
spacer: string
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
}
}
export class ODStartScreenCategoryComponent extends ODStartScreenComponent {
name: string
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
}
}
export class ODStartScreenPropertiesCategoryComponent extends ODStartScreenCategoryComponent {
properties: ODStartScreenProperty[]
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"
}
}
export class ODStartScreenFlagsCategoryComponent extends ODStartScreenCategoryComponent {
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
}
}
export class ODStartScreenPluginsCategoryComponent extends ODStartScreenCategoryComponent {
plugins: ODPlugin[]
unknownCrashedPlugins: ODUnknownCrashedPlugin[]
constructor(id:ODValidId, priority:number, plugins:ODPlugin[], unknownCrashedPlugins:ODUnknownCrashedPlugin[]){
super(id,priority,"plugins",() => {
const renderedPlugins = this.plugins.sort((a,b) => b.priority-a.priority).map((plugin) => {
if (plugin.enabled && plugin.executed) return ansis.green("✅ ["+plugin.name+"] "+plugin.details.shortDescription)
else if (plugin.enabled && plugin.crashed) return ansis.red("❌ ["+plugin.name+"] "+plugin.details.shortDescription)
else return ansis.gray("💤 ["+plugin.name+"] "+plugin.details.shortDescription)
})
const renderedUnknownPlugins = unknownCrashedPlugins.map((plugin) => ansis.red("❌ ["+plugin.name+"] "+plugin.description))
return [...renderedPlugins,...renderedUnknownPlugins].join("\n")
},false)
this.plugins = plugins
this.unknownCrashedPlugins = unknownCrashedPlugins
}
}
export class ODStartScreenLiveStatusCategoryComponent extends ODStartScreenCategoryComponent {
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
}
}
export class ODStartScreenLogCategoryComponent extends ODStartScreenCategoryComponent {
constructor(id:ODValidId, priority:number){
super(id,priority,"logs",() => "",true)
}
}
+212
View File
@@ -0,0 +1,212 @@
///////////////////////////////////////
//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"
export type ODValidStatValue = string|number|boolean
export type ODStatsManagerInitCallback = (database:ODJsonDatabaseStructure, deletables:ODJsonDatabaseStructure) => void|Promise<void>
export type ODStatScopeSetMode = "set"|"increase"|"decrease"
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
}
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)
}
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 = []
this.database.getAll().forEach((data) => {
if (!validCategories.includes(data.category)) deletableStats.push(data)
})
//do additional deletion
for (const cb of this.#initListeners){
await cb(this.database.getAll(),deletableStats)
}
//delete all deletable stats
deletableStats.forEach((data) => {
if (!this.database) return
this.database.delete(data.category,data.key)
})
}
reset(){
if (!this.database) return
this.database.getAll().forEach((data) => {
if (!this.database) return
this.database.delete(data.category,data.key)
})
}
onInit(callback:ODStatsManagerInitCallback){
this.#initListeners.push(callback)
}
}
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
}
useDatabase(database:ODDatabase){
this.database = database
}
getStat(id:ODValidId, scopeId:string): ODValidStatValue|null {
if (!this.database) return null
const newId = new ODId(id)
const data = 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
}
setStat(id:ODValidId, scopeId:string, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean {
if (!this.database) return false
const stat = this.get(id)
if (!stat) return false
if (mode == "set" || typeof value != "number"){
this.database.set(this.id.value+"_"+stat.id.value,scopeId,value)
}else if (mode == "increase"){
const currentValue = this.getStat(id,scopeId)
if (typeof currentValue != "number") this.database.set(this.id.value+"_"+stat.id.value,scopeId,0)
else this.database.set(this.id.value+"_"+stat.id.value,scopeId,currentValue+value)
}else if (mode == "decrease"){
const currentValue = this.getStat(id,scopeId)
if (typeof currentValue != "number") this.database.set(this.id.value+"_"+stat.id.value,scopeId,0)
else this.database.set(this.id.value+"_"+stat.id.value,scopeId,currentValue-value)
}
return true
}
resetStat(id:ODValidId, scopeId:string): ODValidStatValue|null {
if (!this.database) return null
const stat = this.get(id)
if (!stat) return null
if (stat.value != null) this.database.set(this.id.value+"_"+stat.id.value,scopeId,stat.value)
return stat.value
}
init(): string[] {
//get all valid stats categories
this.ready = true
return this.getAll().map((stat) => this.id.value+"_"+stat.id.value)
}
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 = 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")
}
}
export class ODStatGlobalScope extends ODStatScope {
getStat(id:ODValidId): ODValidStatValue|null {
return super.getStat(id,"GLOBAL")
}
setStat(id:ODValidId, value:ODValidStatValue, mode:ODStatScopeSetMode): boolean {
return super.setStat(id,"GLOBAL",value,mode)
}
resetStat(id:ODValidId): 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)
}
}
export type ODStatRenderer = (value:ODValidStatValue, scopeId:string, guild:discord.Guild, channel:discord.TextBasedChannel, user:discord.User) => string|Promise<string>
export class ODStat extends ODManagerData {
priority: number
render: ODStatRenderer
value: ODValidStatValue|null
constructor(id:ODValidId, priority:number, render:ODStatRenderer, value?:ODValidStatValue){
super(id)
this.priority = priority
this.render = render
this.value = value ?? null
}
}
export class ODBasicStat extends ODStat {
name: string
constructor(id:ODValidId, priority:number, name:string, value:ODValidStatValue){
super(id,priority,(value) => {
return ""+name+": `"+value.toString()+"`"
},value)
this.name = name
}
}
export type ODDynamicStatRenderer = (scopeId:string, guild:discord.Guild, channel:discord.TextBasedChannel, user:discord.User) => string|Promise<string>
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)
})
}
}
+43
View File
@@ -0,0 +1,43 @@
///////////////////////////////////////
//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"
export type ODVerifyBarCallback = (responder:ODButtonResponderInstance,customData?:string) => void|Promise<void>
export class ODVerifyBar extends ODManagerData {
success: ODWorkerManager<ODButtonResponderInstance,"verifybar",{data:string|null,verifybarMessage:discord.Message<boolean>|null}>
failure: ODWorkerManager<ODButtonResponderInstance,"verifybar",{data:string|null,verifybarMessage:discord.Message<boolean>|null}>
message: ODMessage<"verifybar",{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User,verifybar:ODVerifyBar,originalMessage:discord.Message<boolean>}>
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
}
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})
}
}
}
export class ODVerifyBarManager extends ODManager<ODVerifyBar> {
constructor(debug:ODDebugger){
super(debug,"verifybar")
}
}
+93
View File
@@ -0,0 +1,93 @@
///////////////////////////////////////
//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 will probably 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)
}
}
}
}
+28
View File
@@ -0,0 +1,28 @@
///////////////////////////////////////
//OPENTICKET BLACKLIST MODULE
///////////////////////////////////////
import { ODManager, ODManagerData, ODValidId } from "../modules/base"
import { ODDebugger } from "../modules/console"
export class ODBlacklist extends ODManagerData {
#reason: string|null
constructor(id:ODValidId,reason:string|null){
super(id)
this.#reason = reason
}
set reason(reason:string|null) {
this.#reason = reason
this._change()
}
get reason(){
return this.#reason
}
}
export class ODBlacklistManager extends ODManager<ODBlacklist> {
constructor(debug:ODDebugger){
super(debug,"blacklist")
}
}
+421
View File
@@ -0,0 +1,421 @@
///////////////////////////////////////
//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 discord from "discord.js"
import * as crypto from "crypto"
import { OTRoleUpdateMode } from "./role"
export class ODOptionManager extends ODManager<ODOption> {
#debug: ODDebugger
suffix: ODOptionSuffixManager
constructor(debug:ODDebugger){
super(debug,"option")
this.#debug = debug
this.suffix = new ODOptionSuffixManager(debug)
}
add(data:ODOption, overwrite?:boolean): boolean {
data.useDebug(this.#debug,"option data")
return super.add(data,overwrite)
}
}
export interface ODOptionDataJson {
id:string,
value:ODValidJsonType
}
export interface ODOptionJson {
id:string,
type:string,
version:string,
data:ODOptionDataJson[]
}
export class ODOption extends ODManager<ODOptionData<ODValidJsonType>> {
id:ODId
type: string
constructor(id:ODValidId, type:string, data:ODOptionData<ODValidJsonType>[]){
super()
this.id = new ODId(id)
this.type = type
data.forEach((data) => {
this.add(data)
})
}
toJson(version:ODVersion): ODOptionJson {
const data = this.getAll().map((data) => {
return {
id:data.id.toString(),
value:data.value
}
})
return {
id:this.id.toString(),
type:this.type,
version:version.toString(),
data
}
}
static fromJson(json:ODOptionJson): ODOption {
return new ODOption(json.id,json.type,json.data.map((data) => new ODOptionData(data.id,data.value)))
}
}
export class ODOptionData<DataType extends ODValidJsonType> extends ODManagerData {
#value: DataType
constructor(id:ODValidId, value:DataType){
super(id)
this.#value = value
}
set value(value:DataType){
this.#value = value
this._change()
}
get value(): DataType {
return this.#value
}
/**Refresh the database. Is only required to be used when updating `ODOptionData` with an object/array as value. */
refreshDatabase(){
this._change()
}
}
/**## ODTicketOptionIds `type`
* This type is an array of ids available in the `ODTicketOption` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODTicketOptionIds {
"openticket:name":ODOptionData<string>,
"openticket:description":ODOptionData<string>,
"openticket:button-emoji":ODOptionData<string>,
"openticket:button-label":ODOptionData<string>,
"openticket:button-color":ODOptionData<ODValidButtonColor>,
"openticket:admins":ODOptionData<string[]>,
"openticket:admins-readonly":ODOptionData<string[]>,
"openticket:allow-blacklisted-users":ODOptionData<boolean>,
"openticket:questions":ODOptionData<string[]>,
"openticket:channel-prefix":ODOptionData<string>,
"openticket:channel-suffix":ODOptionData<"user-name"|"user-id"|"random-number"|"random-hex"|"counter-dynamic"|"counter-fixed">,
"openticket:channel-category":ODOptionData<string>,
"openticket:channel-category-closed":ODOptionData<string>,
"openticket:channel-category-backup":ODOptionData<string>,
"openticket:channel-categories-claimed":ODOptionData<{user:string,category:string}[]>,
"openticket:channel-description":ODOptionData<string>,
"openticket:dm-message-enabled":ODOptionData<boolean>,
"openticket:dm-message-text":ODOptionData<string>,
"openticket:dm-message-embed":ODOptionData<ODJsonConfig_DefaultOptionEmbedSettingsType>,
"openticket:ticket-message-enabled":ODOptionData<boolean>,
"openticket:ticket-message-text":ODOptionData<string>,
"openticket:ticket-message-embed":ODOptionData<ODJsonConfig_DefaultOptionEmbedSettingsType>,
"openticket:ticket-message-ping":ODOptionData<ODJsonConfig_DefaultOptionPingSettingsType>,
"openticket:autoclose-enable-hours":ODOptionData<boolean>,
"openticket:autoclose-enable-leave":ODOptionData<boolean>,
"openticket:autoclose-disable-claim":ODOptionData<boolean>,
"openticket:autoclose-hours":ODOptionData<number>,
"openticket:autodelete-enable-days":ODOptionData<boolean>,
"openticket:autodelete-enable-leave":ODOptionData<boolean>,
"openticket:autodelete-disable-claim":ODOptionData<boolean>,
"openticket:autodelete-days":ODOptionData<number>,
"openticket:cooldown-enabled":ODOptionData<boolean>,
"openticket:cooldown-minutes":ODOptionData<number>,
"openticket:limits-enabled":ODOptionData<boolean>,
"openticket:limits-maximum-global":ODOptionData<number>,
"openticket:limits-maximum-user":ODOptionData<number>
}
export class ODTicketOption extends ODOption {
type: "openticket:ticket" = "openticket:ticket"
constructor(id:ODValidId, data:ODOptionData<ODValidJsonType>[]){
super(id,"openticket:ticket",data)
}
get<OptionId extends keyof ODTicketOptionIds>(id:OptionId): ODTicketOptionIds[OptionId]
get(id:ODValidId): ODOptionData<ODValidJsonType>|null
get(id:ODValidId): ODOptionData<ODValidJsonType>|null {
return super.get(id)
}
remove<OptionId extends keyof ODTicketOptionIds>(id:OptionId): ODTicketOptionIds[OptionId]
remove(id:ODValidId): ODOptionData<ODValidJsonType>|null
remove(id:ODValidId): ODOptionData<ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODTicketOptionIds): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
static fromJson(json: ODOptionJson): ODTicketOption {
return new ODTicketOption(json.id,json.data.map((data) => new ODOptionData(data.id,data.value)))
}
}
/**## ODWebsiteOptionIds `type`
* This type is an array of ids available in the `ODWebsiteOption` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODWebsiteOptionIds {
"openticket:name":ODOptionData<string>,
"openticket:description":ODOptionData<string>,
"openticket:button-emoji":ODOptionData<string>,
"openticket:button-label":ODOptionData<string>,
"openticket:url":ODOptionData<string>,
}
export class ODWebsiteOption extends ODOption {
type: "openticket:website" = "openticket:website"
constructor(id:ODValidId, data:ODOptionData<ODValidJsonType>[]){
super(id,"openticket:website",data)
}
get<OptionId extends keyof ODWebsiteOptionIds>(id:OptionId): ODWebsiteOptionIds[OptionId]
get(id:ODValidId): ODOptionData<ODValidJsonType>|null
get(id:ODValidId): ODOptionData<ODValidJsonType>|null {
return super.get(id)
}
remove<OptionId extends keyof ODWebsiteOptionIds>(id:OptionId): ODWebsiteOptionIds[OptionId]
remove(id:ODValidId): ODOptionData<ODValidJsonType>|null
remove(id:ODValidId): ODOptionData<ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODWebsiteOptionIds): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
static fromJson(json: ODOptionJson): ODWebsiteOption {
return new ODWebsiteOption(json.id,json.data.map((data) => new ODOptionData(data.id,data.value)))
}
}
/**## ODRoleOptionIds `type`
* This type is an array of ids available in the `ODRoleOption` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODRoleOptionIds {
"openticket:name":ODOptionData<string>,
"openticket:description":ODOptionData<string>,
"openticket:button-emoji":ODOptionData<string>,
"openticket:button-label":ODOptionData<string>,
"openticket:button-color":ODOptionData<ODValidButtonColor>,
"openticket:roles":ODOptionData<string[]>,
"openticket:mode":ODOptionData<OTRoleUpdateMode>,
"openticket:remove-roles-on-add":ODOptionData<string[]>,
"openticket:add-on-join":ODOptionData<boolean>
}
export class ODRoleOption extends ODOption {
type: "openticket:role" = "openticket:role"
constructor(id:ODValidId, data:ODOptionData<ODValidJsonType>[]){
super(id,"openticket:role",data)
}
get<OptionId extends keyof ODRoleOptionIds>(id:OptionId): ODRoleOptionIds[OptionId]
get(id:ODValidId): ODOptionData<ODValidJsonType>|null
get(id:ODValidId): ODOptionData<ODValidJsonType>|null {
return super.get(id)
}
remove<OptionId extends keyof ODRoleOptionIds>(id:OptionId): ODRoleOptionIds[OptionId]
remove(id:ODValidId): ODOptionData<ODValidJsonType>|null
remove(id:ODValidId): ODOptionData<ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODRoleOptionIds): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
static fromJson(json:ODOptionJson): ODRoleOption {
return new ODRoleOption(json.id,json.data.map((data) => new ODOptionData(data.id,data.value)))
}
}
export class ODOptionSuffixManager extends ODManager<ODOptionSuffix> {
/**Alias to open ticket global database. */
database: ODDatabase|null = null
constructor(debug:ODDebugger){
super(debug,"ticket suffix")
}
useDatabase(database:ODDatabase){
this.database = database
}
/**Instantly get the suffix from an option. */
getSuffixFromOption(option:ODTicketOption,user:discord.User): string|null {
const suffix = this.getAll().find((suffix) => suffix.option.id.value == option.id.value)
if (!suffix) return null
return suffix.getSuffix(user)
}
}
export class ODOptionSuffix extends ODManagerData {
/**The option of this suffix. */
option: ODTicketOption
constructor(id:ODValidId, option:ODTicketOption){
super(id)
this.option = option
}
/**Get the suffix for a new ticket. */
getSuffix(user:discord.User): string {
throw new ODSystemError("Tried to use an unimplemented ODOptionSuffix!")
}
}
export class ODOptionUserNameSuffix extends ODOptionSuffix {
getSuffix(user:discord.User): string {
return user.username
}
}
export class ODOptionUserIdSuffix extends ODOptionSuffix {
getSuffix(user:discord.User): string {
return user.id
}
}
export class ODOptionCounterDynamicSuffix extends ODOptionSuffix {
/**The database where the value of this counter is stored. */
database: ODDatabase
constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){
super(id,option)
this.database = database
if (!this.database.exists("openticket:option-suffix-counter",option.id.value)) this.database.set("openticket:option-suffix-counter",this.option.id.value,0)
}
getSuffix(user:discord.User): string {
const rawCurrentValue = this.database.get("openticket:option-suffix-counter",this.option.id.value)
const currentValue = (typeof rawCurrentValue != "number") ? 0 : rawCurrentValue
const newValue = currentValue+1
this.database.set("openticket:option-suffix-counter",this.option.id.value,newValue)
return newValue.toString()
}
}
export class ODOptionCounterFixedSuffix extends ODOptionSuffix {
/**The database where the value of this counter is stored. */
database: ODDatabase
constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){
super(id,option)
this.database = database
if (!this.database.exists("openticket:option-suffix-counter",option.id.value)) this.database.set("openticket:option-suffix-counter",this.option.id.value,0)
}
getSuffix(user:discord.User): string {
const rawCurrentValue = this.database.get("openticket:option-suffix-counter",this.option.id.value)
const currentValue = (typeof rawCurrentValue != "number") ? 0 : rawCurrentValue
const newValue = (currentValue >= 9999) ? 0 : currentValue+1
this.database.set("openticket:option-suffix-counter",this.option.id.value,newValue)
if (newValue.toString().length == 1) return "000"+newValue.toString()
else if (newValue.toString().length == 2) return "00"+newValue.toString()
else if (newValue.toString().length == 3) return "0"+newValue.toString()
else return newValue.toString()
}
}
export class ODOptionRandomNumberSuffix extends ODOptionSuffix {
/**The database where previous random numbers are stored. */
database: ODDatabase
constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){
super(id,option)
this.database = database
if (!this.database.exists("openticket:option-suffix-history",option.id.value)) this.database.set("openticket:option-suffix-history",this.option.id.value,[])
}
#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)
else return number
}
getSuffix(user:discord.User): string {
const rawCurrentValues = this.database.get("openticket:option-suffix-history",this.option.id.value)
const currentValues = ((Array.isArray(rawCurrentValues)) ? rawCurrentValues : []) as string[]
const newValue = this.#generateUniqueValue(currentValues)
currentValues.push(newValue)
if (currentValues.length > 50) currentValues.shift()
this.database.set("openticket:option-suffix-history",this.option.id.value,currentValues)
return newValue
}
}
export class ODOptionRandomHexSuffix extends ODOptionSuffix {
/**The database where previous random hexes are stored. */
database: ODDatabase
constructor(id:ODValidId, option:ODTicketOption, database:ODDatabase){
super(id,option)
this.database = database
if (!this.database.exists("openticket:option-suffix-history",option.id.value)) this.database.set("openticket:option-suffix-history",this.option.id.value,[])
}
#generateUniqueValue(history:string[]): string {
const hex = crypto.randomBytes(2).toString("hex")
if (history.includes(hex)) return this.#generateUniqueValue(history)
else return hex
}
getSuffix(user:discord.User): string {
const rawCurrentValues = this.database.get("openticket:option-suffix-history",this.option.id.value)
const currentValues = ((Array.isArray(rawCurrentValues)) ? rawCurrentValues : []) as string[]
const newValue = this.#generateUniqueValue(currentValues)
currentValues.push(newValue)
if (currentValues.length > 50) currentValues.shift()
this.database.set("openticket:option-suffix-history",this.option.id.value,currentValues)
return newValue
}
}
+128
View File
@@ -0,0 +1,128 @@
///////////////////////////////////////
//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"
export class ODPanelManager extends ODManager<ODPanel> {
#debug: ODDebugger
constructor(debug:ODDebugger){
super(debug,"option")
this.#debug = debug
}
add(data:ODPanel, overwrite?:boolean): boolean {
data.useDebug(this.#debug,"option data")
return super.add(data,overwrite)
}
}
export interface ODPanelDataJson {
id:string,
value:ODValidJsonType
}
export interface ODPanelJson {
id:string,
version:string,
data:ODPanelDataJson[]
}
/**## ODPanelIds `type`
* This type is an array of ids available in the `ODPanel` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODPanelIds {
"openticket:name":ODPanelData<string>,
"openticket:options":ODPanelData<string[]>,
"openticket:dropdown":ODPanelData<boolean>,
"openticket:text":ODPanelData<string>,
"openticket:embed":ODPanelData<ODJsonConfig_DefaultPanelEmbedSettingsType>,
"openticket:dropdown-placeholder":ODPanelData<string>,
"openticket:enable-max-tickets-warning-text":ODPanelData<boolean>,
"openticket:enable-max-tickets-warning-embed":ODPanelData<boolean>,
"openticket:describe-options-layout":ODPanelData<"simple"|"normal"|"detailed">,
"openticket:describe-options-custom-title":ODPanelData<string>,
"openticket:describe-options-in-text":ODPanelData<boolean>,
"openticket:describe-options-in-embed-fields":ODPanelData<boolean>,
"openticket:describe-options-in-embed-description":ODPanelData<boolean>
}
export class ODPanel extends ODManager<ODPanelData<ODValidJsonType>> {
id:ODId
constructor(id:ODValidId, data:ODPanelData<ODValidJsonType>[]){
super()
this.id = new ODId(id)
data.forEach((data) => {
this.add(data)
})
}
toJson(version:ODVersion): ODPanelJson {
const data = this.getAll().map((data) => {
return {
id:data.id.toString(),
value:data.value
}
})
return {
id:this.id.toString(),
version:version.toString(),
data
}
}
static fromJson(json:ODPanelJson): ODPanel {
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(id:ODValidId): ODPanelData<ODValidJsonType>|null {
return super.get(id)
}
remove<PanelId extends keyof ODPanelIds>(id:PanelId): ODPanelIds[PanelId]
remove(id:ODValidId): ODPanelData<ODValidJsonType>|null
remove(id:ODValidId): ODPanelData<ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODPanelIds): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
export class ODPanelData<DataType extends ODValidJsonType> extends ODManagerData {
#value: DataType
constructor(id:ODValidId, value:DataType){
super(id)
this.#value = value
}
set value(value:DataType){
this.#value = value
this._change()
}
get value(): DataType {
return this.#value
}
/**Refresh the database. Is only required to be used when updating `ODPanelData` with an object/array as value. */
refreshDatabase(){
this._change()
}
}
+180
View File
@@ -0,0 +1,180 @@
///////////////////////////////////////
//OPENTICKET OPTION MODULE
///////////////////////////////////////
import { ODId, ODManager, ODValidJsonType, ODValidId, ODVersion, ODManagerData } from "../modules/base"
import { ODDebugger } from "../modules/console"
export class ODQuestionManager extends ODManager<ODQuestion> {
#debug: ODDebugger
constructor(debug:ODDebugger){
super(debug,"question")
this.#debug = debug
}
add(data:ODQuestion, overwrite?:boolean): boolean {
data.useDebug(this.#debug,"question data")
return super.add(data,overwrite)
}
}
export interface ODQuestionDataJson {
id:string,
value:ODValidJsonType
}
export interface ODQuestionJson {
id:string,
type:string,
version:string,
data:ODQuestionDataJson[]
}
export class ODQuestion extends ODManager<ODQuestionData<ODValidJsonType>> {
id:ODId
type: string
constructor(id:ODValidId, type:string, data:ODQuestionData<ODValidJsonType>[]){
super()
this.id = new ODId(id)
this.type = type
data.forEach((data) => {
this.add(data)
})
}
toJson(version:ODVersion): ODQuestionJson {
const data = this.getAll().map((data) => {
return {
id:data.id.toString(),
value:data.value
}
})
return {
id:this.id.toString(),
type:this.type,
version:version.toString(),
data
}
}
static fromJson(json:ODQuestionJson): ODQuestion {
return new ODQuestion(json.id,json.type,json.data.map((data) => new ODQuestionData(data.id,data.value)))
}
}
export class ODQuestionData<DataType extends ODValidJsonType> extends ODManagerData {
#value: DataType
constructor(id:ODValidId, value:DataType){
super(id)
this.#value = value
}
set value(value:DataType){
this.#value = value
this._change()
}
get value(): DataType {
return this.#value
}
/**Refresh the database. Is only required to be used when updating `ODQuestionData` with an object/array as value. */
refreshDatabase(){
this._change()
}
}
/**## ODShortQuestionIds `type`
* This type is an array of ids available in the `ODShortQuestion` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODShortQuestionIds {
"openticket:name":ODQuestionData<string>,
"openticket:required":ODQuestionData<boolean>,
"openticket:placeholder":ODQuestionData<string>,
"openticket:length-enabled":ODQuestionData<boolean>,
"openticket:length-min":ODQuestionData<number>,
"openticket:length-max":ODQuestionData<number>
}
export class ODShortQuestion extends ODQuestion {
type: "openticket:short" = "openticket:short"
constructor(id:ODValidId, data:ODQuestionData<ODValidJsonType>[]){
super(id,"openticket:short",data)
}
get<QuestionId extends keyof ODShortQuestionIds>(id:QuestionId): ODShortQuestionIds[QuestionId]
get(id:ODValidId): ODQuestionData<ODValidJsonType>|null
get(id:ODValidId): ODQuestionData<ODValidJsonType>|null {
return super.get(id)
}
remove<QuestionId extends keyof ODShortQuestionIds>(id:QuestionId): ODShortQuestionIds[QuestionId]
remove(id:ODValidId): ODQuestionData<ODValidJsonType>|null
remove(id:ODValidId): ODQuestionData<ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODShortQuestionIds): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
static fromJson(json: ODQuestionJson): ODShortQuestion {
return new ODShortQuestion(json.id,json.data.map((data) => new ODQuestionData(data.id,data.value)))
}
}
/**## ODParagraphQuestionIds `type`
* This type is an array of ids available in the `ODParagraphQuestion` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODParagraphQuestionIds {
"openticket:name":ODQuestionData<string>,
"openticket:required":ODQuestionData<boolean>,
"openticket:placeholder":ODQuestionData<string>,
"openticket:length-enabled":ODQuestionData<boolean>,
"openticket:length-min":ODQuestionData<number>,
"openticket:length-max":ODQuestionData<number>
}
export class ODParagraphQuestion extends ODQuestion {
type: "openticket:paragraph" = "openticket:paragraph"
constructor(id:ODValidId, data:ODQuestionData<ODValidJsonType>[]){
super(id,"openticket:paragraph",data)
}
get<QuestionId extends keyof ODParagraphQuestionIds>(id:QuestionId): ODParagraphQuestionIds[QuestionId]
get(id:ODValidId): ODQuestionData<ODValidJsonType>|null
get(id:ODValidId): ODQuestionData<ODValidJsonType>|null {
return super.get(id)
}
remove<QuestionId extends keyof ODParagraphQuestionIds>(id:QuestionId): ODParagraphQuestionIds[QuestionId]
remove(id:ODValidId): ODQuestionData<ODValidJsonType>|null
remove(id:ODValidId): ODQuestionData<ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODParagraphQuestionIds): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
static fromJson(json: ODQuestionJson): ODParagraphQuestion {
return new ODParagraphQuestion(json.id,json.data.map((data) => new ODQuestionData(data.id,data.value)))
}
}
+122
View File
@@ -0,0 +1,122 @@
///////////////////////////////////////
//OPENTICKET ROLE MODULE
///////////////////////////////////////
import { ODId, ODManager, ODValidJsonType, ODValidId, ODVersion, ODManagerData } from "../modules/base"
import { ODDebugger } from "../modules/console"
import * as discord from "discord.js"
export class ODRoleManager extends ODManager<ODRole> {
#debug: ODDebugger
constructor(debug:ODDebugger){
super(debug,"role")
this.#debug = debug
}
add(data:ODRole, overwrite?:boolean): boolean {
data.useDebug(this.#debug,"role data")
return super.add(data,overwrite)
}
}
export interface ODRoleDataJson {
id:string,
value:ODValidJsonType
}
export interface ODRoleJson {
id:string,
version:string,
data:ODRoleDataJson[]
}
export class ODRoleData<DataType extends ODValidJsonType> extends ODManagerData {
#value: DataType
constructor(id:ODValidId, value:DataType){
super(id)
this.#value = value
}
set value(value:DataType){
this.#value = value
this._change()
}
get value(): DataType {
return this.#value
}
/**Refresh the database. Is only required to be used when updating `ODRoleData` with an object/array as value. */
refreshDatabase(){
this._change()
}
}
/**## ODRoleIds `type`
* This type is an array of ids available in the `ODRole` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODRoleIds {
"openticket:roles":ODRoleData<string[]>,
"openticket:mode":ODRoleData<OTRoleUpdateMode>,
"openticket:remove-roles-on-add":ODRoleData<string[]>,
"openticket:add-on-join":ODRoleData<boolean>
}
export class ODRole extends ODManager<ODRoleData<ODValidJsonType>> {
id:ODId
constructor(id:ODValidId, data:ODRoleData<ODValidJsonType>[]){
super()
this.id = new ODId(id)
data.forEach((data) => {
this.add(data)
})
}
toJson(version:ODVersion): ODRoleJson {
const data = this.getAll().map((data) => {
return {
id:data.id.toString(),
value:data.value
}
})
return {
id:this.id.toString(),
version:version.toString(),
data
}
}
static fromJson(json:ODRoleJson): ODRole {
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(id:ODValidId): ODRoleData<ODValidJsonType>|null {
return super.get(id)
}
remove<OptionId extends keyof ODRoleIds>(id:OptionId): ODRoleIds[OptionId]
remove(id:ODValidId): ODRoleData<ODValidJsonType>|null
remove(id:ODValidId): ODRoleData<ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODRoleIds): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
export interface OTRoleUpdateResult {
role:discord.Role,
action:"added"|"removed"|null
}
export type OTRoleUpdateMode = "add&remove"|"add"|"remove"
+251
View File
@@ -0,0 +1,251 @@
///////////////////////////////////////
//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 { ODOption, ODOptionJson, ODTicketOption } from "./option"
import * as discord from "discord.js"
export class ODTicketManager extends ODManager<ODTicket> {
/**A reference to the main server of the bot */
#guild: discord.Guild|null = null
#client: ODClientManager_Default
#debug: ODDebugger
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("openticket: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("openticket:opened-by").value
if (!creatorId) return null
else return (await this.#guild.client.users.fetch(creatorId))
}else if (user == "closer"){
const closerId = ticket.get("openticket:closed-by").value
if (!closerId) return null
else return (await this.#guild.client.users.fetch(closerId))
}else if (user == "claimer"){
const claimerId = ticket.get("openticket:claimed-by").value
if (!claimerId) return null
else return (await this.#guild.client.users.fetch(claimerId))
}else if (user == "pinner"){
const pinnerId = ticket.get("openticket: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("openticket: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("openticket: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("openticket: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
}
}
export interface ODTicketDataJson {
id:string,
value:ODValidJsonType
}
export interface ODTicketJson {
id:string,
option:string,
version:string,
data:ODTicketDataJson[]
}
/**## ODTicketIds `type`
* This type is an array of ids available in the `ODTicket` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODTicketIds {
"openticket:busy":ODTicketData<boolean>,
"openticket:ticket-message":ODTicketData<string|null>,
"openticket:participants":ODTicketData<{type:"role"|"user",id:string}[]>,
"openticket:channel-suffix":ODTicketData<string>,
"openticket:open":ODTicketData<boolean>,
"openticket:opened-by":ODTicketData<string|null>,
"openticket:opened-on":ODTicketData<number|null>,
"openticket:closed":ODTicketData<boolean>,
"openticket:closed-by":ODTicketData<string|null>,
"openticket:closed-on":ODTicketData<number|null>,
"openticket:claimed":ODTicketData<boolean>,
"openticket:claimed-by":ODTicketData<string|null>,
"openticket:claimed-on":ODTicketData<number|null>,
"openticket:pinned":ODTicketData<boolean>,
"openticket:pinned-by":ODTicketData<string|null>,
"openticket:pinned-on":ODTicketData<number|null>,
"openticket:for-deletion":ODTicketData<boolean>,
"openticket:category":ODTicketData<string|null>,
"openticket:category-mode":ODTicketData<null|"normal"|"closed"|"backup"|"claimed">,
"openticket:autoclose-enabled":ODTicketData<boolean>,
"openticket:autoclose-hours":ODTicketData<number>,
"openticket:autoclosed":ODTicketData<boolean>,
"openticket:autodelete-enabled":ODTicketData<boolean>,
"openticket:autodelete-days":ODTicketData<number>,
"openticket:answers":ODTicketData<{id:string,name:string,type:"short"|"paragraph",value:string|null}[]>,
}
export class ODTicket extends ODManager<ODTicketData<ODValidJsonType>> {
id:ODId
#option: ODTicketOption
constructor(id:ODValidId, option:ODTicketOption, data:ODTicketData<ODValidJsonType>[]){
super()
this.id = new ODId(id)
this.#option = option
data.forEach((data) => {
this.add(data)
})
}
set option(option:ODTicketOption){
this.#option = option
this._change()
}
get option(){
return this.#option
}
toJson(version:ODVersion): ODTicketJson {
const data = this.getAll().map((data) => {
return {
id:data.id.toString(),
value:data.value
}
})
return {
id:this.id.toString(),
option:this.option.id.value,
version:version.toString(),
data
}
}
static fromJson(json:ODTicketJson, option:ODTicketOption): ODTicket {
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(id:ODValidId): ODTicketData<ODValidJsonType>|null {
return super.get(id)
}
remove<OptionId extends keyof ODTicketIds>(id:OptionId): ODTicketIds[OptionId]
remove(id:ODValidId): ODTicketData<ODValidJsonType>|null
remove(id:ODValidId): ODTicketData<ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof ODTicketIds): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
export class ODTicketData<DataType extends ODValidJsonType> extends ODManagerData {
#value: DataType
constructor(id:ODValidId, value:DataType){
super(id)
this.#value = value
}
set value(value:DataType){
this.#value = value
this._change()
}
get value(): DataType {
return this.#value
}
/**Refresh the database. Is only required to be used when updating `ODTicketData` with an object/array as value. */
refreshDatabase(){
this._change()
}
}
export type ODTicketClearFilter = "all"|"open"|"closed"|"claimed"|"unclaimed"|"pinned"|"unpinned"|"autoclosed"
+802
View File
@@ -0,0 +1,802 @@
///////////////////////////////////////
//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 * as discord from "discord.js"
export class ODTranscriptManager extends ODManager<ODTranscriptCompiler<any>> {
/**The manager responsible for collecting all messages in a channel. */
collector: ODTranscriptCollector
constructor(debug:ODDebugger, tickets:ODTicketManager){
super(debug,"transcript compiler")
this.collector = new ODTranscriptCollector(tickets)
}
}
export type ODTranscriptCompilerInitFunction = (ticket:ODTicket, channel:discord.TextChannel, user:discord.User) => (ODTranscriptCompilerInitResult)|Promise<ODTranscriptCompilerInitResult>
export type ODTranscriptCompilerCompileFunction<Data extends object> = (ticket:ODTicket, channel:discord.TextChannel, user:discord.User) => ODTranscriptCompilerCompileResult<Data>|Promise<ODTranscriptCompilerCompileResult<Data>>
export type ODTranscriptCompilerReadyFunction<Data extends object> = (result:ODTranscriptCompilerCompileResult<Data>) => ODTranscriptCompilerReadyResult|Promise<ODTranscriptCompilerReadyResult>
export interface ODTranscriptCompilerInitResult {
success:boolean,
errorReason:string|null,
pendingMessage:ODMessageBuildResult|null
}
export interface ODTranscriptCompilerCompileResult<Data extends object> {
ticket:ODTicket,
channel:discord.TextChannel,
user:discord.User
success:boolean,
errorReason:string|null,
messages:ODTranscriptMessageData[]|null,
data:Data|null
}
export interface ODTranscriptCompilerReadyResult {
channelMessage?:ODMessageBuildResult,
creatorDmMessage?:ODMessageBuildResult,
participantDmMessage?:ODMessageBuildResult,
activeAdminDmMessage?:ODMessageBuildResult,
everyAdminDmMessage?:ODMessageBuildResult
}
export class ODTranscriptCompiler<Data extends object> extends ODManagerData {
/*Initialise the system every time a transcript is created. Returns optional "pending" message to display while the transcript is being compiled. */
init: ODTranscriptCompilerInitFunction|null
/*Compile or create the transcript. Returns data to give to the ready() function for message creation. */
compile: ODTranscriptCompilerCompileFunction<Data>|null
/*Unload the system & create the final transcript message that will be sent. */
ready: ODTranscriptCompilerReadyFunction<Data>|null
constructor(id:ODValidId, init?:ODTranscriptCompilerInitFunction, compile?:ODTranscriptCompilerCompileFunction<Data>, ready?:ODTranscriptCompilerReadyFunction<Data>|null){
super(id)
this.init = init ?? null
this.compile = compile ?? null
this.ready = ready ?? null
}
}
/**## ODTranscriptCompilerIds `type`
* This type is an array of ids available in the `ODTranscriptCompiler` class.
* It's used to generate typescript declarations for this class.
*/
export interface ODTranscriptCompilerIds {
"openticket:html-compiler":ODTranscriptCompiler<{url:string}>,
"openticket:text-compiler":ODTranscriptCompiler<{contents:string}>,
}
/**## 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 `openticket.transcripts`!
*/
export class ODTranscriptManager_Default extends ODTranscriptManager {
get<QuestionId extends keyof ODTranscriptCompilerIds>(id:QuestionId): ODTranscriptCompilerIds[QuestionId]
get(id:ODValidId): ODTranscriptCompiler<any>|null
get(id:ODValidId): ODTranscriptCompiler<any>|null {
return super.get(id)
}
remove<QuestionId extends keyof ODTranscriptCompilerIds>(id:QuestionId): ODTranscriptCompilerIds[QuestionId]
remove(id:ODValidId): ODTranscriptCompiler<any>|null
remove(id:ODValidId): ODTranscriptCompiler<any>|null {
return super.remove(id)
}
exists(id:keyof ODTranscriptCompilerIds): boolean
exists(id:ODValidId): boolean
exists(id:ODValidId): boolean {
return super.exists(id)
}
}
export class ODTranscriptCollector {
/**Alias for the ticket manager. */
#tickets: ODTicketManager
constructor(tickets:ODTicketManager){
this.#tickets = tickets
}
/**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)
if (!channel) return null
const final: discord.Message<true>[] = []
const limit: number = 2000
let lastId: string = ""
while (true){
const options: discord.FetchMessagesOptions = {limit:100}
if (lastId) options.before = lastId
const messages = await channel.messages.fetch(options)
messages.forEach(msg => {
if (msg.author.id == msg.client.user.id && newInclude.client) final.push(msg)
else if ((msg.author.bot || msg.author.system) && newInclude.bots) final.push(msg)
else if (newInclude.users) final.push(msg)
})
const lastMessage = messages.last()
if (messages.size != 100 || final.length >= limit || !lastMessage) break
else lastId = lastMessage.id
}
return final.reverse()
}
/**Count all messages from a given ticket channel. It may not include all messages depending on the ratelimit. */
async countAllMessages(ticket:ODTicket, include?:ODTranscriptCollectorIncludeSettings){
const messages = await this.collectAllMessages(ticket,include)
if (!messages) return null
return messages.length
}
async convertMessagesToTranscriptData(messages:discord.Message<true>[]): Promise<ODTranscriptMessageData[]> {
const final: ODTranscriptMessageData[] = []
for (const msg of messages){
const {guild,channel,id,createdTimestamp} = msg
//create message author
const author = this.#handleUserData(msg.author,msg.member)
//create message type
let type: ODTranscriptMessageType = "default"
if (msg.mentions.everyone || msg.content.includes("@here")) type = "important"
else if (msg.flags.has("Ephemeral")) type = "ephemeral"
else if (msg.type == discord.MessageType.UserJoin) type = "welcome.message"
else if (msg.type == discord.MessageType.ChannelPinnedMessage) type = "pinned.message"
else if (msg.type == discord.MessageType.GuildBoost || msg.type == discord.MessageType.GuildBoostTier1 || msg.type == discord.MessageType.GuildBoostTier2 || msg.type == discord.MessageType.GuildBoostTier3) type = "boost.message"
else if (msg.type == discord.MessageType.ThreadCreated) type = "thread.message"
//create message embeds
const embeds: ODTranscriptEmbedData[] = []
msg.embeds.forEach((embed) => {
embeds.push({
title:embed.title,
description:embed.description,
authorimg:(embed.author && embed.author.iconURL) ? embed.author.iconURL : null,
authortext:(embed.author) ? embed.author.name : null,
footerimg:(embed.footer && embed.footer.iconURL) ? embed.footer.iconURL : null,
footertext:(embed.footer) ? embed.footer.text : null,
color:(embed.hexColor as discord.HexColorString) ?? "#000000",
image:(embed.image) ? embed.image.url : null,
thumbnail:(embed.thumbnail) ? embed.thumbnail.url : null,
url:embed.url,
fields:embed.fields.map((field) => {return {name:field.name,value:field.value,inline:field.inline ?? false}})
})
})
//create message files
const files: ODTranscriptFileData[] = []
msg.attachments.forEach((attachment) => {
const {size,unit} = this.calculateFileSize(attachment.size)
files.push({
type:attachment.contentType ?? "unknown",
size,
unit,
name:attachment.name,
url:attachment.url,
spoiler:attachment.spoiler,
alt:attachment.description
})
})
//create message components
const rows: ODTranscriptComponentRowData[] = []
msg.components.forEach((row) => {
const components: ODTranscriptComponentRowData["components"] = []
row.components.forEach((component) => {
if (component.type == discord.ComponentType.Button){
components.push({
id:component.customId,
disabled:component.disabled,
type:"button",
label:component.label,
emoji:this.#handleComponentEmoji(msg,component.emoji),
color:this.#handleButtonComponentStyle(component.style),
mode:(component.style == discord.ButtonStyle.Link) ? "url" : "button",
url:component.url
})
}else if (component.type == discord.ComponentType.StringSelect){
components.push({
id:component.customId,
disabled:component.disabled,
type:"dropdown",
placeholder:component.placeholder,
options:component.options.map((option) => {
return {
id:option.value,
label:option.label,
description:option.description ?? null,
emoji:this.#handleComponentEmoji(msg,option.emoji ?? null)
}
})
})
}
})
rows.push({components})
})
//create message reply
let reply: ODTranscriptMessageReplyData|ODTranscriptInteractionReplyData|null = null
if (msg.reference && msg.reference.messageId && msg.reference.guildId){
//normal message reply
try{
const replyChannel = await msg.client.channels.fetch(msg.reference.channelId)
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)
reply = {
type:"message",
guild:msg.reference.guildId,
channel:msg.reference.channelId,
id:msg.reference.messageId,
user:replyUser,
content:(replyMessage.content != "") ? replyMessage.content : null
}
}
}
}catch{}
}else if (msg.interaction && msg.interaction.type == discord.InteractionType.ApplicationCommand){
//slash command reply
const member = await msg.guild.members.fetch(msg.interaction.user.id)
reply = {
type:"interaction",
name:msg.interaction.commandName,
user:this.#handleUserData(msg.interaction.user,member)
}
}
//create message reactions
const reactions: ODTranscriptReactionData[] = []
msg.reactions.cache.forEach((reaction) => {
const {count,emoji} = reaction
if (emoji instanceof discord.ReactionEmoji && !emoji.id && emoji.name){
//build-in emoji
reactions.push({
id:null,
name:null,
custom:false,
animated:false,
emoji:emoji.name,
amount:count,
super:false //unimplemented in discord.js
})
}else if (emoji instanceof discord.ReactionEmoji && emoji.id){
//custom emoji
reactions.push({
id:emoji.id,
name:emoji.name,
custom:true,
animated:emoji.animated ?? false,
emoji:(emoji.animated ? emoji.imageURL({extension:"gif"}) : emoji.imageURL({extension:"png"})) ?? "❌",
amount:count,
super:false //unimplemented in discord.js
})
}
})
//create message
final.push({
author,
guild:guild.id,
channel:channel.id,
id,
edited:(msg.editedAt) ? true : false,
timestamp:createdTimestamp,
type,
content:(msg.content != "") ? msg.content : null,
embeds,
files,
components:rows,
reply,
reactions
})
}
return final
}
/**Calculate a human-readable file size. Used in transcripts. */
calculateFileSize(bytes:number): {size:number, unit:"B"|"KB"|"MB"|"GB"|"TB"} {
if (bytes >= 1000000000000) return {size:(Math.round((bytes/1000000000000)*100)/100),unit:"TB"}
if (bytes >= 1000000000) return {size:(Math.round((bytes/1000000000)*100)/100),unit:"GB"}
else if (bytes >= 1000000) return {size:(Math.round((bytes/1000000)*100)/100),unit:"MB"}
else if (bytes >= 1000) return {size:(Math.round((bytes/1000)*100)/100),unit:"KB"}
else return {size:bytes,unit:"B"}
}
/**Get the `ODTranscriptEmojiData` from a discord.js component emoji. */
#handleComponentEmoji(message:discord.Message<true>, rawEmoji:discord.APIMessageComponentEmoji|null): ODTranscriptEmojiData|null {
if (!rawEmoji) return null
//return built-in emoji
if (rawEmoji.name) return {
id:null,
name:null,
custom:false,
animated:false,
emoji:rawEmoji.name
}
if (!rawEmoji.id) return null
const emoji = message.client.emojis.resolve(rawEmoji.id)
if (!emoji) return null
//return custom emoji
return {
id:emoji.id,
name:emoji.name,
custom:true,
animated:emoji.animated ?? false,
emoji:(emoji.animated ? emoji.imageURL({extension:"gif"}) : emoji.imageURL({extension:"png"}))
}
}
/**Create the `ODValidButtonColor` from the discord.js button style. */
#handleButtonComponentStyle(style:discord.ButtonStyle): 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 {
const userData: ODTranscriptUserData = {
id:user.id,
username:user.username,
displayname:user.displayName,
pfp:user.displayAvatarURL(),
tag:null,
color:"#ffffff"
}
if (user.flags && user.flags.has("VerifiedBot")) userData.tag = "verified"
else if (user.system) userData.tag = "system"
else if (user.bot) userData.tag = "app"
if (member) userData.color = member.roles.highest.hexColor.replace("#000000","#ffffff") as discord.HexColorString
return userData
}
}
export interface ODTranscriptCollectorIncludeSettings {
/**Collect messages from normal discord users. */
users: boolean,
/**Collect messages from bots & system users. */
bots: boolean,
/**Collect messages from this bot. */
client: boolean
}
export interface ODTranscriptMessageData {
/**The message author. */
author: ODTranscriptUserData,
/**The server this message originated from. */
guild: string,
/**The channel this message originated from. */
channel: string,
/**The id of this message. */
id: string,
/**Is this message edited? */
edited: boolean,
/**The unix timestamp of the creation of this message. */
timestamp: number,
/**The type of message. */
type: ODTranscriptMessageType,
/**The contents of this message. */
content: string|null,
/**The embeds of this message. */
embeds: ODTranscriptEmbedData[],
/**The files of this message. */
files: ODTranscriptFileData[],
/**The components (buttons & dropdowns) of this message. */
components: ODTranscriptComponentRowData[],
/**When this message is a reply to something, the data will be here. */
reply: (ODTranscriptMessageReplyData|ODTranscriptInteractionReplyData|null),
/**All reactions of htis message. */
reactions: ODTranscriptReactionData[]
}
export type ODTranscriptMessageType = "default"|"important"|"ephemeral"|"pinned.message"|"welcome.message"|"boost.message"|"thread.message"
export interface ODTranscriptUserData {
/**The id of this user. */
id: string,
/**The username of this user. */
username: string,
/**The display name of this user. */
displayname: string,
/**The profile picture url of this user. */
pfp: string,
/**The additional tag of this user. */
tag: "app"|"verified"|"system"|null,
/**When in a server, this is the color of the highest role. */
color: discord.HexColorString
}
export interface ODTranscriptEmbedData {
/**The title of this embed. */
title: string|null,
/**The description of this embed. */
description: string|null,
/**The author image of this embed. */
authorimg: string|null,
/**The author text of this embed. */
authortext: string|null,
/**The footer image of this embed. */
footerimg: string|null
/**The footer text of this embed. */
footertext: string|null,
/**The color of this embed (hex color). */
color: discord.HexColorString,
/**The image of this embed. */
image: string|null,
/**The thumbnail of this embed. */
thumbnail: string|null,
/**The url in the title of this embed. */
url: string|null,
/**All fields available in this embed. */
fields: ODTranscriptEmbedFieldData[]
}
export interface ODTranscriptEmbedFieldData {
/**The name of this embed field. */
name: string,
/**The value or contents of this embed field. */
value: string,
/**Is this field rendered inline? */
inline: boolean
}
export interface ODTranscriptFileData {
/**The file type or extension. */
type: string,
/**The size of this file. */
size: number,
/**The unit used for the size of this file. */
unit: "B"|"KB"|"MB"|"GB"|"TB",
/**The name of this file. */
name: string,
/**The url of this file. */
url: string,
/**Is this file a spoiler? */
spoiler: boolean,
/**The alternative text for this file. */
alt: string|null
}
export interface ODTranscriptComponentRowData {
/**All components (buttons & dropdowns) present in this action row. */
components: (ODTranscriptButtonComponentData|ODTranscriptDropdownComponentData)[]
}
export interface ODTranscriptComponentData {
/**The custom id of this component. */
id: string|null,
/**Is this component disabled? */
disabled: boolean
/**The type of this component. */
type: "button"|"dropdown"
}
export interface ODTranscriptButtonComponentData extends ODTranscriptComponentData {
/**The type of this component. */
type: "button"
/**The label of this button. */
label: string|null,
/**The emoji of this button. */
emoji: ODTranscriptEmojiData|null,
/**The color of this button. */
color: ODValidButtonColor,
/**Is this button a url or button? */
mode: "url"|"button",
/**The url of this button. */
url: string|null
}
export interface ODTranscriptDropdownComponentData extends ODTranscriptComponentData {
/**The type of this component. */
type: "dropdown"
/**The placeholder in this dropdown. */
placeholder: string|null,
/**All options available in this dropdown. */
options: ODTranscriptDropdownComponentOptionData[]
}
export interface ODTranscriptDropdownComponentOptionData {
/**The custom id of this dropdown option. */
id: string,
/**The label of this dropdown option. */
label: string|null,
/**The description of this dropdown option. */
description: string|null,
/**The emoji of this dropdown option. */
emoji: ODTranscriptEmojiData|null
}
export interface ODTranscriptReplyData {
/**The type of reply. */
type: "interaction"|"message",
}
export interface ODTranscriptInteractionReplyData extends ODTranscriptReplyData {
/**The type of reply. */
type: "interaction",
/**The bot used for this interaction. */
user: ODTranscriptUserData,
/**The name of the slash command used. */
name: string
}
export interface ODTranscriptMessageReplyData extends ODTranscriptReplyData {
/**The type of reply. */
type: "message",
/**The server this message originated from. */
guild: string,
/**The channel this message originated from. */
channel: string,
/**The id of this message. */
id: string,
/**The author of this message. */
user: ODTranscriptUserData,
/**The content of this message. */
content: string|null
}
export interface ODTranscriptEmojiData {
/**The id of this emoji. */
id: string|null,
/**The name of this emoji. */
name: string|null,
/**Is this emoji animated? */
animated: boolean,
/**Is this a custom emoji (img/gif)? */
custom: boolean,
/**The url or emoji. */
emoji: string,
}
export interface ODTranscriptReactionData extends ODTranscriptEmojiData {
/**The amount of emojis for this reaction. */
amount: number,
/**Is this a super (nitro) reaction? */
super: boolean
}
export interface ODTranscriptHtmlV2Data {
version:"2",
otversion:string,
language:string,
style:{
background:{
enableCustomBackground:boolean,
backgroundModus:"color"|"image",
backgroundData:string
},
header:{
enableCustomHeader:boolean,
decoColor:string,
backgroundColor:string,
textColor:string
},
stats:{
enableCustomStats:boolean,
backgroundColor:string,
keyTextColor:string,
valueTextColor:string,
hideBackgroundColor:string,
hideTextColor:string
},
favicon:{
enableCustomFavicon:boolean,
imageUrl:string
}
},
bot:{
name:string,
id:string,
pfp:string
},
ticket:{
name:string,
id:string,
guildname:string,
guildid:string,
guildinvite:string|false,
creatorname:string,
creatorid:string,
closedbyname:string,
closedbyid:string,
claimedname:string,
claimedid:string,
creatorpfp:string,
closedbypfp:string,
claimedpfp:string,
closedtime:number,
openedtime:number,
components:{
messages:number,
files:number,
embeds:number,
reactions:number,
interactions:{
dropdowns:number,
buttons:number,
total:number
},
attachments:{
invites:number,
images:number,
gifs:number,
stickers:number
}
},
roleColors:{id:string,color:string}[]
},
messages:{
author:{
name:string,
id:string,
color:string,
pfp:string,
bot:boolean,
verifiedBot:boolean,
system:boolean
},
content:string|false,
timestamp:number,
type:"normal",
important:boolean,
edited:boolean,
embeds:{
title:string|false,
description:string|false,
authorimg:string|false,
authortext:string|false,
footerimg:string|false,
footertext:string|false,
color:string,
image:string|false,
thumbnail:string|false,
url:string|false,
fields:{name:string,value:string,inline:boolean}[]
}[],
attachments:(
{
type:"FILE",
name:string,
fileType:string,
size:string,
url:string
}|{
type:"FILE:image",
name:string,
fileType:string,
size:string,
url:string
}|{
type:"URL:invite",
guildId:string,
guildName:string,
guildSize:Number,
guildOnline:Number,
image:string,
url:string
}|{
type:"URL:gif",
url:string
}|{
type:"BUILDIN:sticker",
name:string,
url:string
}
)[],
components:(
{
type:"buttons",
buttons:{
type:"interaction"|"url",
label:string|false,
icon:string|false,
color:"gray"|"green"|"red"|"blue",
id:string|false,
url:string|false,
disabled:boolean
}[]
}|{
type:"dropdown",
placeholder:string|false,
options:{
label:string|false,
icon:string|false,
description:string|false,
id:string|false
}[]
}|{
type:"reactions",
reactions:{
amount:number,
emoji:string,
type:"svg"|"image"|"gif"
}[]
}
)[],
reply:{
type:"reply"|"command"|false,
user?:{
name:string,
id:string,
color:string,
pfp:string,
bot:Boolean,
verifiedBot:Boolean,
system:Boolean
},
replyOptions?:{
content:string,
messageId:string,
channelId:string,
guildId:string
},
commandOptions?:{
interactionName:string,
interactionId:string
}
}
}[],
premium:{
enabled:boolean,
premiumToken:string,
customCredits:{
enable:boolean,
replaceText:string,
replaceURL:string,
enableReportBug:boolean
},
customHeaderUrl:{
enabled:boolean,
url:string,
text:string
},
customTranscriptUrl:{
enabled:boolean,
name:string
},
customFavicon:{
enabled:boolean,
image:string
},
additionalFlags:string[]
}
}
export interface ODTranscriptHtmlV2Response {
status:"success"|"error",
id:string,
time:number,
estimated:{
lastdump: number,
processtime:number,
waittime:number
},
transcriptstatus:{
value:2,
data:{
fetchedmsgs:true,
uploaded:true,
inqueue:true,
processed:false,
waiting:false,
available:false
}
}
}