import { Metadata } from "grpc" ; import { HttpHeader } from "./types" ; import EnvoyHttpRequestParams , { EnvoyHttpRequestInit } from "./envoy-http-request-params" ; import EnvoyContext from "./envoy-context" ; import envoyFetch , { EnvoyResponse } from "./envoy-fetch" ; internal export const APPLICATION_JSON = "application/json" ; /**
 * a high level http client that will send traffic to Envoy:
 * 1. all HTTP GET / POST ... will be wrapped as async signature
 * 2. doing JSON RESET API common works: accepting object, return objects, only works with `application/json`
 * 3. none 2XX request will be throw as Error
 */ export default class EnvoyHttpClient { /**
     * the envoy context where you can read
     */ envoyContext : EnvoyContext ; param ctx constructor ( ctx ) { if ( ctx instanceof EnvoyContext ) { this . envoyContext = ctx ; } else { this . envoyContext = new EnvoyContext ( ctx ) ; } } param response private async returnJsonOrError ( response ) { const $statusCode = response . status ; if ( $statusCode === 204 ) { return undefined ; } const contentType = response . headers . get ( "content-type" ) ; if ( ! contentType || ( contentType !== "application/json" && ! contentType . startsWith ( "text/" ) ) ) { const err = new Error ( `Unexpected content type: ${ contentType }, http status: ${ $statusCode }` ) ; const body = await response . text ( ) ; Object . assign ( err , { $statusCode , body } ) ; throw err ; } if ( contentType === "application/json" ) { const result = await response . json ( ) ; if ( $statusCode >= 400 ) { result . $statusCode = result . $statusCode || $statusCode ; throw result ; } return result ; } const text = await response . text ( ) ; if ( $statusCode !== 200 ) { const error = new Error ( text ) ; Object . assign ( error , { $statusCode } ) ; throw error ; } return text ; } async actionWithoutBody ( method , url , init ? ) { const param = new EnvoyHttpRequestParams ( this . envoyContext , init ) ; const res = await envoyFetch ( param , url , { method , headers : { accept : APPLICATION_JSON } } ) ; return this . returnJsonOrError ( res ) ; } param url param init throws async get ( url , init ? ) { return this . actionWithoutBody ( "GET" , url , init ) ; } param url param init throws async delete ( url , init ? ) { return this . actionWithoutBody ( "DELETE" , url , init ) ; } async actionWithBody ( method , url , body , init ? ) { const param = new EnvoyHttpRequestParams ( this . envoyContext , init ) ; const res = await envoyFetch ( param , url , { method , headers : { "content-type" : APPLICATION_JSON , accept : APPLICATION_JSON } , body : JSON . stringify ( body ) } ) ; return this . returnJsonOrError ( res ) ; } param url param body param init throws async post ( url , body , init ? ) { return this . actionWithBody ( "POST" , url , body , init ) ; } param url param body param init throws async patch ( url , body , init ? ) { return this . actionWithBody ( "PATCH" , url , body , init ) ; } param url param body param init throws async put ( url , body , init ? ) { return this . actionWithBody ( "PUT" , url , body , init ) ; } }