import { inject , injectable , decorate } from 'inversify' ; import { Controller , Middleware , ControllerMetadata , HandlerDecorator , ControllerMethodMetadata , ControllerParameterMetadata , ParameterMetadata , } from './interfaces' ; import { TYPE , METADATA_KEY , PARAMETER_TYPE , HTTP_VERBS_ENUM , } from './constants' ; export const injectHttpContext = inject ( TYPE . HttpContext ) ; export function controller ( path , ... middleware ) { return ( target ) : void => { const currentMetadata = { middleware , path , target , } ; decorate ( injectable ( ) , target ) ; Reflect . defineMetadata ( METADATA_KEY . controller , currentMetadata , target ) ; const previousMetadata = Reflect . getMetadata ( METADATA_KEY . controller , Reflect ) || [ ] ; const newMetadata = [ currentMetadata , ... previousMetadata ] ; Reflect . defineMetadata ( METADATA_KEY . controller , newMetadata , Reflect ) ; } ; } export function all ( path , ... middleware ) { return httpMethod ( 'all' , path , ... middleware ) ; } export function httpGet ( path , ... middleware ) { return httpMethod ( 'get' , path , ... middleware ) ; } export function httpPost ( path , ... middleware ) { return httpMethod ( 'post' , path , ... middleware ) ; } export function httpPut ( path , ... middleware ) { return httpMethod ( 'put' , path , ... middleware ) ; } export function httpPatch ( path , ... middleware ) { return httpMethod ( 'patch' , path , ... middleware ) ; } export function httpHead ( path , ... middleware ) { return httpMethod ( 'head' , path , ... middleware ) ; } export function httpDelete ( path , ... middleware ) { return httpMethod ( 'delete' , path , ... middleware ) ; } export function httpMethod ( method , path , ... middleware ) { return ( target , key ) : void => { const metadata = { key , method , middleware , path , target , } ; let metadataList = [ ] ; if ( ! Reflect . hasOwnMetadata ( METADATA_KEY . controllerMethod , target . constructor ) ) { Reflect . defineMetadata ( METADATA_KEY . controllerMethod , metadataList , target . constructor ) ; } else { metadataList = Reflect . getOwnMetadata ( METADATA_KEY . controllerMethod , target . constructor ) ; } metadataList . push ( metadata ) ; } ; } export const request = paramDecoratorFactory ( PARAMETER_TYPE . REQUEST ) ; export const response = paramDecoratorFactory ( PARAMETER_TYPE . RESPONSE ) ; export const requestParam = paramDecoratorFactory ( PARAMETER_TYPE . PARAMS ) ; export const queryParam = paramDecoratorFactory ( PARAMETER_TYPE . QUERY ) ; export const requestBody = paramDecoratorFactory ( PARAMETER_TYPE . BODY ) ; export const requestHeaders = paramDecoratorFactory ( PARAMETER_TYPE . HEADERS ) ; export const cookies = paramDecoratorFactory ( PARAMETER_TYPE . COOKIES ) ; export const next = paramDecoratorFactory ( PARAMETER_TYPE . NEXT ) ; export const principal = paramDecoratorFactory ( PARAMETER_TYPE . PRINCIPAL ) ; function paramDecoratorFactory ( parameterType ) { return ( name ? ) : ParameterDecorator => params ( parameterType , name ) ; } export function params ( type , parameterName ? ) { return ( target , methodName , index ) : void => { let metadataList = { } ; let parameterMetadataList = [ ] ; const parameterMetadata = { index , injectRoot : parameterName === undefined , parameterName , type , } ; if ( ! Reflect . hasOwnMetadata ( METADATA_KEY . controllerParameter , target . constructor ) ) { parameterMetadataList . unshift ( parameterMetadata ) ; } else { metadataList = Reflect . getOwnMetadata ( METADATA_KEY . controllerParameter , target . constructor ) ; if ( metadataList [ methodName as string ] ) { parameterMetadataList = metadataList [ methodName as string ] || [ ] ; } parameterMetadataList . unshift ( parameterMetadata ) ; } metadataList [ methodName as string ] = parameterMetadataList ; Reflect . defineMetadata ( METADATA_KEY . controllerParameter , metadataList , target . constructor ) ; } ; }