const axios = require('axios');
const _ = require('lodash');
const methodMap = require('./methods');
const API_METHODS = require('./request-type');
const BASE_URL = 'https://platform.segmentapis.com/v1beta';
/**
* @class SegmentApi
*/
class SegmentApi {
/**
*
* @param config
* @param config.WORKSPACE
* @param [config.BASE_URL]
* @param [config.TOKEN]
* @param [config.CATALOG_SOURCE]
* @param [config.CONNECTION_MODE]
* @param [config.transformApiConfig]
*/
constructor(config) {
this.__axios = axios.create({
baseURL: config.BASE_URL || BASE_URL,
});
this.WORKSPACE = config.WORKSPACE;
this.CATALOG_SOURCE = config.CATALOG_SOURCE || 'catalog/sources/javascript';
this.CONNECTION_MODE = config.CONNECTION_MODE || 'CLOUD';
this.TOKEN = config.TOKEN;
this.transformApiConfig = config.transformApiConfig || this.transformConfig;
this.applyMethods(methodMap);
};
/**
* @private
* @param methodMap
*/
applyMethods(methodMap) {
Object.keys(methodMap)
.forEach((methodName) => {
this[methodName] = (...rest) => {
if (!rest.length) {
rest = [{}];
}
const config = methodMap[methodName].call(this, ...rest);
return this.callAPI(config);
};
});
}
/**
* @private
* @param config
* @return {AxiosPromise<any>}
*/
async axios(config) {
return this.__axios(this.transformApiConfig(config));
}
/**
* @private
* @param {Object} params
* @param params.method
* @param params.url
* @param params.data
* @param params.headers
* @param params.rest
* @return {Promise<AxiosResponse<any>>}
*/
async callAPI({method, url, data, headers = {}, ...rest}) {
const requestHeaders = _.clone(headers);
if (url.indexOf('access-tokens') === -1 && !!this.TOKEN &&
!requestHeaders.Authorization) {
requestHeaders.Authorization = `Bearer ${this.TOKEN}`;
}
let requestData = {data};
if (method === API_METHODS.GET) {
requestData = {params: data};
}
const config = {
...rest,
...requestData,
method,
headers: requestHeaders,
url,
};
try {
const response = await this.axios(config);
return response;
} catch (err) {
this.handleError(err);
}
}
/**
* @private
* @param err
*/
handleError(err) {
const responseErrorMessage = _.get(err, 'response.data.error');
if (!responseErrorMessage) {
throw err;
}
const error = new Error(responseErrorMessage);
error.errorCode = _.get(err, 'response.data.code');
error.statusCode = _.get(err, 'response.status');
error.headers = _.get(err, 'response.headers');
throw error;
}
/**
* @private
* @param config
* @return {*}
*/
transformConfig(config) {
return config;
}
}
module.exports = SegmentApi;