import { Prettify } from '../internal/types.js'; type PluginHooksConstraint = { [Hook in keyof Hooks]?: Record; }; type PluginPerHookSetup = { [Hook in keyof THooks & keyof Hooks]: (...params: Parameters) => THooks[Hook]; }; type Plugin = { name: TName; setup: (params: { name: string; }) => PluginPerHookSetup; }; type AnyPlugin = Plugin>; type Hooks = Required; type AnyFunction = (...args: Array) => any; /** * Turn the plugin into a simplified type representation of itself that can be more easily manipulated. * * No value of this type exists at runtime, it's only used for type manipulation. */ type SimplifyPlugin = { name: TPlugin["name"]; hooks: TPlugin extends Plugin ? THooks : Record; }; /** * Return a tuple of simplified plugins that affect the given hook. * * Plugins that don't affect the hook are removed from the tuple. The order of the tuple is preserved. * * @internal */ type FilterPluginsByHook> = TPlugins extends [infer Head, ...infer Tail] ? Head extends AnyPlugin ? Tail extends Array ? undefined extends SimplifyPlugin["hooks"][THook] ? FilterPluginsByHook : [SimplifyPlugin, ...FilterPluginsByHook] : [] : [] : []; type OmitKeysByValue = { [Key in keyof T as T[Key] extends ValueType ? never : Key]: T[Key]; }; type OverridePluginParamsForHook> = TPlugins extends [...infer Head, infer Tail] ? Tail extends SimplifyPlugin ? Head extends SimplifyPlugin[] ? Omit, keyof Tail["hooks"][THook]> & Tail["hooks"][THook] : never : never : Record; /** * Compute plugin-added parameters for a hook. * * Plugins are applied in order, so the last plugin to define a parameter wins. * Plugins that don't define any value for the given hook are ignored. * * @internal */ type AddedParam, THook extends keyof Hooks> = Prettify>, never>>; /** * Extend the signature of a function to receive extra parameters. * * Used to inject plugin-defined parameters into hooks. */ type AddParam = [Param] extends [never] ? Func : Func extends (params: infer Params) => infer ReturnType ? (params: Params & Param) => ReturnType : never; type ExtendedHooks> = { [Hook in keyof Hooks]?: Hooks[Hook] extends AnyFunction ? AddParam> : never; }; export type { AddedParam, AnyPlugin, ExtendedHooks, Hooks, Plugin, PluginHooksConstraint };