import { Context as LambdaContext, Handler as LambdaHandler, Callback as LambdaCallback } from 'aws-lambda' declare type PluginHook = () => void declare type PluginHookWithMiddlewareName = (middlewareName: string) => void declare type PluginHookPromise = (request: Request) => Promise | unknown interface PluginObject { internal?: any beforePrefetch?: PluginHook requestStart?: PluginHook beforeMiddleware?: PluginHookWithMiddlewareName afterMiddleware?: PluginHookWithMiddlewareName beforeHandler?: PluginHook timeoutEarlyInMillis?: number timeoutEarlyResponse?: PluginHook afterHandler?: PluginHook requestEnd?: PluginHookPromise } interface Request { event: TEvent context: TContext response: TResult | null error: TErr | null internal: { [key: string]: any } } declare type MiddlewareFn = (request: Request) => any export interface MiddlewareObj { before?: MiddlewareFn after?: MiddlewareFn onError?: MiddlewareFn } // The AWS provided Handler type uses void | Promise so we have no choice but to follow and suppress the linter warning // eslint-disable-next-line @typescript-eslint/no-invalid-void-type type MiddyInputHandler = (event: TEvent, context: TContext, callback: LambdaCallback) => void | Promise type MiddyInputPromiseHandler = (event: TEvent, context: TContext,) => Promise export interface MiddyfiedHandler extends MiddyInputHandler, MiddyInputPromiseHandler { use: UseFn before: AttachMiddlewareFn after: AttachMiddlewareFn onError: AttachMiddlewareFn } declare type AttachMiddlewareFn = (middleware: MiddlewareFn) => MiddyfiedHandler declare type AttachMiddlewareObj = (middleware: MiddlewareObj) => MiddyfiedHandler declare type UseFn = (middlewares: MiddlewareObj | Array>) => MiddyfiedHandler declare type MiddlewareHandler, TContext extends LambdaContext = LambdaContext> = THandler extends LambdaHandler // always true ? MiddyInputHandler : never /** * Middy factory function. Use it to wrap your existing handler to enable middlewares on it. * @param handler your original AWS Lambda function * @param plugin wraps around each middleware and handler to add custom lifecycle behaviours (e.g. to profile performance) */ declare function middy (handler?: MiddlewareHandler, TContext>, plugin?: PluginObject): MiddyfiedHandler declare namespace middy { export { Request, PluginHook, PluginHookWithMiddlewareName, PluginObject, MiddlewareFn, MiddlewareObj, MiddyfiedHandler } } export default middy