import { ConfigParserFn, CustomOverrideCriteriaFunctions, PluginOptions } from "../config/configTypes"; import { Awaitable } from "../utils"; import { AfterUnloadPluginData, AnyPluginData, BeforeLoadPluginData, GlobalPluginData, GuildPluginData } from "./PluginData"; import { MessageCommandBlueprint } from "../commands/messageCommands/messageCommandBlueprint"; import { EventListenerBlueprint } from "../events/EventListenerBlueprint"; import { BasePluginType } from "./pluginTypes"; import { GuildEvent, ValidEvent } from "../events/eventTypes"; import { AnySlashCommandSignature, SlashCommandBlueprint } from "../commands/slashCommands/slashCommandBlueprint"; import { SlashGroupBlueprint } from "../commands/slashCommands/slashGroupBlueprint"; /** * Each value in the public interface is a function that returns the actual * value that other plugins can access when using the interface. * This allows other plugins to be unaware of the pluginData object for the * plugin with the public interface. */ export interface PluginBlueprintPublicInterface> { [key: string]: (pluginData: TPluginData) => any; } export type ResolvedPluginBlueprintPublicInterface> = { [P in keyof T]: ReturnType; }; interface BasePluginBlueprint> { /** * **[Required]** Internal name for the plugin */ name: string; /** * Arbitrary info about the plugin, e.g. description. * This property is mainly here to set a convention, as it's not actually used in Knub itself. */ info?: any; /** * The plugin's default options, including overrides */ defaultOptions?: PluginOptions; /** * Parses the plugin's config from untrusted input, returning the correct type for the config or throwing an error */ configParser: ConfigParserFn; messageCommands?: Array>; /** * Commands that are automatically registered on plugin load */ slashCommands?: Array | SlashGroupBlueprint>; /** * If this plugin includes any custom overrides, this function evaluates them */ customOverrideCriteriaFunctions?: CustomOverrideCriteriaFunctions; /** * Public interface for this plugin */ public?: PluginBlueprintPublicInterface; /** * This function is called before the plugin is loaded. * At this point, there are two guarantees: * * 1. Other plugins haven't yet interacted with this plugin * 2. Other plugins can't interact with this plugin during this function * * Similarly, `PluginData.hasPlugin()` and `PluginData.getPlugin()` are unavailable. */ beforeLoad?: (pluginData: BeforeLoadPluginData) => Awaitable; /** * This function is called after the plugin has been loaded. * At this point, make sure to consider the following: * * 1. Commands and event handlers are already registered. * If you need to set up dependencies for them, do it in `beforeLoad()`. * 2. Other plugins are able to interact with this plugin's public interfaces */ afterLoad?: (pluginData: TPluginData) => Awaitable; /** * This function is called before the plugin is unloaded. * At this point, make sure to consider the following: * * 1. Commands and event handlers are still registered. * If you need to unload their dependencies, do it in `afterUnload()`. * 2. Other plugins are still able to interact with this plugin's public interfaces */ beforeUnload?: (pluginData: TPluginData) => Awaitable; /** * This function is called after the plugin has been unloaded. * At this point, it is guaranteed that other plugins can't interact with this plugin anymore. * Similarly, `PluginData.hasPlugin()` and `PluginData.getPlugin()` are unavailable. */ afterUnload?: (pluginData: AfterUnloadPluginData) => Awaitable; } /** * Blueprint for a plugin that can only be loaded in a guild context */ export interface GuildPluginBlueprint> extends BasePluginBlueprint { /** * Function that returns other plugins that are required for this plugin to function. * They will be loaded before this plugin. */ dependencies?: () => Array> | Promise>>; /** * Event listeners that are automatically registered on plugin load */ events?: Array>; } /** * This is used in conjunction with arr[keyof arr] syntax in AnyGuildEventListenerBlueprint to create * a union type of event listener blueprints for each different guild event. * * We can't simply do EventListenerBlueprint, GuildEvent>, because then adding * an event listener blueprint for a single event isn't valid in TS strict mode anymore, as technically that specific * event listener blueprint doesn't accept *every* GuildEvent, just the specific one. */ type GuildEventListenerBlueprintsHelper> = { [K in GuildEvent]: EventListenerBlueprint; }; export type AnyGuildEventListenerBlueprint> = GuildEventListenerBlueprintsHelper[keyof GuildEventListenerBlueprintsHelper]; /** * Blueprint for a plugin that can only be loaded in a global context */ export interface GlobalPluginBlueprint> extends BasePluginBlueprint { /** * Function that returns other plugins that are required for this plugin to function. * They will be loaded before this plugin. */ dependencies?: () => Array> | Promise>>; /** * Event listeners that are automatically registered on plugin load */ events?: Array>; } /** * This is used in conjunction with arr[keyof arr] syntax in AnyGlobalEventListenerBlueprint to create * a union type of event listener blueprints for each different global event (i.e. each ValidEvent). * * We can't simply do EventListenerBlueprint, ValidEvent>, because then adding * an event listener blueprint for a single event isn't valid in TS strict mode anymore, as technically that specific * event listener blueprint doesn't accept *every* ValidEvent, just the specific one. */ type GlobalEventListenerBlueprintsHelper> = { [K in ValidEvent]: EventListenerBlueprint; }; export type AnyGlobalEventListenerBlueprint> = GlobalEventListenerBlueprintsHelper[keyof GlobalEventListenerBlueprintsHelper]; export type AnyPluginBlueprint = GuildPluginBlueprint | GlobalPluginBlueprint; type PluginBlueprintCreator = (blueprint: TBlueprint) => TBlueprint; /** * Helper function that creates a plugin blueprint for a guild plugin. * * To specify `TPluginType` for additional type hints, use: `guildPlugin()(blueprint)` */ export declare function guildPlugin>>(blueprint: TBlueprint): TBlueprint; /** * Helper function with no arguments. Specify `TPluginType` for type hints and return self. */ export declare function guildPlugin(): PluginBlueprintCreator>>; /** * Helper function that creates a plugin blueprint for a global plugin. * * To specify `TPluginType` for additional type hints, use: `globalPlugin()(blueprint)` */ export declare function globalPlugin>>(blueprint: TBlueprint): TBlueprint; /** * Helper function with no arguments. Specify `TPluginType` for type hints and return self */ export declare function globalPlugin(): PluginBlueprintCreator>>; export {};