koa 3.0.0-alpha.3 → 3.0.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,7 @@ const Emitter = require('events')
16
16
  const util = require('util')
17
17
  const Stream = require('stream')
18
18
  const http = require('http')
19
+ const isStream = require('./is-stream.js')
19
20
  const only = require('./only.js')
20
21
  const { HttpError } = require('http-errors')
21
22
 
@@ -55,7 +56,7 @@ module.exports = class Application extends Emitter {
55
56
  * @param {string} [options.proxyIpHeader] Proxy IP header, defaults to X-Forwarded-For
56
57
  * @param {number} [options.maxIpsCount] Max IPs read from proxy IP header, default to 0 (means infinity)
57
58
  * @param {function} [options.compose] Function to handle middleware composition
58
- * @param {boolean} [options.asyncLocalStorage] Max IPs read from proxy IP header, default to 0 (means infinity)
59
+ * @param {boolean} [options.asyncLocalStorage] Enable AsyncLocalStorage, default to false
59
60
  *
60
61
  */
61
62
 
@@ -258,9 +259,10 @@ function respond (ctx) {
258
259
  // allow bypassing koa
259
260
  if (ctx.respond === false) return
260
261
 
261
- if (!ctx.writable) return
262
-
263
262
  const res = ctx.res
263
+
264
+ if (!ctx.writable) return res.end()
265
+
264
266
  let body = ctx.body
265
267
  const code = ctx.status
266
268
 
@@ -303,10 +305,10 @@ function respond (ctx) {
303
305
 
304
306
  if (Buffer.isBuffer(body)) return res.end(body)
305
307
  if (typeof body === 'string') return res.end(body)
306
- if (body instanceof Stream) return body.pipe(res)
307
308
  if (body instanceof Blob) return Stream.Readable.from(body.stream()).pipe(res)
308
309
  if (body instanceof ReadableStream) return Stream.Readable.from(body).pipe(res)
309
310
  if (body instanceof Response) return Stream.Readable.from(body?.body || '').pipe(res)
311
+ if (isStream(body)) return body.pipe(res)
310
312
 
311
313
  // body: json
312
314
  body = JSON.stringify(body)
package/lib/context.js CHANGED
@@ -150,9 +150,6 @@ const proto = module.exports = {
150
150
 
151
151
  let statusCode = err.status || err.statusCode
152
152
 
153
- // ENOENT support
154
- if (err.code === 'ENOENT') statusCode = 404
155
-
156
153
  // default to 500
157
154
  if (typeof statusCode !== 'number' || !statuses.message[statusCode]) statusCode = 500
158
155
 
@@ -0,0 +1,20 @@
1
+ 'use strict'
2
+
3
+ const Stream = require('stream')
4
+
5
+ // TODO: use a third party library for this
6
+
7
+ module.exports = (stream) => {
8
+ return (
9
+ stream instanceof Stream ||
10
+ (stream !== null &&
11
+ typeof stream === 'object' &&
12
+ !!stream.readable &&
13
+ typeof stream.pipe === 'function' &&
14
+ typeof stream.read === 'function' &&
15
+ typeof stream.readable === 'boolean' &&
16
+ typeof stream.readableObjectMode === 'boolean' &&
17
+ typeof stream.destroy === 'function' &&
18
+ typeof stream.destroyed === 'boolean')
19
+ )
20
+ }
package/lib/request.js CHANGED
@@ -89,14 +89,14 @@ module.exports = {
89
89
  },
90
90
 
91
91
  /**
92
- * Get origin of URL.
92
+ * Get the origin header.
93
93
  *
94
94
  * @return {String}
95
95
  * @api public
96
96
  */
97
97
 
98
98
  get origin () {
99
- return `${this.protocol}://${this.host}`
99
+ return this.req.headers.origin || null
100
100
  },
101
101
 
102
102
  /**
@@ -109,7 +109,7 @@ module.exports = {
109
109
  get href () {
110
110
  // support: `GET http://example.com/foo`
111
111
  if (/^https?:\/\//i.test(this.originalUrl)) return this.originalUrl
112
- return this.origin + this.originalUrl
112
+ return this.protocol + '://' + this.host + this.originalUrl
113
113
  },
114
114
 
115
115
  /**
@@ -288,7 +288,7 @@ module.exports = {
288
288
  if (!this.memoizedURL) {
289
289
  const originalUrl = this.originalUrl || '' // avoid undefined in template string
290
290
  try {
291
- this.memoizedURL = new URL(`${this.origin}${originalUrl}`)
291
+ this.memoizedURL = new URL(`${this.protocol}://${this.host}${originalUrl}`)
292
292
  } catch (err) {
293
293
  this.memoizedURL = Object.create(null)
294
294
  }
@@ -732,6 +732,6 @@ if (util.inspect.custom) {
732
732
  * @param {number} [limit] - The maximum number of values to return.
733
733
  * @returns {string[]} An array of values from the comma-separated string.
734
734
  */
735
- function splitCommaSeparatedValues(value, limit) {
736
- return value.split(',', limit).map(v => v.trim());
735
+ function splitCommaSeparatedValues (value, limit) {
736
+ return value.split(',', limit).map(v => v.trim())
737
737
  }
package/lib/response.js CHANGED
@@ -14,10 +14,10 @@ const destroy = require('destroy')
14
14
  const assert = require('assert')
15
15
  const extname = require('path').extname
16
16
  const vary = require('vary')
17
+ const isStream = require('./is-stream.js')
17
18
  const only = require('./only.js')
18
19
  const util = require('util')
19
20
  const encodeUrl = require('encodeurl')
20
- const Stream = require('stream')
21
21
  const deprecate = require('depd')('koa')
22
22
 
23
23
  /**
@@ -172,7 +172,7 @@ module.exports = {
172
172
  }
173
173
 
174
174
  // stream
175
- if (val instanceof Stream) {
175
+ if (isStream(val)) {
176
176
  onFinish(this.res, destroy.bind(null, val))
177
177
  if (original !== val) {
178
178
  val.once('error', err => this.ctx.onerror(err))
@@ -211,7 +211,7 @@ module.exports = {
211
211
 
212
212
  // json
213
213
  this.remove('Content-Length')
214
- this.type = 'json'
214
+ if (!this.type || !/\bjson\b/i.test(this.type)) this.type = 'json'
215
215
  },
216
216
 
217
217
  /**
@@ -240,7 +240,7 @@ module.exports = {
240
240
  }
241
241
 
242
242
  const { body } = this
243
- if (!body || body instanceof Stream) return undefined
243
+ if (!body || isStream(body)) return undefined
244
244
  if (typeof body === 'string') return Buffer.byteLength(body)
245
245
  if (Buffer.isBuffer(body)) return body.length
246
246
  return Buffer.byteLength(JSON.stringify(body))
@@ -309,7 +309,7 @@ module.exports = {
309
309
  if (this.ctx.accepts('html')) {
310
310
  url = escape(url)
311
311
  this.type = 'text/html; charset=utf-8'
312
- this.body = `Redirecting to <a href="${url}">${url}</a>.`
312
+ this.body = `Redirecting to ${url}.`
313
313
  return
314
314
  }
315
315
 
@@ -513,22 +513,18 @@ module.exports = {
513
513
  * this.set('Accept', 'application/json');
514
514
  * this.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
515
515
  *
516
- * @param {String|Object|Array} field
517
- * @param {*} val
516
+ * @param {String|{ [k: string]: any }} field
517
+ * @param {any} [val]
518
518
  * @api public
519
519
  */
520
520
 
521
521
  set (field, val) {
522
- if (this.headerSent) return
522
+ if (this.headerSent || !field) return
523
523
 
524
- if (arguments.length === 2) {
525
- if (Array.isArray(val)) val = val.map(v => typeof v === 'string' ? v : String(v))
526
- else if (typeof val !== 'string') val = String(val)
524
+ if (typeof field === 'string') {
527
525
  this.res.setHeader(field, val)
528
526
  } else {
529
- for (const key in field) {
530
- this.set(key, field[key])
531
- }
527
+ Object.keys(field).forEach(header => this.res.setHeader(header, field[header]))
532
528
  }
533
529
  },
534
530
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koa",
3
- "version": "3.0.0-alpha.3",
3
+ "version": "3.0.0-alpha.5",
4
4
  "publishConfig": {
5
5
  "tag": "experimental"
6
6
  },
@@ -55,7 +55,7 @@
55
55
  "on-finished": "^2.3.0",
56
56
  "parseurl": "^1.3.2",
57
57
  "statuses": "^2.0.1",
58
- "type-is": "^1.6.16",
58
+ "type-is": "^2.0.1",
59
59
  "vary": "^1.1.2"
60
60
  },
61
61
  "devDependencies": {
@@ -70,5 +70,6 @@
70
70
  "files": [
71
71
  "dist",
72
72
  "lib"
73
- ]
73
+ ],
74
+ "homepage": "https://koajs.com"
74
75
  }