@smash-sdk/core
Version:
Smash Sdk Core
80 lines (79 loc) • 3.18 kB
JavaScript
import axios, { AxiosError } from 'axios';
import { ConnectionAbortedError, NetworkError, TimeoutError, UnknownError } from '../errors/sdkError';
import { HttpResponse } from './types';
import { XMLParser } from "fast-xml-parser";
import Qs from "qs";
;
const defaultAxiosConfig = {
maxContentLength: Infinity,
maxBodyLength: Infinity,
responseType: 'json',
};
export class AxiosClient {
constructor() {
this.client = axios.create(defaultAxiosConfig);
}
setHttpConfiguration(configuration) {
this.client = axios.create({ ...defaultAxiosConfig, ...configuration });
}
handle(request) {
return new Promise(async (resolve, reject) => {
try {
const axiosParams = this.transformToAxiosParams(request);
const response = await this.client.request(axiosParams);
const smashResponse = this.transformToSmashResponse(response);
resolve(smashResponse);
}
catch (error) {
if (error?.code === AxiosError.ERR_NETWORK) {
reject(new NetworkError(error));
}
else if (error?.code === AxiosError.ECONNABORTED) {
reject(new ConnectionAbortedError(error));
}
else if (error?.code === AxiosError.ETIMEDOUT) {
reject(new TimeoutError(error));
}
else if ((!error?.response && error?.request)) {
reject(new NetworkError(error));
}
else if (error?.response?.status || (request.bypassErrorHandler && error instanceof AxiosError && error?.response)) {
const smashResponse = this.transformToSmashResponse(error.response);
resolve(smashResponse);
}
else {
reject(new UnknownError(error));
}
}
});
}
;
transformToSmashResponse(response) {
if (response?.headers?.['content-type'] === 'application/xml' && typeof response?.data === 'string') {
const parser = new XMLParser();
response.data = parser.parse(response.data);
}
return new HttpResponse({ ...response, body: response.data });
}
transformToAxiosParams(request) {
return {
method: request.method.toLowerCase(),
url: request.getUrl(),
headers: request.headers,
data: request.bodyParameters,
params: request.queryParameters,
paramsSerializer: (params) => Qs.stringify(params, { arrayFormat: 'repeat' }),
responseType: request.responseType === 'object' ? 'json' : 'stream',
onUploadProgress: (event) => {
if (request.onUploadProgress) {
const parsedEvent = {
uploadedBytes: event.loaded,
totalBytes: event.total,
timestamp: event.timeStamp,
};
request.onUploadProgress(parsedEvent);
}
},
};
}
}