'use strict' ; import * as _ from 'lodash' ; import 'reflect-metadata' ; import { MethodParam , ParamType , ServiceClass , ServiceMethod } from '../server/model/metadata' ; import { ServerContainer } from '../server/server-container' ; export function Context ( ... args ) { return new ParameterDecorator ( 'Context' ) . withType ( ParamType . context ) . decorateParameterOrProperty ( args ) ; } export function ContextRequest ( ... args ) { return new ParameterDecorator ( 'ContextRequest' ) . withType ( ParamType . context_request ) . decorateParameterOrProperty ( args ) ; } export function ContextResponse ( ... args ) { return new ParameterDecorator ( 'ContextResponse' ) . withType ( ParamType . context_response ) . decorateParameterOrProperty ( args ) ; } export function ContextNext ( ... args ) { return new ParameterDecorator ( 'ContextNext' ) . withType ( ParamType . context_next ) . decorateParameterOrProperty ( args ) ; } export function ContextLanguage ( ... args ) { return new ParameterDecorator ( 'ContextLanguage' ) . withType ( ParamType . context_accept_language ) . decorateParameterOrProperty ( args ) ; } export function ContextAccept ( ... args ) { return new ParameterDecorator ( 'ContextAccept' ) . withType ( ParamType . context_accept ) . decorateParameterOrProperty ( args ) ; } export function PathParam ( name ) { return new ParameterDecorator ( 'PathParam' ) . withType ( ParamType . path ) . withName ( name ) . decorateNamedParameterOrProperty ( ) ; } export function FileParam ( name ) { return new ParameterDecorator ( 'FileParam' ) . withType ( ParamType . file ) . withName ( name ) . decorateNamedParameterOrProperty ( ) ; } export function FilesParam ( name ) { return new ParameterDecorator ( 'FilesParam' ) . withType ( ParamType . files ) . withName ( name ) . decorateNamedParameterOrProperty ( ) ; } export function QueryParam ( name ) { return new ParameterDecorator ( 'QueryParam' ) . withType ( ParamType . query ) . withName ( name ) . decorateNamedParameterOrProperty ( ) ; } export function HeaderParam ( name ) { return new ParameterDecorator ( 'HeaderParam' ) . withType ( ParamType . header ) . withName ( name ) . decorateNamedParameterOrProperty ( ) ; } export function CookieParam ( name ) { return new ParameterDecorator ( 'CookieParam' ) . withType ( ParamType . cookie ) . withName ( name ) . decorateNamedParameterOrProperty ( ) ; } export function FormParam ( name ) { return new ParameterDecorator ( 'FormParam' ) . withType ( ParamType . form ) . withName ( name ) . decorateNamedParameterOrProperty ( ) ; } export function Param ( name ) { return new ParameterDecorator ( 'Param' ) . withType ( ParamType . param ) . withName ( name ) . decorateNamedParameterOrProperty ( ) ; } class ParameterDecorator { private decorator : string ; private paramType : ParamType ; private nameRequired : boolean = false ; private name : string = null ; constructor ( decorator ) { this . decorator = decorator ; } public withType ( paramType ) { this . paramType = paramType ; return this ; } public withName ( name ) { this . nameRequired = true ; this . name = name ? name . trim ( ) : '' ; return this ; } public decorateParameterOrProperty ( args ) { if ( ! this . nameRequired || this . name ) { args = _ . without ( args , undefined ) ; if ( args . length < 3 || typeof args [ 2 ] === 'undefined' ) { return this . decorateProperty ( args [ 0 ] , args [ 1 ] ) ; } else if ( args . length === 3 && typeof args [ 2 ] === 'number' ) { return this . decorateParameter ( args [ 0 ] , args [ 1 ] , args [ 2 ] ) ; } } throw new Error ( `Invalid @${ this . decorator } Decorator declaration.` ) ; } public decorateNamedParameterOrProperty ( ) { return ( ... args ) => { return this . decorateParameterOrProperty ( args ) ; } ; } private decorateParameter ( target , propertyKey , parameterIndex ) { const serviceMethod = ServerContainer . get ( ) . registerServiceMethod ( target . constructor , propertyKey ) ; if ( serviceMethod ) { const paramTypes = Reflect . getOwnMetadata ( 'design:paramtypes' , target , propertyKey ) ; while ( paramTypes && serviceMethod . parameters . length < paramTypes . length ) { serviceMethod . parameters . push ( new MethodParam ( null , paramTypes [ serviceMethod . parameters . length ] , ParamType . body ) ) ; } serviceMethod . parameters [ parameterIndex ] = new MethodParam ( this . name , paramTypes [ parameterIndex ] , this . paramType ) ; } } private decorateProperty ( target , key ) { const classData = ServerContainer . get ( ) . registerServiceClass ( target . constructor ) ; const propertyType = Reflect . getMetadata ( 'design:type' , target , key ) ; classData . addProperty ( key , { name : this . name , propertyType : propertyType , type : this . paramType } ) ; } }