index.d.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. type HookMethod<Options, Result> = (
  2. options: Options
  3. ) => Result | Promise<Result>
  4. type BeforeHook<Options> = (options: Options) => void | Promise<void>
  5. type ErrorHook<Options, Error> = (
  6. error: Error,
  7. options: Options
  8. ) => void | Promise<void>
  9. type AfterHook<Options, Result> = (
  10. result: Result,
  11. options: Options
  12. ) => void | Promise<void>
  13. type WrapHook<Options, Result> = (
  14. hookMethod: HookMethod<Options, Result>,
  15. options: Options
  16. ) => Result | Promise<Result>
  17. type AnyHook<Options, Result, Error> =
  18. | BeforeHook<Options>
  19. | ErrorHook<Options, Error>
  20. | AfterHook<Options, Result>
  21. | WrapHook<Options, Result>
  22. type TypeStoreKeyLong = 'Options' | 'Result' | 'Error'
  23. type TypeStoreKeyShort = 'O' | 'R' | 'E'
  24. type TypeStore =
  25. | ({ [key in TypeStoreKeyLong]?: any } &
  26. { [key in TypeStoreKeyShort]?: never })
  27. | ({ [key in TypeStoreKeyLong]?: never } &
  28. { [key in TypeStoreKeyShort]?: any })
  29. type GetType<
  30. Store extends TypeStore,
  31. LongKey extends TypeStoreKeyLong,
  32. ShortKey extends TypeStoreKeyShort
  33. > = LongKey extends keyof Store
  34. ? Store[LongKey]
  35. : ShortKey extends keyof Store
  36. ? Store[ShortKey]
  37. : any
  38. export interface HookCollection<
  39. HooksType extends Record<string, TypeStore> = Record<
  40. string,
  41. { Options: any; Result: any; Error: any }
  42. >,
  43. HookName extends keyof HooksType = keyof HooksType
  44. > {
  45. /**
  46. * Invoke before and after hooks
  47. */
  48. <Name extends HookName>(
  49. name: Name | Name[],
  50. hookMethod: HookMethod<
  51. GetType<HooksType[Name], 'Options', 'O'>,
  52. GetType<HooksType[Name], 'Result', 'R'>
  53. >,
  54. options?: GetType<HooksType[Name], 'Options', 'O'>
  55. ): Promise<GetType<HooksType[Name], 'Result', 'R'>>
  56. /**
  57. * Add `before` hook for given `name`
  58. */
  59. before<Name extends HookName>(
  60. name: Name,
  61. beforeHook: BeforeHook<GetType<HooksType[Name], 'Options', 'O'>>
  62. ): void
  63. /**
  64. * Add `error` hook for given `name`
  65. */
  66. error<Name extends HookName>(
  67. name: Name,
  68. errorHook: ErrorHook<
  69. GetType<HooksType[Name], 'Options', 'O'>,
  70. GetType<HooksType[Name], 'Error', 'E'>
  71. >
  72. ): void
  73. /**
  74. * Add `after` hook for given `name`
  75. */
  76. after<Name extends HookName>(
  77. name: Name,
  78. afterHook: AfterHook<
  79. GetType<HooksType[Name], 'Options', 'O'>,
  80. GetType<HooksType[Name], 'Result', 'R'>
  81. >
  82. ): void
  83. /**
  84. * Add `wrap` hook for given `name`
  85. */
  86. wrap<Name extends HookName>(
  87. name: Name,
  88. wrapHook: WrapHook<
  89. GetType<HooksType[Name], 'Options', 'O'>,
  90. GetType<HooksType[Name], 'Result', 'R'>
  91. >
  92. ): void
  93. /**
  94. * Remove added hook for given `name`
  95. */
  96. remove<Name extends HookName>(
  97. name: Name,
  98. hook: AnyHook<
  99. GetType<HooksType[Name], 'Options', 'O'>,
  100. GetType<HooksType[Name], 'Result', 'R'>,
  101. GetType<HooksType[Name], 'Error', 'E'>
  102. >
  103. ): void
  104. /**
  105. * Public API
  106. */
  107. api: Pick<
  108. HookCollection<HooksType>,
  109. 'before' | 'error' | 'after' | 'wrap' | 'remove'
  110. >
  111. }
  112. export interface HookSingular<Options, Result, Error> {
  113. /**
  114. * Invoke before and after hooks
  115. */
  116. (hookMethod: HookMethod<Options, Result>, options?: Options): Promise<Result>
  117. /**
  118. * Add `before` hook
  119. */
  120. before(beforeHook: BeforeHook<Options>): void
  121. /**
  122. * Add `error` hook
  123. */
  124. error(errorHook: ErrorHook<Options, Error>): void
  125. /**
  126. * Add `after` hook
  127. */
  128. after(afterHook: AfterHook<Options, Result>): void
  129. /**
  130. * Add `wrap` hook
  131. */
  132. wrap(wrapHook: WrapHook<Options, Result>): void
  133. /**
  134. * Remove added hook
  135. */
  136. remove(hook: AnyHook<Options, Result, Error>): void
  137. /**
  138. * Public API
  139. */
  140. api: Pick<
  141. HookSingular<Options, Result, Error>,
  142. 'before' | 'error' | 'after' | 'wrap' | 'remove'
  143. >
  144. }
  145. type Collection = new <
  146. HooksType extends Record<string, TypeStore> = Record<
  147. string,
  148. { Options: any; Result: any; Error: any }
  149. >
  150. >() => HookCollection<HooksType>
  151. type Singular = new <
  152. Options = any,
  153. Result = any,
  154. Error = any
  155. >() => HookSingular<Options, Result, Error>
  156. interface Hook {
  157. new <
  158. HooksType extends Record<string, TypeStore> = Record<
  159. string,
  160. { Options: any; Result: any; Error: any }
  161. >
  162. >(): HookCollection<HooksType>
  163. /**
  164. * Creates a collection of hooks
  165. */
  166. Collection: Collection
  167. /**
  168. * Creates a nameless hook that supports strict typings
  169. */
  170. Singular: Singular
  171. }
  172. export const Hook: Hook
  173. export const Collection: Collection
  174. export const Singular: Singular
  175. export default Hook