96 lines
2.3 KiB
JavaScript
96 lines
2.3 KiB
JavaScript
|
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)
|
||
|
}
|