import http from 'http' import { URL } from 'url' // taken from isobject npm library function isObject(val) { return val != null && typeof val === 'object' && Array.isArray(val) === false } function defaults(options, def) { let out = { } if (options) { Object.keys(options || {}).forEach(key => { out[key] = options[key] if (Array.isArray(out[key])) { out[key] = out[key].map(item => { if (isObject(item)) return defaults(item) return item }) } else if (out[key] && typeof out[key] === 'object') { out[key] = defaults(options[key], def && def[key]) } }) } if (def) { Object.keys(def).forEach(function(key) { if (typeof out[key] === 'undefined') { out[key] = def[key] } }) } return out } export default function Client(port, opts) { this.options = defaults(opts, {}) this.prefix = `http://localhost:${port}` } Client.prototype.customRequest = function(method = 'GET', path, body, options) { if (path.slice(0, 4) !== 'http') { path = this.prefix + path } let urlObj = new URL(path) return new Promise((resolve, reject) => { const opts = defaults(defaults(options, { method: method, timeout: 500, protocol: urlObj.protocol, username: urlObj.username, password: urlObj.password, host: urlObj.hostname, port: Number(urlObj.port), path: urlObj.pathname + urlObj.search, })) const req = http.request(opts) if (body) { req.write(body) } req.on('error', reject) req.on('timeout', function() { reject(new Error(`Request ${method} ${path} timed out`)) }) req.on('response', res => { res.setEncoding('utf8') let output = '' res.on('data', function (chunk) { output += chunk.toString() }) res.on('end', function () { try { output = JSON.parse(output) } catch (e) { return reject(new Error(`${e.message} while decoding: ${output}`)) } if (output.status) { let err = new Error(`Request failed [${output.status}]: ${output.message}`) err.body = output return reject(err) } resolve(output) }) }) req.end() }) } Client.prototype.get = function(path = '/') { return this.customRequest('GET', path, null) }