1'use strict' 2const http = require('http') 3const { STATUS_CODES } = http 4 5const Headers = require('./headers.js') 6const Body = require('./body.js') 7const { clone, extractContentType } = Body 8 9const INTERNALS = Symbol('Response internals') 10 11class Response extends Body { 12 constructor (body = null, opts = {}) { 13 super(body, opts) 14 15 const status = opts.status || 200 16 const headers = new Headers(opts.headers) 17 18 if (body !== null && body !== undefined && !headers.has('Content-Type')) { 19 const contentType = extractContentType(body) 20 if (contentType) { 21 headers.append('Content-Type', contentType) 22 } 23 } 24 25 this[INTERNALS] = { 26 url: opts.url, 27 status, 28 statusText: opts.statusText || STATUS_CODES[status], 29 headers, 30 counter: opts.counter, 31 trailer: Promise.resolve(opts.trailer || new Headers()), 32 } 33 } 34 35 get trailer () { 36 return this[INTERNALS].trailer 37 } 38 39 get url () { 40 return this[INTERNALS].url || '' 41 } 42 43 get status () { 44 return this[INTERNALS].status 45 } 46 47 get ok () { 48 return this[INTERNALS].status >= 200 && this[INTERNALS].status < 300 49 } 50 51 get redirected () { 52 return this[INTERNALS].counter > 0 53 } 54 55 get statusText () { 56 return this[INTERNALS].statusText 57 } 58 59 get headers () { 60 return this[INTERNALS].headers 61 } 62 63 clone () { 64 return new Response(clone(this), { 65 url: this.url, 66 status: this.status, 67 statusText: this.statusText, 68 headers: this.headers, 69 ok: this.ok, 70 redirected: this.redirected, 71 trailer: this.trailer, 72 }) 73 } 74 75 get [Symbol.toStringTag] () { 76 return 'Response' 77 } 78} 79 80module.exports = Response 81 82Object.defineProperties(Response.prototype, { 83 url: { enumerable: true }, 84 status: { enumerable: true }, 85 ok: { enumerable: true }, 86 redirected: { enumerable: true }, 87 statusText: { enumerable: true }, 88 headers: { enumerable: true }, 89 clone: { enumerable: true }, 90}) 91