const { clone } = require('../utils/helpers');
const current_API_version_endpoint = 3;
const allowableVersions = [2, 3];
const is_nodejs = typeof module !== 'undefined' && module.exports;
/**
* @description Make a request using the SkyCiv API
* @param {object} apiObject A SkyCiv API Object
* @param {function} callback The function to run after the request. Receives a parsed response.
* @param {Object} options Additional options
* @param {2 | 3} options.version The API version to use. Defaults to 3.
* @param {"http" | "https"} options.http_or_https Whethere the request should use http or https. Defaults to https.
*/
function request(apiObject, callback, options = {}) {
let reqObject = clone(apiObject);
// Convert ApiObject class to JSON - Can't use instanceof as it will create a circular dependency.
if (apiObject.__proto__.constructor.name === 'ApiObject') {
reqObject = apiObject.get();
}
// Input validation
if (!options) options = {};
// Check version
if (!options.version) options.version = current_API_version_endpoint;
if (!allowableVersions.includes(options.version))
throw new Error(
`options.version should be one of the following: ${allowableVersions.join(', ')}`
);
// Check transport method
if (!options.http_or_https) options.http_or_https = 'https';
// Check if already stringified
if (typeof reqObject === 'object') {
reqObject = JSON.stringify(reqObject);
}
// FOR NODE.JS
if (is_nodejs) {
var req_module;
var req_port;
if (options.http_or_https == 'https') {
req_module = require('https');
req_port = 8085; // 443;
} else {
req_module = require('http');
req_port = 8086; // 80;
}
var req_options = {
hostname: 'api.skyciv.com',
port: req_port,
path: '/v' + options.version + '',
method: 'POST',
headers: {
// these are compulsory for it to work properly
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(reqObject),
},
//timeout: timeout
};
var req = req_module.request(req_options, function (res) {
res.setEncoding('utf8');
var res_data = '';
res.on('data', function (chunk) {
res_data += chunk;
});
res.on('end', function () {
if (!res_data) {
res_data = JSON.stringify({
response: {
status: 1,
msg:
'No response was received from the API. Please contact [email protected] for more assistance with this.',
},
});
}
const parsed_res = JSON.parse(res_data);
if (callback) {
callback(parsed_res);
}
});
});
req.on('error', function (e) {
console.log('Problem with request: ' + e.message);
});
// Send the object as a JSON string
req.write(reqObject);
req.end();
} else {
// FOR BROWSER
var req = new XMLHttpRequest();
req.onreadystatechange = function () {
if (req.readyState == XMLHttpRequest.DONE) {
var response_obj;
try {
if (req.responseText) {
response_obj = JSON.parse(req.responseText);
} else {
response_obj = {
response: {
status: 1,
msg:
'No response was received from the API. Please contact [email protected] for more assistance with this.',
},
};
}
} catch (e) {
response_obj = {
response: {
status: 2,
msg:
'There was an issue parsing the response from the API. Please contact [email protected] for more assistance with this.',
},
};
}
if (typeof response_obj === 'string') {
response_obj = JSON.parse(response_obj);
}
if (callback) {
callback(response_obj);
}
}
};
var req_port = '';
if (options.http_or_https == 'https') {
req_port = ':8085'; // 443;
} else {
req_port = ':8086'; // 80;
}
//req.timeout = timeout;
req.open(
'POST',
options.http_or_https + '://api.skyciv.com' + req_port + '/v' + options.version,
true
); // true=async
req.setRequestHeader('Content-type', 'application/json');
req.send(reqObject);
}
}
module.exports = request;