import { HttpMetadata , ServiceMetadata } from "../metadata" ; import { ArgBinder , ContextBinder , HttpAdapter , HttpCode , HttpMethod , HttpResponse , RequestBinder } from "../types" ; export function Get ( route , adapter ? ) { return HttpMethod ( "GET" , route , false , 200 , adapter ) ; } export function Post ( route , model ? , adapter ? ) { return HttpMethod ( "POST" , route , model , 200 , adapter ) ; } export function Put ( route , model ? , adapter ? ) { return HttpMethod ( "PUT" , route , model , 200 , adapter ) ; } export function Delete ( route , model ? , adapter ? ) { return HttpMethod ( "DELETE" , route , model , 200 , adapter ) ; } export function Patch ( route , model ? , adapter ? ) { return HttpMethod ( "PATCH" , route , model , 200 , adapter ) ; } function HttpMethod ( verb , resource , model , code , adapter ? ) { return function ( type , propertyKey , descriptor ) { if ( ! model ) model = null ; else if ( model === true ) model = propertyKey ; else model = model . toString ( ) ; let route = `${ verb } ${ resource }` ; let meta = { service : undefined , route , method : propertyKey , verb , resource , model : model as string , code , adapter } ; let metadata = ServiceMetadata . get ( type ) ; if ( model ) { let modelRoute = `${ route }:${ model }` ; if ( metadata . httpMetadata [ modelRoute ] ) throw new Error ( `Duplicate route: ${ modelRoute }` ) ; metadata . httpMetadata [ modelRoute ] = meta ; } else { if ( metadata . httpMetadata [ route ] ) throw new Error ( `Duplicate route: ${ route }` ) ; metadata . httpMetadata [ route ] = meta ; } } ; } export function PathParam ( param ) { return ArgBinding ( PathParam . name , param , ( ctx , req ) => req . pathParameters [ param ] ) ; } export function PathParams ( ) { return ArgBinding ( PathParams . name , "*" , ( ctx , req ) => req . pathParameters ) ; } export function QueryParam ( param ) { return ArgBinding ( QueryParam . name , param , ( ctx , req ) => req . queryStringParameters [ param ] ) ; } export function QueryParams ( ) { return ArgBinding ( QueryParams . name , "*" , ( ctx , req ) => req . queryStringParameters ) ; } export function BodyParam ( param ) { return ArgBinding ( BodyParam . name , param , ( ctx , req ) => resolvePath ( req . json , param ) ) ; } export function HeaderParam ( param ) { return ArgBinding ( HeaderParam . name , param , ( ctx , req ) => req . headers [ ( "" + param ) . toLowerCase ( ) ] ) ; } export function Body ( ) { return ArgBinding ( Body . name , null , ( ctx , req ) => req . json ) ; } export function ContextObject ( ) { return ArgBinding ( ContextObject . name , null , ( ctx , req ) => ctx ) ; } export function ContextParam ( param ) { return ArgBinding ( ContextParam . name , param instanceof Function ? "[Function]" : param , ( ctx , req ) => resolvePath ( ctx , param ) ) ; } export function RequestObject ( ) { return ArgBinding ( RequestObject . name , null , ( ctx , req ) => req ) ; } export function RequestParam ( param ) { return ArgBinding ( RequestParam . name , param instanceof Function ? "[Function]" : param , ( ctx , req ) => resolvePath ( req , param ) ) ; } function ArgBinding ( type , param , binder ) { return function ( target , propertyName , index ) { let metadata = ServiceMetadata . get ( target ) ; metadata . bindingMetadata [ propertyName ] = metadata . bindingMetadata [ propertyName ] || { method : propertyName , contentType : undefined , argBindings : [ ] } ; metadata . bindingMetadata [ propertyName ] . argBindings [ index ] = { type , index , param , binder } ; } ; } export function ContentType ( type ) { return function ( target , propertyName , descriptor ) { let metadata = ServiceMetadata . get ( target ) ; metadata . bindingMetadata [ propertyName ] = metadata . bindingMetadata [ propertyName ] || { method : propertyName , contentType : type , argBindings : [ ] } ; metadata . bindingMetadata [ propertyName ] . contentType = type ; } ; } function resolvePath ( root , param ) { if ( typeof param === "function" ) return param ( root ) ; if ( ! param ) return undefined ; param = param . toString ( ) ; let path = param . split ( "." ) ; let val = root ; for ( let p of path ) { val = val && val [ p ] ; } return val ; }