zcatalyst-integ-cliq
Version:
Node.js SDK for integrating Zoho Catalyst with Zoho Cliq
130 lines (129 loc) • 4.42 kB
JavaScript
import { request } from 'https';
import { stringify } from 'querystring';
import { parse } from 'url';
import { inspect } from 'util';
import { CatalystError } from '../error.js';
import CONSTANT from '../constants.js';
import FORM from 'zcatalyst-sdk-node/lib/utils/form-data.js';
export default class ApiUtil {
constructor(connection) {
this.connection = connection;
}
async sendRequest(url, requestBody, params, file) {
if (params !== undefined) {
url = this.appendQueryData(url, params);
}
const parsed = parse(url);
let headers = {
['Authorization']: CONSTANT.API_CONSTANTS.OAUTH_PREFIX + (await this.connection.getAccessToken()),
['User-Agent']: CONSTANT.USER_AGENT
};
const formData = file !== undefined ? new FORM().append('file', file) : undefined;
if (formData) {
headers = formData.getHeaders(headers);
}
const options = {
hostname: parsed.hostname,
port: parsed.port,
path: parsed.path,
method: 'post',
headers
};
return apiRequest(options, requestBody, params, formData);
}
appendQueryData(url, data) {
if (data && Object.keys(data).length > 0) {
url += url.includes('?') ? '&' : '?';
url += stringify(data);
}
return url;
}
}
export async function apiRequest(options, data, params, formData) {
return new Promise((resolve, reject) => {
const req = request(options, (res) => {
if (req.aborted) {
return;
}
const response = Object.assign({
headers: res.headers,
request: req,
params
}, res);
const responseBuffer = [];
res.on('data', (chunk) => {
responseBuffer.push(chunk);
});
res.on('error', (err) => {
if (req.aborted) {
return;
}
reject(err);
});
res.on('end', () => {
const responseData = Buffer.concat(responseBuffer);
response.data = responseData.toString();
response.buffer = responseData;
if (response.statusCode === undefined) {
reject(new CatalystError('unknown_status_code', 2));
return;
}
if (response.statusCode >= 200 && response.statusCode < 300) {
resolve(response);
}
else {
try {
const responseData = JSON.parse(response.data);
reject('Request failed with status ' +
response.statusCode +
' and code: ' +
responseData.data.error_code +
' ,message: ' +
responseData.data.message);
}
catch (e) {
reject('Request failed with status ' +
response.statusCode +
' and response data: ' +
inspect(response.data));
}
}
});
});
//error handler
req.on('error', (err) => {
if (req.aborted) {
return;
}
reject(err);
req.end();
});
flushData(req, data, formData)
.catch((err) => {
throw new CatalystError(err);
})
.finally(() => req.end());
});
}
function flushData(req, data, formData) {
const promiseArr = [];
if (data) {
promiseArr.push(new Promise((resolve, reject) => {
const isSuccessful = req.write(JSON.stringify(data));
if (isSuccessful) {
resolve();
}
else {
reject('DATA WRITE UNSUCCESSFUL');
}
}));
}
if (formData) {
promiseArr.push(new Promise((resolve, reject) => {
formData.on('end', () => resolve());
formData.on('error', (err) => reject(err));
formData.pipe(req);
}));
}
return Promise.all(promiseArr);
}