plugin.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { Message, ClientEvents } from "discord.js";
  2. import { EsModuleClass, isModuleClass } from "../util";
  3. export type CommandType = "prefix" | "mention";
  4. export interface ICommand extends CommandOptions {
  5. action : MessageCommand;
  6. }
  7. export interface CommandOptions {
  8. type: CommandType;
  9. pattern: string | RegExp;
  10. documentation?: CommandDocumentation;
  11. auth?: boolean;
  12. allowDM?: boolean;
  13. }
  14. export interface CommandDocumentation {
  15. description: string;
  16. example: string;
  17. }
  18. export type MessageCommand = (data: ICommandData) => void | Promise<void>;
  19. export interface ICommandData {
  20. message: Message;
  21. contents: string | RegExpMatchArray;
  22. }
  23. export type BotEvent = (data: BotEventData, ...params: unknown[]) => void | Promise<void>;
  24. export interface BotEventData {
  25. actionsDone: boolean;
  26. }
  27. interface CustomEventType {
  28. message: [string];
  29. indirectMention: [string];
  30. directMention: [string];
  31. postMessage: [string];
  32. }
  33. const customEvents : Set<keyof CustomEventType> = new Set(["directMention", "indirectMention", "message", "postMessage"]);
  34. export type EventType = keyof ClientEvents | keyof CustomEventType;
  35. export function isCustomEvent(s: string): s is keyof CustomEventType {
  36. return customEvents.has(s as keyof CustomEventType);
  37. }
  38. export interface IPlugin {
  39. PLUGIN_TYPE?: string;
  40. botCommands?: ICommand[];
  41. botEvents?: { [action in EventType]?: BotEvent };
  42. start?(): Promise<void>;
  43. }
  44. export function Command(opts: CommandOptions) : MethodDecorator {
  45. return function<T>(target: unknown, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>): void {
  46. if(!descriptor.value)
  47. throw new Error("The decorator value must be initialized!");
  48. const plg = target as IPlugin;
  49. if (!plg.botCommands)
  50. plg.botCommands = [];
  51. plg.botCommands.push({
  52. action: descriptor.value as unknown as MessageCommand,
  53. ...opts
  54. });
  55. };
  56. }
  57. export function Event(type: EventType): MethodDecorator {
  58. return function<T>(target: unknown, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>): void {
  59. if(!descriptor.value)
  60. throw new Error("The decorator value must be initialized!");
  61. const plg = target as IPlugin;
  62. if(!plg.botEvents)
  63. plg.botEvents = {};
  64. plg.botEvents[type] = descriptor.value as unknown as BotEvent;
  65. };
  66. }
  67. export const PLUGIN_TYPE_DESCRIPTOR = "PLUGIN_TYPE_DESCRIPTOR";
  68. export function Plugin<T extends {new(...params: unknown[]): unknown}>(base: T): void {
  69. base.prototype.PLUGIN_TYPE = PLUGIN_TYPE_DESCRIPTOR;
  70. }
  71. export function isPlugin(obj: unknown): obj is EsModuleClass<IPlugin> {
  72. return isModuleClass<IPlugin>(obj) && obj.prototype.PLUGIN_TYPE == PLUGIN_TYPE_DESCRIPTOR;
  73. }