UNPKG

@remix-run/web-fetch

Version:

Web API compatible fetch implementation

144 lines (123 loc) 2.9 kB
/** * Response.js * * Response class provides content decoding */ import Headers from './headers.js'; import Body, {clone, extractContentType} from './body.js'; import {isRedirect} from './utils/is-redirect.js'; const INTERNALS = Symbol('Response internals'); /** * Response class * * @typedef {Object} Ext * @property {number} [size] * @property {string} [url] * @property {number} [counter] * @property {number} [highWaterMark] * * @implements {globalThis.Response} */ export default class Response extends Body { /** * @param {BodyInit|import('stream').Stream|null} [body] - Readable stream * @param {ResponseInit & Ext} [options] - Response options */ constructor(body = null, options = {}) { super(body, options); const status = options.status || 200; const headers = new Headers(options.headers); if (body !== null && !headers.has('Content-Type')) { const contentType = extractContentType(this); if (contentType) { headers.append('Content-Type', contentType); } } /** * @private */ this[INTERNALS] = { url: options.url, status, statusText: options.statusText || '', headers, counter: options.counter || 0, highWaterMark: options.highWaterMark }; } /** * @type {ResponseType} */ get type() { return "default" } get url() { return this[INTERNALS].url || ''; } get status() { return this[INTERNALS].status; } /** * Convenience property representing if the request ended normally */ get ok() { return this[INTERNALS].status >= 200 && this[INTERNALS].status < 300; } get redirected() { return this[INTERNALS].counter > 0; } get statusText() { return this[INTERNALS].statusText; } /** * @type {Headers} */ get headers() { return this[INTERNALS].headers; } get highWaterMark() { return this[INTERNALS].highWaterMark; } /** * Clone this response * * @returns {Response} */ clone() { return new Response(clone(this), { url: this.url, status: this.status, statusText: this.statusText, headers: this.headers, size: this.size }); } /** * @param {string} url The URL that the new response is to originate from. * @param {number} status An optional status code for the response (e.g., 302.) * @returns {Response} A Response object. */ static redirect(url, status = 302) { if (!isRedirect(status)) { throw new RangeError('Failed to execute "redirect" on "response": Invalid status code'); } return new Response(null, { headers: { location: new URL(url).toString() }, status }); } get [Symbol.toStringTag]() { return 'Response'; } } Object.defineProperties(Response.prototype, { url: {enumerable: true}, status: {enumerable: true}, ok: {enumerable: true}, redirected: {enumerable: true}, statusText: {enumerable: true}, headers: {enumerable: true}, clone: {enumerable: true} });