type HookMethod = ( options: Options ) => Result | Promise type BeforeHook = (options: Options) => void | Promise type ErrorHook = ( error: Error, options: Options ) => void | Promise type AfterHook = ( result: Result, options: Options ) => void | Promise type WrapHook = ( hookMethod: HookMethod, options: Options ) => Result | Promise type AnyHook = | BeforeHook | ErrorHook | AfterHook | WrapHook type TypeStoreKeyLong = 'Options' | 'Result' | 'Error' type TypeStoreKeyShort = 'O' | 'R' | 'E' type TypeStore = | ({ [key in TypeStoreKeyLong]?: any } & { [key in TypeStoreKeyShort]?: never }) | ({ [key in TypeStoreKeyLong]?: never } & { [key in TypeStoreKeyShort]?: any }) type GetType< Store extends TypeStore, LongKey extends TypeStoreKeyLong, ShortKey extends TypeStoreKeyShort > = LongKey extends keyof Store ? Store[LongKey] : ShortKey extends keyof Store ? Store[ShortKey] : any export interface HookCollection< HooksType extends Record = Record< string, { Options: any; Result: any; Error: any } >, HookName extends keyof HooksType = keyof HooksType > { /** * Invoke before and after hooks */ ( name: Name | Name[], hookMethod: HookMethod< GetType, GetType >, options?: GetType ): Promise> /** * Add `before` hook for given `name` */ before( name: Name, beforeHook: BeforeHook> ): void /** * Add `error` hook for given `name` */ error( name: Name, errorHook: ErrorHook< GetType, GetType > ): void /** * Add `after` hook for given `name` */ after( name: Name, afterHook: AfterHook< GetType, GetType > ): void /** * Add `wrap` hook for given `name` */ wrap( name: Name, wrapHook: WrapHook< GetType, GetType > ): void /** * Remove added hook for given `name` */ remove( name: Name, hook: AnyHook< GetType, GetType, GetType > ): void /** * Public API */ api: Pick< HookCollection, 'before' | 'error' | 'after' | 'wrap' | 'remove' > } export interface HookSingular { /** * Invoke before and after hooks */ (hookMethod: HookMethod, options?: Options): Promise /** * Add `before` hook */ before(beforeHook: BeforeHook): void /** * Add `error` hook */ error(errorHook: ErrorHook): void /** * Add `after` hook */ after(afterHook: AfterHook): void /** * Add `wrap` hook */ wrap(wrapHook: WrapHook): void /** * Remove added hook */ remove(hook: AnyHook): void /** * Public API */ api: Pick< HookSingular, 'before' | 'error' | 'after' | 'wrap' | 'remove' > } type Collection = new < HooksType extends Record = Record< string, { Options: any; Result: any; Error: any } > >() => HookCollection type Singular = new < Options = any, Result = any, Error = any >() => HookSingular interface Hook { new < HooksType extends Record = Record< string, { Options: any; Result: any; Error: any } > >(): HookCollection /** * Creates a collection of hooks */ Collection: Collection /** * Creates a nameless hook that supports strict typings */ Singular: Singular } export const Hook: Hook export const Collection: Collection export const Singular: Singular export default Hook