import { Blob , FormData , HttpRequest , HttpParameterCodec , HttpParams , HttpHeaders } from './lib' ; /**
 * Custom parameter codec to correctly handle the plus sign in parameter
 * values. See https://github.com/angular/angular/issues/18261
 */ class ParameterCodec implements HttpParameterCodec { encodeKey ( key ) { return encodeURIComponent ( key ) ; } encodeValue ( value ) { return encodeURIComponent ( value ) ; } decodeKey ( key ) { return decodeURIComponent ( key ) ; } decodeValue ( value ) { return decodeURIComponent ( value ) ; } } const ParameterCodecInstance = new ParameterCodec ( ) ; /**
 * Defines the options for appending a parameter
 */ interface ParameterOptions { style ? : string ; explode ? : boolean ; } /**
 * Base class for a parameter
 */ abstract class Parameter { constructor ( public name , public value , public options , defaultStyle , defaultExplode ) { this . options = options || { } ; if ( this . options . style === null || this . options . style === undefined ) { this . options . style = defaultStyle ; } if ( this . options . explode === null || this . options . explode === undefined ) { this . options . explode = defaultExplode ; } } serializeValue ( value , separator = ',' ) { if ( value === null || value === undefined ) { return '' ; } else if ( value instanceof Array ) { return value . map ( v => this . serializeValue ( v ) . split ( separator ) . join ( encodeURIComponent ( separator ) ) ) . join ( separator ) ; } else if ( typeof value === 'object' ) { const array = [ ] ; for ( const key of Object . keys ( value ) ) { let propVal = value [ key ] ; if ( propVal !== null && propVal !== undefined ) { propVal = this . serializeValue ( propVal ) . split ( separator ) . join ( encodeURIComponent ( separator ) ) ; if ( this . options . explode ) { array . push ( `${ key }=${ propVal }` ) ; } else { array . push ( key ) ; array . push ( propVal ) ; } } } return array . join ( separator ) ; } else { return String ( value ) ; } } } /**
 * A parameter in the operation path
 */ class PathParameter extends Parameter { constructor ( name , value , options ) { super ( name , value , options , 'simple' , false ) ; } append ( path ) { let value = this . value ; if ( value === null || value === undefined ) { value = '' ; } let prefix = this . options . style === 'label' ? '.' : '' ; let separator = this . options . explode ? prefix === '' ? ',' : prefix : ',' ; let alreadySerialized = false ; if ( this . options . style === 'matrix' ) { prefix = `;${ this . name }=` ; if ( this . options . explode && typeof value === 'object' ) { prefix = ';' ; if ( value instanceof Array ) { value = value . map ( v => `${ this . name }=${ this . serializeValue ( v , ';' ) }` ) ; value = value . join ( ';' ) ; alreadySerialized = true ; } else { value = this . serializeValue ( value , ';' ) ; alreadySerialized = true ; } } } value = prefix + ( alreadySerialized ? value : this . serializeValue ( value , separator ) ) ; path = path . replace ( `{${ this . name }}` , value ) ; path = path . replace ( `{${ prefix }${ this . name }${ this . options . explode ? '*' : '' }}` , value ) ; return path ; } serializeValue ( value , separator = ',' ) { var result = typeof value === 'string' ? encodeURIComponent ( value ) : super . serializeValue ( value , separator ) ; result = result . replace ( '%3D' , '=' ) ; result = result . replace ( '%3B' , ';' ) ; result = result . replace ( '%2C' , ',' ) ; return result ; } } /**
 * A parameter in the query
 */ class QueryParameter extends Parameter { constructor ( name , value , options ) { super ( name , value , options , 'form' , true ) ; } append ( params ) { if ( this . value instanceof Array ) { if ( this . options . explode ) { for ( const v of this . value ) { params = params . append ( this . name , this . serializeValue ( v ) ) ; } } else { const separator = this . options . style === 'spaceDelimited' ? ' ' : this . options . style === 'pipeDelimited' ? '|' : ',' ; return params . append ( this . name , this . serializeValue ( this . value , separator ) ) ; } } else if ( this . value !== null && typeof this . value === 'object' ) { if ( this . options . style === 'deepObject' ) { for ( const key of Object . keys ( this . value ) ) { const propVal = this . value [ key ] ; if ( propVal !== null && propVal !== undefined ) { params = params . append ( `${ this . name }[${ key }]` , this . serializeValue ( propVal ) ) ; } } } else if ( this . options . explode ) { for ( const key of Object . keys ( this . value ) ) { const propVal = this . value [ key ] ; if ( propVal !== null && propVal !== undefined ) { params = params . append ( key , this . serializeValue ( propVal ) ) ; } } } else { const array = [ ] ; for ( const key of Object . keys ( this . value ) ) { const propVal = this . value [ key ] ; if ( propVal !== null && propVal !== undefined ) { array . push ( key ) ; array . push ( propVal ) ; } } params = params . append ( this . name , this . serializeValue ( array ) ) ; } } else if ( this . value !== null && this . value !== undefined ) { params = params . append ( this . name , this . serializeValue ( this . value ) ) ; } return params ; } } /**
 * A parameter in the HTTP request header
 */ class HeaderParameter extends Parameter { constructor ( name , value , options ) { super ( name , value , options , 'simple' , false ) ; } append ( headers ) { if ( this . value !== null && this . value !== undefined ) { if ( this . value instanceof Array ) { for ( const v of this . value ) { headers = headers . append ( this . name , this . serializeValue ( v ) ) ; } } else { headers = headers . append ( this . name , this . serializeValue ( this . value ) ) ; } } return headers ; } } /**
 * Helper to build http requests from parameters
 */ export class RequestBuilder { private _path = new Map < string , PathParameter > ( ) ; private _query = new Map < string , QueryParameter > ( ) ; private _header = new Map < string , HeaderParameter > ( ) ; _bodyContent : any | null ; _bodyContentType ? : string ; constructor ( public rootUrl , public operationPath , public method ) { } /**
     * Sets a path parameter
     */ path ( name , value , options ? ) { this . _path . set ( name , new PathParameter ( name , value , options || { } ) ) ; } /**
     * Sets a query parameter
     */ query ( name , value , options ? ) { this . _query . set ( name , new QueryParameter ( name , value , options || { } ) ) ; } /**
     * Sets a header parameter
     */ header ( name , value , options ? ) { this . _header . set ( name , new HeaderParameter ( name , value , options || { } ) ) ; } /**
     * Sets the body content, along with the content type
     */ body ( value , contentType = 'application/json' ) { if ( value instanceof Blob ) { this . _bodyContentType = value . type ; } else { this . _bodyContentType = contentType ; } if ( this . _bodyContentType === 'application/x-www-form-urlencoded' && value !== null && typeof value === 'object' ) { const pairs = [ ] ; for ( const key of Object . keys ( value ) ) { let val = value [ key ] ; if ( ! ( val instanceof Array ) ) { val = [ val ] ; } for ( const v of val ) { const formValue = this . formDataValue ( v ) ; if ( formValue !== null ) { pairs . push ( [ key , formValue ] ) ; } } } this . _bodyContent = pairs . map ( p => `${ encodeURIComponent ( p [ 0 ] ) }=${ encodeURIComponent ( p [ 1 ] ) }` ) . join ( '&' ) ; } else if ( this . _bodyContentType === 'multipart/form-data' ) { const formData = new FormData ( ) ; if ( value !== null && value !== undefined ) { for ( const key of Object . keys ( value ) ) { const val = value [ key ] ; if ( val instanceof Array ) { for ( const v of val ) { const toAppend = this . formDataValue ( v ) ; if ( toAppend !== null ) { formData . append ( key , toAppend ) ; } } } else { const toAppend = this . formDataValue ( val ) ; if ( toAppend !== null ) { formData . set ( key , toAppend ) ; } } } } this . _bodyContent = formData ; } else { this . _bodyContent = value ; } } private formDataValue ( value ) { if ( value === null || value === undefined ) { return null ; } if ( value instanceof Blob ) { return value ; } if ( typeof value === 'object' ) { return JSON . stringify ( value ) ; } return String ( value ) ; } /**
     * Builds the request with the current set parameters
     */ build < T = any > ( options ? ) { options = options || { } ; let path = this . operationPath ; for ( const pathParam of this . _path . values ( ) ) { path = pathParam . append ( path ) ; } const url = this . rootUrl + path ; let httpParams = new HttpParams ( { encoder : ParameterCodecInstance } ) ; for ( const queryParam of this . _query . values ( ) ) { httpParams = queryParam . append ( httpParams ) ; } let httpHeaders = new HttpHeaders ( ) ; if ( options . accept ) { httpHeaders = httpHeaders . append ( 'Accept' , options . accept ) ; } for ( const headerParam of this . _header . values ( ) ) { httpHeaders = headerParam . append ( httpHeaders ) ; } if ( this . _bodyContentType && ! ( this . _bodyContent instanceof FormData ) ) { httpHeaders = httpHeaders . set ( 'Content-Type' , this . _bodyContentType ) ; } return new HttpRequest < T > ( this . method . toUpperCase ( ) , url , this . _bodyContent , { params : httpParams , headers : httpHeaders , responseType : options . responseType , reportProgress : options . reportProgress } ) ; } }