chargebee
Version:
A library for integrating with Chargebee.
89 lines (88 loc) • 3.08 kB
JavaScript
import { HttpClient, HttpClientResponse, } from './ClientInterface.js';
export class FetchHttpClient extends HttpClient {
async makeApiRequest(props) {
const headers = this._createHeaders(props.headers);
let url = `${props.protocol}://${props.host}:${props.port}${props.path}`;
let fetchOptions = {
method: props.method,
headers: headers,
body: props.data ? props.data : undefined,
};
try {
const response = globalThis.AbortController
? await this.fetchWithAbortTimeout(url, fetchOptions, props.timeout)
: await this.fetchWithTimeout(url, fetchOptions, props.timeout);
return new FetchHttpClientResponse(response);
}
catch (err) {
return Promise.reject(err);
}
}
_createHeaders(httpHeaders) {
const headers = new Headers();
Object.entries(httpHeaders).forEach(([key, value]) => {
headers.append(key, String(value));
});
return headers;
}
async fetchWithTimeout(url, fetchOptions, timeout) {
let pendingTimeoutId;
const timeoutPromise = new Promise((_, reject) => {
pendingTimeoutId = setTimeout(() => {
pendingTimeoutId = null;
reject(HttpClient.timeOutError());
}, timeout);
});
const fetchPromise = fetch(url, fetchOptions);
return Promise.race([fetchPromise, timeoutPromise]).finally(() => {
if (pendingTimeoutId) {
clearTimeout(pendingTimeoutId);
}
});
}
async fetchWithAbortTimeout(url, fetchOptions, timeout) {
const abort = new AbortController();
let timeoutId = setTimeout(() => {
timeoutId = null;
abort.abort(HttpClient.timeOutError());
}, timeout);
try {
return await fetch(url, Object.assign(Object.assign({}, fetchOptions), { signal: abort.signal }));
}
catch (err) {
if (err.name === 'AbortError') {
return Promise.reject(HttpClient.timeOutError());
}
else {
return Promise.reject(err);
}
}
finally {
if (timeoutId) {
clearTimeout(timeoutId);
}
}
}
}
export class FetchHttpClientResponse extends HttpClientResponse {
constructor(response) {
super(response.status, FetchHttpClientResponse._transformHeadersToObject(response.headers));
this._res = response;
}
getRawResponse() {
return this._res;
}
toJson() {
return this._res.json();
}
static _transformHeadersToObject(headers) {
const headersObj = {};
for (const entry of headers) {
if (!Array.isArray(entry) || entry.length != 2) {
throw new Error('Headers should be an iterable object.');
}
headersObj[entry[0]] = entry[1];
}
return headersObj;
}
}