const logger = require('./logger.js'); const realpath = require('fs/promises').realpath; const stat = require('fs/promises').stat; const http = require('http'); const { HTTP_GET, HTTP_POST } = require('./constants.js'); function timeDiff(startTime) { if (startTime instanceof Date) { return (new Date().getTime() - startTime.getTime()); } return new Date().getTime - startTime; } function clone(object) { let clone = {}; for (key in object) { clone[key] = object[key]; } return clone; } function httpGET(host, port, path, args) { return httpRequest(host, port, path, HTTP_GET, args); } function httpPOST(host, port, path, args) { return httpRequest(host, port, path, HTTP_POST, args); } function httpRequest(host, port, path, method, args) { return new Promise((resolve, reject) => { if (!path.startsWith("/")) { path = "/" + path; } const options = { hostname: host, port: port, path: path, method: method, timeout: global.config?.requests?.timeout || 5000 }; let requestName = 'http \'' + method + '\' request > \'' + host + ':' + port + path; if (args !== undefined) { args = new URLSearchParams(args).toString(); options.headers = { 'Content-Type': 'application/x-www-form-urlencoded' } requestName += '?' + args; } requestName += '\''; logger.debug('sending ' + requestName + '...'); const request = http.request(options, (response) => { if (!response) { return reject('no response from host for ' + requestName); } let responseData = ""; response.on('data', (data) => { responseData += data; }); response.on('end', () => { logger.debug(requestName + ' returned status code \'' + response.statusCode + '\' and data \'' + responseData + '\''); let fn = resolve; if (response.statusCode != 200) { fn = reject; } if (!responseData) { return fn(); } try { return fn(JSON.parse(responseData)); } catch (err) { return fn(responseData); } }); }); request.on('timeout', () => { request.destroy(); return reject(requestName + ' timed out after ' + options.timeout + 'ms'); }); request.on('error', (err) => { return reject(requestName + ' returned an error >>> ' + err.message); }); if (args !== undefined) { request.write(args); } request.end(); }); } function toHex(value) { let hex = Number(value).toString(16); return hex; } function hexToRGB(hex) { let validHEXInput = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); if (!validHEXInput) { return; } let output = [ { red: parseInt(validHEXInput[1], 16), green: parseInt(validHEXInput[2], 16), blue: parseInt(validHEXInput[3], 16), }, ]; return output; } function sortById(array) { return array.sort((a, b) => { return a.id - b.id; }); } function fileExists(file) { return new Promise((resolve, reject) => { if (file == undefined) { reject('can not check the existence of an undefined file'); } resolvePath(file) .then((path) => { stat(path) .then((stats) => { resolve({ path, stats }); }) }) .catch(reject); }); } function resolvePath(file) { return new Promise((resolve, reject) => { if (file == undefined) { reject('can not resolve a path to an undefined file'); } realpath(file) .then(resolve) .catch((err) => { reject('resolving path \'' + file + '\' encountered an error >>> ' + err); }); }); } module.exports = { timeDiff, clone, httpGET, httpPOST, toHex, hexToRGB, sortById, fileExists, resolvePath }