import { Container , InjectionToken } from '@decorators/di' ; /**
 * IO Middleware class registration DI token
 */ export const IO_MIDDLEWARE = new InjectionToken ( 'IO_MIDDLEWARE' ) ; export interface Type extends Function { new ( ... args ) ; } export type NextFunction = ( err ? : Error ) => void ; export interface export interface ServerMiddleware { use ( io , socket , next ) : void ; } export interface export interface Middleware { use ( io , socket , args , next ) : void ; } export param { Type | InjectionToken } middleware returns { RequestHandler } export function middlewareHandler ( middleware ) { return function ( ... args ) : any { const next = args [ args . length - 1 ] ; let instance ; try { instance = Container . get ( middleware ) ; } catch { try { instance = new ( middleware as Type ) ( ) ; } catch { instance = middleware as any ; } } const use = ( instance as Middleware | ServerMiddleware ) . use ? ( instance as Middleware | ServerMiddleware ) . use : instance as Type ; try { const result = use . apply ( instance , args ) ; if ( result instanceof Promise ) { result . catch ( next ) ; } return result ; } catch ( e ) { return next ( e ) ; } } ; } param { Type [ ] } middleware param { any [ ] } args returns { Promise < * > } export function executeMiddleware ( middleware , args = [ ] ) { function iteratee ( done , i = 0 ) { try { middlewareHandler ( middleware [ i ] ) ( ... args , ( err ) => { if ( err ) { return done ( err ) ; } if ( i === middleware . length - 1 ) { return done ( null ) ; } iteratee ( done , ++ i ) ; } ) ; } catch ( e ) { done ( e ) ; } } return new Promise ( ( resolve , reject ) => { if ( middleware === undefined || middleware . length === 0 ) { return resolve ( ) ; } iteratee ( ( err ) => err ? reject ( err ) : resolve ( ) ) ; } ) ; }