import { Callback as LambdaCallback, Context as LambdaContext, Handler as LambdaHandler } 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 streamifyResponse?: Boolean } export interface Request< TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext, TInternal extends Record = {} > { event: TEvent context: TContext response: TResult | null error: TErr | null internal: TInternal } declare type MiddlewareFn< TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext, TInternal extends Record = {} > = (request: Request) => any export interface MiddlewareObj< TEvent = unknown, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext, TInternal extends Record = {} > { 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< TEvent, TResult, TContext extends LambdaContext = LambdaContext > = ( event: TEvent, context: TContext, callback: LambdaCallback ) => // eslint-disable-next-line @typescript-eslint/no-invalid-void-type void | Promise | TResult type MiddyInputPromiseHandler< TEvent, TResult, TContext extends LambdaContext = LambdaContext > = (event: TEvent, context: TContext) => Promise export interface MiddyfiedHandler< TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext, TInternal extends Record = {} > extends MiddyInputHandler, MiddyInputPromiseHandler { use: UseFn before: AttachMiddlewareFn after: AttachMiddlewareFn onError: AttachMiddlewareFn handler: ( handler: MiddlewareHandler< LambdaHandler, TContext > ) => MiddyfiedHandler } declare type AttachMiddlewareFn< TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext, TInternal extends Record = {} > = ( middleware: MiddlewareFn ) => MiddyfiedHandler declare type AttachMiddlewareObj< TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext, TInternal extends Record = {} > = ( middleware: MiddlewareObj ) => MiddyfiedHandler declare type UseFn< TEvent = any, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext, TInternal extends Record = {} > = >( middlewares: TMiddleware | TMiddleware[] ) => TMiddleware extends MiddlewareObj< infer TMiddlewareEvent, any, Error, infer TMiddlewareContext, infer TMiddlewareInternal > ? MiddyfiedHandler< TMiddlewareEvent & TEvent, TResult, TErr, TMiddlewareContext & TContext, TMiddlewareInternal & TInternal > // always true : never declare type MiddlewareHandler< THandler extends LambdaHandler, 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< TEvent = unknown, TResult = any, TErr = Error, TContext extends LambdaContext = LambdaContext, TInternal extends Record = {} > ( handler?: | MiddlewareHandler, TContext> | PluginObject, plugin?: PluginObject ): MiddyfiedHandler declare namespace middy { export { Request, PluginHook, PluginHookWithMiddlewareName, PluginObject, MiddlewareFn, MiddlewareObj, MiddyfiedHandler } } export default middy