type HookMethod = ( options: Options ) => Result | Promise; type BeforeHook = (options: Options) => void | Promise; type ErrorHook = ( error: Error, options: Options ) => unknown | 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;