import { Router , Express , IRouterConfig , IDinoProperties , IMiddlewareProvider } from '../types' ; import { DinoUtility , ObjectUtility , DinoParser } from '../utility' ; import { IDIContainer , IDinoRouter } from '../interfaces' ; import { IUserIdentity } from '../providers' ; import { Middleware , MiddlewareAsync , ActionFilter , ActionFilterAsync , ResultFilter , ResultFilterAsync , ExceptionFilter , ExceptionFilterAsync } from '../filter' ; export class DinoRouter implements IDinoRouter { private router : Router ; private diContainer : IDIContainer ; private enableTaskContext : boolean ; constructor ( config ) { this . diContainer = config . diContainer ; this . router = config . routerCb ( ) ; this . enableTaskContext = config . enableTaskContext ; } resolve < T > ( middleware , dino ) { let o = this . diContainer . resolve < T > ( middleware ) ; return this . enableTaskContext ? ObjectUtility . replaceObjectReferences ( o , dino . context , IUserIdentity ) : o ; } registerMiddleware ( middleware ) { let provider = DinoParser . parseMiddlewareProvider ( middleware ) ; if ( DinoUtility . isSyncMiddleWare ( provider . useClass ) ) { this . router . use ( ( req , res , next ) => { let mware = this . resolve < Middleware > ( provider . useClass , res . locals . dino ) ; mware . invoke ( req , res , next , provider . data ) ; } ) ; } else if ( DinoUtility . isAsyncMiddleWare ( provider . useClass ) ) { this . router . use ( async ( req , res , next ) => { let mware = this . resolve < MiddlewareAsync > ( provider . useClass , res . locals . dino ) ; try { await mware . invoke ( req , res , next , provider . data ) ; } catch ( err ) { next ( err ) ; } } ) ; } } registerBeginActionFilter ( filter ) { let provider = DinoParser . parseMiddlewareProvider ( filter ) ; if ( DinoUtility . isSyncActionFilter ( provider . useClass ) ) { this . router . use ( ( req , res , next ) => { let mware = this . resolve < ActionFilter > ( provider . useClass , res . locals . dino ) ; mware . beforeExecution ( req , res , next , provider . data ) ; } ) ; } else if ( DinoUtility . isAsyncActionFilter ( provider . useClass ) ) { this . router . use ( async ( req , res , next ) => { let mware = this . resolve < ActionFilterAsync > ( provider . useClass , res . locals . dino ) ; try { await mware . beforeExecution ( req , res , next , provider . data ) ; } catch ( err ) { next ( err ) ; } } ) ; } } registerAfterActionFilter ( filter ) { let provider = DinoParser . parseMiddlewareProvider ( filter ) ; if ( DinoUtility . isSyncActionFilter ( provider . useClass ) ) { this . router . use ( ( req , res , next ) => { let mware = this . resolve < ActionFilter > ( provider . useClass , res . locals . dino ) ; mware . afterExecution ( req , res , next , res . locals . dino . result , provider . data ) ; } ) ; } else if ( DinoUtility . isAsyncActionFilter ( provider . useClass ) ) { this . router . use ( async ( req , res , next ) => { let mware = this . resolve < ActionFilterAsync > ( provider . useClass , res . locals . dino ) ; try { await mware . afterExecution ( req , res , next , res . locals . dino . result , provider . data ) ; } catch ( err ) { next ( err ) ; } } ) ; } } registerResultFilter ( filter ) { let provider = DinoParser . parseMiddlewareProvider ( filter ) ; if ( DinoUtility . isSyncResultFilter ( provider . useClass ) ) { this . router . use ( ( req , res , next ) => { let mware = this . resolve < ResultFilter > ( provider . useClass , res . locals . dino ) ; mware . invoke ( req , res , next , res . locals . dino . result , provider . data ) ; } ) ; } else if ( DinoUtility . isAsyncResultFilter ( provider . useClass ) ) { this . router . use ( async ( req , res , next ) => { let mware = this . resolve < ResultFilterAsync > ( provider . useClass , res . locals . dino ) ; try { await mware . invoke ( req , res , next , res . locals . dino . result , provider . data ) ; } catch ( err ) { next ( err ) ; } } ) ; } } registerExceptionFilter ( app , uri , middleware ) { let provider = DinoParser . parseMiddlewareProvider ( middleware ) ; if ( DinoUtility . isSyncExceptionFilter ( provider . useClass ) ) { app . use ( uri , ( err , req , res , next ) => { let mware = this . resolve < ExceptionFilter > ( provider . useClass , res . locals . dino ) ; mware . invoke ( err , req , res , next ) ; } ) ; } else if ( DinoUtility . isAsyncExceptionFilter ( provider . useClass ) ) { app . use ( uri , async ( err , req , res , next ) => { let mware = this . resolve < ExceptionFilterAsync > ( provider . useClass , res . locals . dino ) ; try { await mware . invoke ( err , req , res , next ) ; } catch ( err ) { next ( err ) ; } } ) ; } } expressRouter ( ) { return this . router ; } registerExceptionFilters ( app , uri , filters ) { for ( const filter of filters ) { this . registerExceptionFilter ( app , uri , filter ) ; } } registerMiddlewares ( middlewares ) { for ( const middleware of middlewares ) { this . registerMiddleware ( middleware ) ; } } registerBeginActionFilters ( actionFilters ) { for ( const filter of actionFilters ) { this . registerBeginActionFilter ( filter ) ; } } registerAfterActionFilters ( actionFilters ) { for ( const filter of actionFilters ) { this . registerAfterActionFilter ( filter ) ; } } registerResultFilters ( resultFilters ) { for ( const filter of resultFilters ) { this . registerResultFilter ( filter ) ; } } static create ( config ) { return new DinoRouter ( config ) ; } }