codekingpro/portable-devtools
114k
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 