UNPKG

rekwest

Version:

The robust request library that humanity deserves 🌐

122 lines (105 loc) 3.37 kB
import { Blob, isUtf8, } from 'node:buffer'; import http2 from 'node:http2'; import { buffer } from 'node:stream/consumers'; import { MIMEType } from 'node:util'; import { decode } from './codecs.js'; import { brandCheck } from './utils.js'; const { HTTP2_HEADER_CONTENT_ENCODING, HTTP2_HEADER_CONTENT_TYPE, } = http2.constants; export const mixin = (res, { decodersOptions, digest = false, parse = false } = {}) => { if (!digest) { Object.defineProperties(res, { arrayBuffer: { enumerable: true, value: async function () { brandCheck(this, res?.constructor); parse &&= false; const { buffer, byteLength, byteOffset } = await this.body(); return buffer.slice(byteOffset, byteOffset + byteLength); }, }, blob: { enumerable: true, value: async function () { brandCheck(this, res?.constructor); const val = await this.arrayBuffer(); return new Blob([val]); }, }, bytes: { enumerable: true, value: async function () { brandCheck(this, res?.constructor); return new Uint8Array(await this.arrayBuffer()); }, }, json: { enumerable: true, value: async function () { brandCheck(this, res?.constructor); const val = await this.text(); return JSON.parse(val); }, }, text: { enumerable: true, value: async function () { brandCheck(this, res?.constructor); const blob = await this.blob(); return blob.text(); }, }, }); } return Object.defineProperties(res, { body: { enumerable: true, value: async function () { brandCheck(this, res?.constructor); if (this.bodyUsed) { throw new TypeError('Response stream already read.'); } let body = await buffer(decode(this, this.headers[HTTP2_HEADER_CONTENT_ENCODING], { decodersOptions })); if (!body.length && parse) { return null; } if (body.length && parse) { const contentType = this.headers[HTTP2_HEADER_CONTENT_TYPE] ?? ''; let isTextual, mimeType; try { mimeType = contentType ? new MIMEType(contentType) : null; } finally { isTextual = mimeType && ( mimeType.type === 'text' || mimeType.subtype.match(/\bcsv\b|\bjson\b|\bxml\b|\byaml\b/) || mimeType.essence.match(/\becmascript\b|\bjavascript\b|\bx-www-form-urlencoded\b/) ); } if (isTextual) { if (/\bjson\b/.test(mimeType)) { body = JSON.parse(body.toString()); } else if (isUtf8(body)) { body = body.toString(); } else { const charset = mimeType.params.get('charset')?.toLowerCase() ?? 'utf-8'; body = new TextDecoder(charset, { fatal: true }).decode(body); } } } return body; }, writable: true, }, bodyUsed: { enumerable: true, get() { return this.readableEnded; }, }, }); };