import { Inject } from "angular2/core" ; import { Http , Headers as AngularHeaders , Request , RequestOptions , RequestMethod as RequestMethods , Response , URLSearchParams } from "angular2/http" ; import { Observable } from "rxjs/Observable" ; class constructor export class RESTClient { public constructor ( @ Inject ( Http ) protected http ) { } protected getBaseUrl ( ) { return null ; } ; protected getDefaultHeaders ( ) { return null ; } ; method param { Request } req protected requestInterceptor ( req ) { } method param { Response } res returns { Response } protected responseInterceptor ( res ) { return res ; } } param { String } url export function BaseUrl ( url ) { return function < TFunction extends Function > ( Target ) : TFunction { Target . prototype . getBaseUrl = function ( ) { return url ; } ; return Target ; } ; } param { Object } headers export function DefaultHeaders ( headers ) { return function < TFunction extends Function > ( Target ) : TFunction { Target . prototype . getDefaultHeaders = function ( ) { return headers ; } ; return Target ; } ; } function paramBuilder ( paramName ) { return function ( key ) { return function ( target , propertyKey , parameterIndex ) { var metadataKey = `${ propertyKey }_${ paramName }_parameters` ; var paramObj = { key : key , parameterIndex : parameterIndex } ; if ( Array . isArray ( target [ metadataKey ] ) ) { target [ metadataKey ] . push ( paramObj ) ; } else { target [ metadataKey ] = [ paramObj ] ; } } ; } ; } param { string } key export var Path = paramBuilder ( "Path" ) ; param { string } key export var Query = paramBuilder ( "Query" ) ; /**
 * Body of a REST method, type: key-value pair object
 * Only one body per method!
 */ export var Body = paramBuilder ( "Body" ) ( "Body" ) ; param { string } key export var Header = paramBuilder ( "Header" ) ; param { Object } headersDef export function Headers ( headersDef ) { return function ( target , propertyKey , descriptor ) { descriptor . headers = headersDef ; return descriptor ; } ; } param MediaType export function Produces ( producesDef ) { return function ( target , propertyKey , descriptor ) { descriptor . isJSON = producesDef === MediaType . JSON ; return descriptor ; } ; } /**
 * Supported @Produces media types
 */ export enum MediaType { JSON } function methodBuilder ( method ) { return function ( url ) { return function ( target , propertyKey , descriptor ) { var pPath = target [ `${ propertyKey }_Path_parameters` ] ; var pQuery = target [ `${ propertyKey }_Query_parameters` ] ; var pBody = target [ `${ propertyKey }_Body_parameters` ] ; var pHeader = target [ `${ propertyKey }_Header_parameters` ] ; descriptor . value = function ( ... args ) { var body = null ; if ( pBody ) { body = JSON . stringify ( args [ pBody [ 0 ] . parameterIndex ] ) ; } var resUrl = url ; if ( pPath ) { for ( var k in pPath ) { if ( pPath . hasOwnProperty ( k ) ) { resUrl = resUrl . replace ( "{" + pPath [ k ] . key + "}" , args [ pPath [ k ] . parameterIndex ] ) ; } } } var search = new URLSearchParams ( ) ; if ( pQuery ) { pQuery . filter ( p => args [ p . parameterIndex ] ) . forEach ( p => { var key = p . key ; var value = args [ p . parameterIndex ] ; if ( value instanceof Object ) { value = JSON . stringify ( value ) ; } search . set ( encodeURIComponent ( key ) , encodeURIComponent ( value ) ) ; } ) ; } var headers = new AngularHeaders ( this . getDefaultHeaders ( ) ) ; for ( var k in descriptor . headers ) { if ( descriptor . headers . hasOwnProperty ( k ) ) { headers . append ( k , descriptor . headers [ k ] ) ; } } if ( pHeader ) { for ( var k in pHeader ) { if ( pHeader . hasOwnProperty ( k ) ) { headers . append ( pHeader [ k ] . key , args [ pHeader [ k ] . parameterIndex ] ) ; } } } var options = new RequestOptions ( { method , url : this . getBaseUrl ( ) + resUrl , headers , body , search } ) ; var req = new Request ( options ) ; this . requestInterceptor ( req ) ; var observable = this . http . request ( req ) ; if ( descriptor . isJSON ) { observable = observable . map ( res => res . json ( ) ) ; } observable = this . responseInterceptor ( observable ) ; return observable ; } ; return descriptor ; } ; } ; } param { string } url export var GET = methodBuilder ( RequestMethods . Get ) ; param { string } url export var POST = methodBuilder ( RequestMethods . Post ) ; param { string } url export var PUT = methodBuilder ( RequestMethods . Put ) ; param { string } url export var DELETE = methodBuilder ( RequestMethods . Delete ) ; param { string } url export var HEAD = methodBuilder ( RequestMethods . Head ) ;