UNPKG

@kmamal/sdl

Version:
86 lines (72 loc) 1.69 kB
const _consume = async (stream) => { const chunks = [] for await (const chunk of stream) { chunks.push(chunk) } return Buffer.concat(chunks) } const fetch = async (_url, options = {}) => { let url = _url let { maxRedirect = 5, body = null, } = options const { protocol } = new URL(url) const lib = require(protocol.slice(0, -1)) const evalPromise = (resolve, reject) => { const request = lib.request(url, options) .on('error', reject) .on('response', resolve) if (!body) { request.end() return } if (body?.length) { if (!Buffer.isBuffer(body)) { body = Buffer.from(body) } body = Promise.resolve(body) } else { body = _consume(body) } body.then((buffer) => { request.setHeader('Content-Length', buffer.length) request.end(buffer) }) } for (;;) { const response = await new Promise(evalPromise) const { statusCode } = response if (300 <= statusCode && statusCode < 400) { if (maxRedirect-- > 0) { url = response.headers.location continue } } if (!(200 <= statusCode && statusCode < 300)) { let responseBody try { responseBody = (await _consume(response)).toString() } catch (_) {} try { responseBody = JSON.parse(responseBody) } catch (_) {} throw Object.assign(new Error(`bad status code ${statusCode}`), { statusCode, responseBody, }) } return { stream () { return response }, async buffer () { return await _consume(response) }, async text () { const buffer = await this.buffer() return buffer.toString() }, async json () { const text = await this.text() return JSON.parse(text) }, } } } module.exports = { fetch }