@intuitionrobotics/thunderstorm
Version:
178 lines • 6.83 kB
JavaScript
import axios from 'axios';
import { HttpMethod } from "../../../shared/types.js";
import { _keys, BadImplementationException, } from "@intuitionrobotics/ts-common";
import { BaseHttpRequest } from "../../../shared/BaseHttpRequest.js";
import { BaseHttpModule_Class } from "../../../shared/BaseHttpModule.js";
import {} from "./types.js";
import * as fs from "fs";
export class AxiosHttpModule_Class extends BaseHttpModule_Class {
requestOption = {};
constructor(name) {
super(name || "AxiosHttpModule");
}
init() {
super.init();
const origin = this.config.origin;
if (origin)
this.origin = origin;
}
createRequest(method, key, data) {
return new AxiosHttpRequest(key, data, this.shouldCompress())
.setOrigin(this.origin)
.setMethod(method)
.setTimeout(this.timeout)
.setDefaultHeaders(this.defaultHeaders)
.setHandleRequestSuccess(this.handleRequestSuccess)
.setHandleRequestFailure(this.handleRequestFailure)
.setDefaultRequestHandler(this.processDefaultResponseHandlers)
.setRequestOption(this.requestOption);
}
setRequestOption(requestOption) {
this.requestOption = requestOption;
return this;
}
async downloadFile(url, outputFile, key = `Download file: ${url}`) {
const downloadRequest = await this.createRequest(HttpMethod.GET, key)
.setResponseType("arraybuffer")
.setUrl(url);
const downloadResponse = await downloadRequest.executeSync();
const outputFolder = outputFile.substring(0, outputFile.lastIndexOf("/"));
if (!fs.existsSync(outputFolder))
fs.mkdirSync(outputFolder);
fs.writeFileSync(outputFile, downloadResponse);
return outputFile;
}
}
export const AxiosHttpModule = new AxiosHttpModule_Class();
class AxiosHttpRequest extends BaseHttpRequest {
response;
cancelSignal;
status;
requestOption = {};
constructor(requestKey, requestData, shouldCompress) {
super(requestKey, requestData);
this.compress = shouldCompress === undefined ? false : shouldCompress;
this.cancelSignal = axios.CancelToken.source();
}
getStatus() {
if (!this.status)
throw new BadImplementationException('Missing status..');
return this.status;
}
getResponse() {
return this.response?.data;
}
resolveResponse() {
return this.getResponse();
}
abortImpl() {
this.cancelSignal.cancel(`Request with key: '${this.key}' aborted by the user.`);
}
getErrorResponse() {
return { debugMessage: this.getResponse() };
}
setRequestOption(requestOption) {
this.requestOption = requestOption;
return this;
}
executeImpl() {
//loop through whatever preprocessor
return new Promise(async (resolve, reject) => {
if (this.aborted)
return resolve();
let nextOperator = this.url.indexOf("?") === -1 ? "?" : "&";
let fullUrl = this.url;
const params = this.params;
if (params)
fullUrl = _keys(params).reduce((url, paramKey) => {
const param = params[paramKey];
if (!param)
return url;
const toRet = `${url}${nextOperator}${String(paramKey)}=${encodeURIComponent(param)}`;
nextOperator = "&";
return toRet;
}, this.url);
// TODO set progress listener
// this.xhr.upload.onprogress = this.onProgressListener;
const body = this.body;
// TODO add zipping of body
// if (typeof body === "string" && this.compress)
// return gzip(body, (error: Error | null, result: Buffer) => {
// if (error)
// return reject(error);
//
// xhr.send(result);
// });
//
// this.xhr.send(body as BodyInit);
const headers = Object.keys(this.headers).reduce((carry, headerKey) => {
carry[headerKey] = this.headers[headerKey].join('; ');
return carry;
}, {});
const options = {
...this.requestOption,
url: fullUrl,
method: this.method,
headers: headers,
// TODO will probably need to use the abortController with a timeout for this.
timeout: this.timeout,
cancelToken: this.cancelSignal.token
};
if (body)
options.data = body;
if (this.responseType)
options.responseType = this.responseType;
try {
this.response = await axios.request(options);
this.status = this.response?.status || 200;
return resolve();
}
catch (e) {
if (!(e instanceof axios.AxiosError)) {
this.status = 500;
return reject(e);
}
if (axios.isCancel(e)) {
// Should already be set when I abort but just in case its aborted somehow else
this.aborted = true;
console.log('Api cancelled: ', e.message);
}
this.response = e["response"];
this.status = this.response?.status || 500;
return reject(e);
}
});
}
getResponseHeader(headerKey) {
if (!this.response)
throw new BadImplementationException(`axios didn't return yet`);
return this.response.headers[headerKey];
}
}
export class AxiosHttpClient extends BaseHttpModule_Class {
requestOption = {};
constructor(name, config) {
super(name);
this.setConfig(config);
super.init();
const origin = this.config.origin;
if (origin)
this.origin = origin;
}
createRequest(method, key, data) {
return new AxiosHttpRequest(key, data, this.shouldCompress())
.setOrigin(this.origin)
.setMethod(method)
.setTimeout(this.timeout)
.setDefaultHeaders(this.defaultHeaders)
.setHandleRequestSuccess(this.handleRequestSuccess)
.setHandleRequestFailure(this.handleRequestFailure)
.setDefaultRequestHandler(this.processDefaultResponseHandlers)
.setRequestOption(this.requestOption);
}
setRequestOption(requestOption) {
this.requestOption = requestOption;
return this;
}
}
//# sourceMappingURL=AxiosHttpModule.js.map