/* * Plugins can be inserted on all commands and are emitted * * 1. On ready event, where all commands are loaded. * 2. On corresponding observable (when command triggers) * * The goal of plugins is to organize commands and * provide extensions to repetitive patterns * examples include refreshing modules, * categorizing commands, cool-downs, permissions, etc. * Plugins are reminiscent of middleware in express. */ import type { Err, Ok, Result } from 'ts-results-es'; import type { CommandType, EventType, PluginType } from '../core/structures'; import type { CommandArgsMatrix, CommandModule, EventArgsMatrix, EventModule } from './module'; import type { InitArgs } from './core'; import type { Awaitable } from './handler'; import { Processed } from './core'; export type PluginResult = Awaitable; export type VoidResult = Result; export interface Controller { next: () => Ok; stop: () => Err; } export interface Plugin { type: PluginType; execute: (...args: Args) => PluginResult; } export interface InitPlugin { type: PluginType.Init; execute: (...args: Args) => PluginResult; } export interface ControlPlugin { type: PluginType.Control; execute: (...args: Args) => PluginResult; } export type AnyCommandPlugin = ControlPlugin | InitPlugin<[InitArgs>]>; export type AnyEventPlugin = ControlPlugin | InitPlugin<[InitArgs>]>; export type CommandArgs< I extends CommandType = CommandType, J extends PluginType = PluginType, > = CommandArgsMatrix[I][J]; export type EventArgs< I extends EventType = EventType, J extends PluginType = PluginType, > = EventArgsMatrix[I][J];