@simbachain/simbats
Version:
TypeScript SDK for SIMBA Chain
456 lines • 17.2 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.RequestHandler = exports.RequestMethods = void 0;
const axios_1 = __importDefault(require("axios"));
const utf8_1 = __importDefault(require("utf8"));
const form_data_1 = __importDefault(require("form-data"));
const fs = __importStar(require("fs"));
const config_1 = require("./config");
var RequestMethods;
(function (RequestMethods) {
RequestMethods["POST"] = "POST";
RequestMethods["PUT"] = "PUT";
RequestMethods["DELETE"] = "DELETE";
RequestMethods["GET"] = "GET";
})(RequestMethods = exports.RequestMethods || (exports.RequestMethods = {}));
/**
* class for making HTTP requests
*/
class RequestHandler {
constructor(baseURL = config_1.SimbaConfig.baseURL) {
this.baseURL = baseURL;
}
/**
* method for building a URL, accounting for redundant slashes, etc.
* @param baseURL
* @param endpoint
* @returns {string}
*/
buildURL(baseURL, endpoint) {
const params = {
baseURL,
endpoint,
};
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER : params : ${JSON.stringify(params)}`);
let fullURL;
if (baseURL.endsWith("/") && endpoint.startsWith("/")) {
fullURL = `${baseURL.slice(0, -1)}${endpoint}`;
}
else if (!baseURL.endsWith("/") && !endpoint.startsWith("/")) {
fullURL = `${baseURL}/${endpoint}`;
}
else {
fullURL = `${baseURL}${endpoint}`;
}
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT : fullURL : ${fullURL}`);
return fullURL;
}
/**
* general method for making HTTP requests. never gets called directly
* @param url
* @param method
* @param options
* @param data
* @param parseDataFromResponse
* @returns {Promise<AxiosResponse<any> | Record<any, any> | Array<any>>}
*/
async doHTTPRequest(url, method, options, data, parseDataFromResponse = true) {
const params = {
url,
method,
options,
data,
};
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER : params : ${JSON.stringify(params)}`);
let res;
try {
switch (method) {
case RequestMethods.POST: {
data = data ? data : {};
res = await axios_1.default.post(url, data, options);
break;
}
case RequestMethods.PUT: {
data = data ? data : {};
res = await axios_1.default.put(url, data, options);
break;
}
case RequestMethods.DELETE: {
res = await axios_1.default.delete(url, options);
break;
}
case RequestMethods.GET: {
res = await axios_1.default.get(url, options);
break;
}
default: {
const message = `unrecognized request method: ${method}`;
config_1.SimbaConfig.log.error(`:: SIMBA : EXIT : ${message}`);
throw (message);
}
}
if (res.data && parseDataFromResponse) {
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT : res.data : ${res.data}`);
const resData = res.data;
return resData;
}
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT : res : ${res}`);
return res;
}
catch (error) {
if (axios_1.default.isAxiosError(error) && error.response) {
config_1.SimbaConfig.log.error(`${JSON.stringify(error.response.data)}`);
}
else {
config_1.SimbaConfig.log.error(`${error}`);
}
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT :`);
throw (error);
}
}
/**
* do post request
* @param url
* @param options
* @param data
* @param parseDataFromResponse
* @returns {Promise<AxiosResponse<any> | Record<any, any> | Array<any>>}
*/
async doPostRequest(url, options, data, parseDataFromResponse = true) {
const params = {
url,
options,
data,
parseDataFromResponse,
};
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER : params : ${JSON.stringify(params)}`);
const res = await this.doHTTPRequest(url, RequestMethods.POST, options, data, parseDataFromResponse);
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT : res : ${res}`);
return res;
}
/**
* do get request
* @param url
* @param options
* @param parseDataFromResponse
* @param responseType
* @returns {Promise<AxiosResponse<any> | Record<any, any> | Array<any>>}
*/
async doGetRequest(url, options, parseDataFromResponse = true, responseType) {
const params = {
url,
options,
parseDataFromResponse,
};
if (responseType) {
options.responseType = responseType;
}
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER : params : ${JSON.stringify(params)}`);
const res = await this.doHTTPRequest(url, RequestMethods.GET, options, undefined, parseDataFromResponse);
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT : res : ${res}`);
return res;
}
/**
* do put request
* @param url
* @param options
* @param data
* @param parseDataFromResponse
* @returns {Promise<AxiosResponse<any> | Record<any, any> | Array<any>>}
*/
async doPutRequest(url, options, data, parseDataFromResponse = true) {
const params = {
url,
options,
data,
parseDataFromResponse,
};
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER : params : ${JSON.stringify(params)}`);
const res = await this.doHTTPRequest(url, RequestMethods.PUT, options, data, parseDataFromResponse);
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT : res : ${res}`);
return res;
}
/**
* do delete request
* @param url
* @param options
* @param data
* @param parseDataFromResponse
* @returns {Promise<AxiosResponse<any> | Record<any, any> | Array<any>>}
*/
async doDeleteRequest(url, options, data, parseDataFromResponse = true) {
const params = {
url,
options,
data,
parseDataFromResponse,
};
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER : params : ${JSON.stringify(params)}`);
const res = await this.doHTTPRequest(url, RequestMethods.DELETE, options, data, parseDataFromResponse);
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT : res : ${res}`);
return res;
}
/**
* method for generating headers for form data
* @param options
* @param formData
* @returns {Record<any, any>}
*/
formDataHeaders(options, formData) {
const params = {
options,
formData,
};
if (options.headers["Content-Type"]) {
delete options.headers["Content-Type"];
}
if (options.headers["content-type"]) {
delete options.headers["content-type"];
}
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER : params : ${JSON.stringify(params)}`);
const formDataHeaders = formData.getHeaders();
const headers = Object.assign(Object.assign({}, options["headers"]), formDataHeaders);
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT`);
return headers;
}
/**
* method for generating form data, by passing file paths and method inputs
* @param inputs
* @param filePaths
* @returns {FormData}
*/
formDataFromFilePathsAndInputs(inputs, filePaths) {
const params = {
filePaths,
};
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER : params : ${JSON.stringify(params)}`);
const formData = new form_data_1.default();
filePaths.forEach(fileName => {
// you do NOT have to JSON.stringify the readStream below
formData.append("_files", fs.createReadStream(fileName));
});
Object.keys(inputs).forEach(key => {
// you do NOT have to JSON.stringify inputs[key] below
formData.append(key, JSON.stringify(inputs[key]));
});
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT :`);
return formData;
}
/**
* do post or put request with form data
* never gets called directly
* @param url
* @param method
* @param formData
* @param headers
* @param parseDataFromResponse
* @returns {Promise<AxiosResponse<any> | Record<any, any> | Array<any>>}
*/
async doPostOrPutRequestWithFormData(url, method, formData, headers, parseDataFromResponse = true) {
const params = {
url,
method,
formData,
headers,
parseDataFromResponse,
};
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER : params : ${JSON.stringify(params)}`);
const axiosConfig = {
method: method,
url: url,
headers: headers,
data: formData
};
try {
const res = await axios_1.default(axiosConfig);
if (res.data && parseDataFromResponse) {
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT : res.data : ${JSON.stringify(res.data)}`);
return res.data;
}
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT : res : ${res}`);
return res;
}
catch (error) {
if (axios_1.default.isAxiosError(error) && error.response) {
config_1.SimbaConfig.log.error(`${JSON.stringify(error.response.data)}`);
}
else {
config_1.SimbaConfig.log.error(`${error}`);
}
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT :`);
throw (error);
}
}
/**
* do post request with form data
* @param url
* @param formData
* @param headers
* @param parseDataFromResponse
* @returns {Promise<AxiosResponse<any> | Record<any, any> | Array<any>>}
*/
async doPostRequestWithFormData(url, formData, headers, parseDataFromResponse = true) {
const params = {
url,
formData,
headers,
parseDataFromResponse,
};
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER : params : ${JSON.stringify(params)}`);
const res = await this.doPostOrPutRequestWithFormData(url, RequestMethods.POST, formData, headers, parseDataFromResponse);
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT :`);
return res;
}
/**
* do put request with form data
* @param url
* @param formData
* @param headers
* @param parseDataFromResponse
* @returns {Promise<Record<any, any>>}
*/
async doPutRequestWithFormData(url, formData, headers, parseDataFromResponse = true) {
const params = {
url,
formData,
headers,
parseDataFromResponse,
};
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER : params : ${JSON.stringify(params)}`);
const res = await this.doPostOrPutRequestWithFormData(url, RequestMethods.PUT, formData, headers, parseDataFromResponse);
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT :`);
return res;
}
/**
* generate auth token from client creds
* @returns {Promise<Record<any, any>>}
*/
async getAuthTokenFromClientCreds() {
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER :`);
const clientID = config_1.SimbaConfig.retrieveEnvVar(config_1.SimbaEnvVarKeys.SIMBA_AUTH_CLIENT_ID);
const clientSecret = config_1.SimbaConfig.retrieveEnvVar(config_1.SimbaEnvVarKeys.SIMBA_AUTH_CLIENT_SECRET);
const authEndpoint = `${config_1.SimbaConfig.retrieveEnvVar(config_1.SimbaEnvVarKeys.SIMBA_AUTH_ENDPOINT)}token/`;
const credential = `${clientID}:${clientSecret}`;
const utf8EncodedCred = utf8_1.default.encode(credential);
const base64EncodedCred = Buffer.from(utf8EncodedCred).toString('base64');
const params = new URLSearchParams();
params.append('grant_type', "client_credentials");
const headers = {
"content-type": "application/x-www-form-urlencoded",
"Cache-Control": "no-cache",
"Authorization": `Basic ${base64EncodedCred}`
};
const config = {
headers,
};
try {
const url = this.buildURL(this.baseURL, authEndpoint);
config_1.SimbaConfig.log.debug(`:: url : ${url}`);
const res = await axios_1.default.post(url, params, config);
let authToken = res.data;
authToken = config_1.SimbaConfig.getAndSetParsedAuthToken(authToken);
return authToken;
}
catch (error) {
if (axios_1.default.isAxiosError(error) && error.response) {
config_1.SimbaConfig.log.error(`:: SIMBA : EXIT : ${JSON.stringify(error.response.data)}`);
}
else {
config_1.SimbaConfig.log.error(`:: SIMBA : EXIT : ${JSON.stringify(error)}`);
}
throw (error);
}
}
/**
* generate auth token, then set in authconfig.json
* @returns {Promise<Record<any, any>>}
*/
async setAndGetAuthToken() {
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER :`);
let authToken = this.getAuthTokenFromClientCreds();
config_1.SimbaConfig.authConfig.set(config_1.AUTHKEY, authToken);
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT :`);
return authToken;
}
/**
* returns headers with access token
* @returns {Promise<Record<any, any>>}
*/
async accessTokenHeader() {
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER :`);
let authToken;
if (config_1.SimbaConfig.tokenExpired()) {
authToken = await this.getAuthTokenFromClientCreds();
authToken = config_1.SimbaConfig.getAndSetParsedAuthToken(authToken);
}
else {
authToken = config_1.SimbaConfig.getAuthTokenFromConfig();
}
if (authToken) {
const accessToken = authToken.access_token;
const headers = {
Authorization: `Bearer ${accessToken}`,
};
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT :`);
return headers;
}
else {
const message = `unable to obtain auth token`;
config_1.SimbaConfig.log.error(`:: SIMBA : ${message}`);
throw (message);
}
}
/**
* generate headers with access token and other headers
* @param contentType
* @param queryParams
* @param addContentType
* @returns {Promise<Record<any, any>>}
*/
async getAuthAndOptions(contentType, queryParams, addContentType = true) {
const params = {
queryParams,
};
config_1.SimbaConfig.log.debug(`:: SIMBA : ENTER : params : ${JSON.stringify(params)}`);
const config = {};
const headers = await this.accessTokenHeader();
if (addContentType) {
if (contentType) {
headers["Content-Type"] = contentType;
}
else {
headers["Content-Type"] = "application/json";
}
}
config.headers = headers;
if (queryParams) {
config.params = queryParams;
}
config_1.SimbaConfig.log.debug(`:: SIMBA : EXIT :`);
return config;
}
}
exports.RequestHandler = RequestHandler;
//# sourceMappingURL=request_handler.js.map