import { Controller , ValidateParam , FieldErrors , ValidateError , TsoaRoute } from 'tsoa' ; import { iocContainer } from './../src/ioc' ; import { UserController } from './../src/controllers/UserController' ; import { expressAuthentication } from './../src/auth' ; const models = { "IUserModel" : { "properties" : { "_id" : { "dataType" : "string" } , "id" : { "dataType" : "string" } , "email" : { "dataType" : "string" , "required" : true } , "name" : { "dataType" : "string" , "required" : true } , } , } , "IPaginationModel" : { "properties" : { "count" : { "dataType" : "double" , "required" : true } , "page" : { "dataType" : "double" , "required" : true } , "limit" : { "dataType" : "double" , "required" : true } , "totalPages" : { "dataType" : "double" , "required" : true } , "docs" : { "dataType" : "array" , "array" : { "dataType" : "any" } , "required" : true } , } , } , } ; export function RegisterRoutes ( app ) { app . get ( '/service/users/:id' , function ( request , response , next ) { const args = { id : { "in" : "path" , "name" : "id" , "required" : true , "dataType" : "string" } , } ; let validatedArgs = [ ] ; try { validatedArgs = getValidatedArgs ( args , request ) ; } catch ( err ) { return next ( err ) ; } const controller = iocContainer . get < UserController > ( UserController ) ; if ( typeof controller [ 'setStatus' ] === 'function' ) { ( < any > controller ) . setStatus ( undefined ) ; } const promise = controller . getById . apply ( controller , validatedArgs ) ; promiseHandler ( controller , promise , response , next ) ; } ) ; app . get ( '/service/users' , function ( request , response , next ) { const args = { page : { "in" : "query" , "name" : "page" , "required" : true , "dataType" : "double" } , limit : { "in" : "query" , "name" : "limit" , "required" : true , "dataType" : "double" } , fields : { "in" : "query" , "name" : "fields" , "dataType" : "string" } , sort : { "in" : "query" , "name" : "sort" , "dataType" : "string" } , q : { "in" : "query" , "name" : "q" , "dataType" : "string" } , } ; let validatedArgs = [ ] ; try { validatedArgs = getValidatedArgs ( args , request ) ; } catch ( err ) { return next ( err ) ; } const controller = iocContainer . get < UserController > ( UserController ) ; if ( typeof controller [ 'setStatus' ] === 'function' ) { ( < any > controller ) . setStatus ( undefined ) ; } const promise = controller . getPaginated . apply ( controller , validatedArgs ) ; promiseHandler ( controller , promise , response , next ) ; } ) ; app . post ( '/service/users' , authenticateMiddleware ( [ { "name" : "admin" } ] ) , function ( request , response , next ) { const args = { body : { "in" : "body" , "name" : "body" , "required" : true , "ref" : "IUserModel" } , } ; let validatedArgs = [ ] ; try { validatedArgs = getValidatedArgs ( args , request ) ; } catch ( err ) { return next ( err ) ; } const controller = iocContainer . get < UserController > ( UserController ) ; if ( typeof controller [ 'setStatus' ] === 'function' ) { ( < any > controller ) . setStatus ( undefined ) ; } const promise = controller . create . apply ( controller , validatedArgs ) ; promiseHandler ( controller , promise , response , next ) ; } ) ; app . put ( '/service/users/:id' , authenticateMiddleware ( [ { "name" : "admin" } ] ) , function ( request , response , next ) { const args = { id : { "in" : "path" , "name" : "id" , "required" : true , "dataType" : "string" } , body : { "in" : "body" , "name" : "body" , "required" : true , "ref" : "IUserModel" } , } ; let validatedArgs = [ ] ; try { validatedArgs = getValidatedArgs ( args , request ) ; } catch ( err ) { return next ( err ) ; } const controller = iocContainer . get < UserController > ( UserController ) ; if ( typeof controller [ 'setStatus' ] === 'function' ) { ( < any > controller ) . setStatus ( undefined ) ; } const promise = controller . update . apply ( controller , validatedArgs ) ; promiseHandler ( controller , promise , response , next ) ; } ) ; app . delete ( '/service/users/:id' , authenticateMiddleware ( [ { "name" : "admin" } ] ) , function ( request , response , next ) { const args = { id : { "in" : "path" , "name" : "id" , "required" : true , "dataType" : "string" } , } ; let validatedArgs = [ ] ; try { validatedArgs = getValidatedArgs ( args , request ) ; } catch ( err ) { return next ( err ) ; } const controller = iocContainer . get < UserController > ( UserController ) ; if ( typeof controller [ 'setStatus' ] === 'function' ) { ( < any > controller ) . setStatus ( undefined ) ; } const promise = controller . delete . apply ( controller , validatedArgs ) ; promiseHandler ( controller , promise , response , next ) ; } ) ; function authenticateMiddleware ( security = [ ] ) { return ( request , response , next ) => { let responded = 0 ; let success = false ; for ( const secMethod of security ) { expressAuthentication ( request , secMethod . name , secMethod . scopes ) . then ( ( user ) => { if ( ! success ) { success = true ; responded ++ ; request [ 'user' ] = user ; next ( ) ; } } ) . catch ( ( error ) => { responded ++ ; if ( responded == security . length && ! success ) { response . status ( 401 ) ; next ( error ) ; } } ) ; } } ; } function promiseHandler ( controllerObj , promise , response , next ) { return Promise . resolve ( promise ) . then ( ( data ) => { let statusCode ; if ( controllerObj instanceof Controller ) { const controller = controllerObj as Controller ; const headers = controller . getHeaders ( ) ; Object . keys ( headers ) . forEach ( ( name ) => { response . set ( name , headers [ name ] ) ; } ) ; statusCode = controller . getStatus ( ) ; } if ( data || data === false ) { response . status ( statusCode || 200 ) . json ( data ) ; } else { response . status ( statusCode || 204 ) . end ( ) ; } } ) . catch ( ( error ) => next ( error ) ) ; } function getValidatedArgs ( args , request ) { const fieldErrors = { } ; const values = Object . keys ( args ) . map ( ( key ) => { const name = args [ key ] . name ; switch ( args [ key ] . in ) { case 'request' : return request ; case 'query' : return ValidateParam ( args [ key ] , request . query [ name ] , models , name , fieldErrors ) ; case 'path' : return ValidateParam ( args [ key ] , request . params [ name ] , models , name , fieldErrors ) ; case 'header' : return ValidateParam ( args [ key ] , request . header ( name ) , models , name , fieldErrors ) ; case 'body' : return ValidateParam ( args [ key ] , request . body , models , name , fieldErrors , name + '.' ) ; case 'body-prop' : return ValidateParam ( args [ key ] , request . body [ name ] , models , name , fieldErrors , 'body.' ) ; } } ) ; if ( Object . keys ( fieldErrors ) . length > 0 ) { throw new ValidateError ( fieldErrors , '' ) ; } return values ; } }