koa 2.10.0 → 2.13.0

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.
package/History.md CHANGED
@@ -1,4 +1,57 @@
1
1
 
2
+ 2.13.0 / 2020-06-21
3
+ ==================
4
+
5
+ **features**
6
+ * [[`bbcde76`](http://github.com/koajs/koa/commit/bbcde76f5cb5b67bbcd3201791cf0ef648fd3a8b)] - feat: support esm (#1474) (ZYSzys <<zhangyongsheng@youzan.com>>)
7
+
8
+ **others**
9
+ * [[`20e58cf`](http://github.com/koajs/koa/commit/20e58cf3e4f20fc5d5886df1d0ac6dd8c33bd202)] - test: imporve coverage to 100% (dead-horse <<dead_horse@qq.com>>)
10
+ * [[`4a40d63`](http://github.com/koajs/koa/commit/4a40d633c4b4a203c6656078f9952ccef65c5875)] - build: use prepare instead of prepublish (dead-horse <<dead_horse@qq.com>>)
11
+ * [[`226ba8c`](http://github.com/koajs/koa/commit/226ba8c8e81e83da48e7bf137be3f146d03f40b8)] - build: use prepublish instead of prepack (dead-horse <<dead_horse@qq.com>>)
12
+
13
+ 2.12.1 / 2020-06-13
14
+ ==================
15
+
16
+ **fixes**
17
+ * [[`e2030c7`](http://github.com/koajs/koa/commit/e2030c7249c7ae24e28158d8eae405a02fefc9f8)] - fix: Improve checks for Error in onerror handlers (#1468) (Julien Wajsberg <<felash@gmail.com>>)
18
+
19
+ **others**
20
+ * [[`5208c5e`](http://github.com/koajs/koa/commit/5208c5e15d35b3653fce6b8ed68d09865abea843)] - chore: Use single console.error() statement in error handler (#1471) (Mike Vosseller <<michael.vosseller@gmail.com>>)
21
+
22
+ 2.12.0 / 2020-05-18
23
+ ==================
24
+
25
+ **features**
26
+ * [[`0d2f421`](http://github.com/koajs/koa/commit/0d2f421c265350d3d84e1bc261572954479f27d3)] - feat: error handler treat err.statusCode as the same as err.status (#1460) (Vijay Krishnavanshi <<vijaykrishnavanshi@gmail.com>>)
27
+ * [[`8d52105`](http://github.com/koajs/koa/commit/8d52105a34234be9e771ff3b76b43e4e30328943)] - feat: allow bodyless responses for non empty status codes (#1447) (ejose19 <<8742215+ejose19@users.noreply.github.com>>)
28
+
29
+ **others**
30
+ * [[`faeaff5`](http://github.com/koajs/koa/commit/faeaff5c149a81a188ab8e5af0b994029e45acbb)] - fox: remove `error-inject` and fix error handling (#1409) (Konstantin Vyatkin <<tino@vtkn.io>>)
31
+ * [[`f7c732f`](http://github.com/koajs/koa/commit/f7c732fd06f724505e9090add4d977e667da55a8)] - docs: fixed incorrect onerror example (#1459) (Paul Annekov <<paul.annekov@gmail.com>>)
32
+ * [[`143d8f7`](http://github.com/koajs/koa/commit/143d8f72f2a232b4c97eac00e7811015911e4f7c)] - Always use strict equality. (#1225) (Yazan Medanat <<medanat@gmail.com>>)
33
+ * [[`6b6b0dd`](http://github.com/koajs/koa/commit/6b6b0ddf7aff073e65493c6efaffab8331c0331c)] - docs(api): add app.use chainability note (#1449) (Zac Anger <<zac@zacanger.com>>)
34
+ * [[`8ddab48`](http://github.com/koajs/koa/commit/8ddab48cbdbca1e6d1cc8c3ddae45491db524d51)] - docs: Document response status with empty body (#1445) (Marc-Aurèle DARCHE <<152407+madarche@users.noreply.github.com>>)
35
+ * [[`7deedb2`](http://github.com/koajs/koa/commit/7deedb235274223f1b9da46dee296545b23598de)] - docs: Updating context.md with the latest cookies opts (#1433) (Brad Ito <<phlogisticfugu@users.noreply.github.com>>)
36
+ * [[`3e97a10`](http://github.com/koajs/koa/commit/3e97a106bb846d9337737011bb85149ddd797229)] - docs(links): remove Google+ link (#1439) (laffachan <<45162759+laffachan@users.noreply.github.com>>)
37
+ * [[`eda2760`](http://github.com/koajs/koa/commit/eda27608f7d39ede86d7b402aae64b1867ce31c6)] - build: Drop unused Travis sudo: false directive (#1416) (Olle Jonsson <<olle.jonsson@gmail.com>>)
38
+
39
+ 2.11.0 / 2019-10-28
40
+ ==================
41
+
42
+ **features**
43
+ * [[`422e539`](http://github.com/koajs/koa/commit/422e539e8989e65ba43ecc39ddbaa3c4f755d465)] - feat: support app.proxyIPHeader and app.maxIpsCount to make ctx.ips more security (Yiyu He <<dead_horse@qq.com>>)
44
+ * [[`d48d88e`](http://github.com/koajs/koa/commit/d48d88ee17b780c02123e6d657274cab456e943e)] - feat: implement response.has (#1397) (Konstantin Vyatkin <<tino@vtkn.io>>)
45
+
46
+ **others**
47
+ * [[`4dc56f6`](http://github.com/koajs/koa/commit/4dc56f6d04e8f5fe12ba53a8a776653b3d7b60ed)] - chore: update ESLint and plugins/configs (#1407) (Konstantin Vyatkin <<tino@vtkn.io>>)
48
+ * [[`be7d334`](http://github.com/koajs/koa/commit/be7d334778481639294cdf87f5c359a230aeb65b)] - chore: removes code duplication at handling HEAD method (#1400) (Konstantin Vyatkin <<tino@vtkn.io>>)
49
+ * [[`f155785`](http://github.com/koajs/koa/commit/f155785e2bb42b5ddf0a8156401c6dafdf57ba8b)] - chore: support `writableEnded` (#1402) (Konstantin Vyatkin <<tino@vtkn.io>>)
50
+ * [[`b968688`](http://github.com/koajs/koa/commit/b968688afe2c727ae141f50aa983d481dbc1dbbf)] - chore: add FUNDING.yml (#1403) (Konstantin Vyatkin <<tino@vtkn.io>>)
51
+ * [[`4f96829`](http://github.com/koajs/koa/commit/4f968298f97394e488297ec32c8e927a3a322076)] - chore: remove isJSON in res.length (#1399) (Konstantin Vyatkin <<tino@vtkn.io>>)
52
+ * [[`8be5626`](http://github.com/koajs/koa/commit/8be5626bbb54e6c899a1b71d22411709126d9fea)] - build: enable codecov partial coverage and use bash uploader (#1396) (Konstantin Vyatkin <<tino@vtkn.io>>)
53
+ * [[`ef5c43b`](http://github.com/koajs/koa/commit/ef5c43bcbcf31819e032c3b7ae7654b7f8e9358b)] - chore: use rest params (#1393) (Konstantin Vyatkin <<tino@vtkn.io>>)
54
+
2
55
  2.10.0 / 2019-10-12
3
56
  ==================
4
57
 
package/Readme.md CHANGED
@@ -221,7 +221,6 @@ See [AUTHORS](AUTHORS).
221
221
  - [Examples](https://github.com/koajs/examples)
222
222
  - [Middleware](https://github.com/koajs/koa/wiki) list
223
223
  - [Wiki](https://github.com/koajs/koa/wiki)
224
- - [G+ Community](https://plus.google.com/communities/101845768320796750641)
225
224
  - [Reddit Community](https://www.reddit.com/r/koajs)
226
225
  - [Mailing list](https://groups.google.com/forum/#!forum/koajs)
227
226
  - [中文文档 v1.x](https://github.com/guo-yu/koa-guide)
package/dist/koa.mjs ADDED
@@ -0,0 +1,4 @@
1
+ import mod from "../lib/application.js";
2
+
3
+ export default mod;
4
+ export const HttpError = mod.HttpError;
@@ -10,7 +10,6 @@ const debug = require('debug')('koa:application');
10
10
  const onFinished = require('on-finished');
11
11
  const response = require('./response');
12
12
  const compose = require('koa-compose');
13
- const isJSON = require('koa-is-json');
14
13
  const context = require('./context');
15
14
  const request = require('./request');
16
15
  const statuses = require('statuses');
@@ -42,6 +41,8 @@ module.exports = class Application extends Emitter {
42
41
  * @param {string[]} [options.keys] Signed cookie keys
43
42
  * @param {boolean} [options.proxy] Trust proxy headers
44
43
  * @param {number} [options.subdomainOffset] Subdomain offset
44
+ * @param {boolean} [options.proxyIpHeader] proxy ip header, default to X-Forwarded-For
45
+ * @param {boolean} [options.maxIpsCount] max ips read from proxy ip header, default to 0 (means infinity)
45
46
  *
46
47
  */
47
48
 
@@ -50,12 +51,16 @@ module.exports = class Application extends Emitter {
50
51
  options = options || {};
51
52
  this.proxy = options.proxy || false;
52
53
  this.subdomainOffset = options.subdomainOffset || 2;
54
+ this.proxyIpHeader = options.proxyIpHeader || 'X-Forwarded-For';
55
+ this.maxIpsCount = options.maxIpsCount || 0;
53
56
  this.env = options.env || process.env.NODE_ENV || 'development';
54
57
  if (options.keys) this.keys = options.keys;
55
58
  this.middleware = [];
56
59
  this.context = Object.create(context);
57
60
  this.request = Object.create(request);
58
61
  this.response = Object.create(response);
62
+ // util.inspect.custom support for node 6+
63
+ /* istanbul ignore else */
59
64
  if (util.inspect.custom) {
60
65
  this[util.inspect.custom] = this.inspect;
61
66
  }
@@ -192,15 +197,19 @@ module.exports = class Application extends Emitter {
192
197
  */
193
198
 
194
199
  onerror(err) {
195
- if (!(err instanceof Error)) throw new TypeError(util.format('non-error thrown: %j', err));
196
-
197
- if (404 == err.status || err.expose) return;
200
+ // When dealing with cross-globals a normal `instanceof` check doesn't work properly.
201
+ // See https://github.com/koajs/koa/issues/1466
202
+ // We can probably remove it once jest fixes https://github.com/facebook/jest/issues/2549.
203
+ const isNativeError =
204
+ Object.prototype.toString.call(err) === '[object Error]' ||
205
+ err instanceof Error;
206
+ if (!isNativeError) throw new TypeError(util.format('non-error thrown: %j', err));
207
+
208
+ if (404 === err.status || err.expose) return;
198
209
  if (this.silent) return;
199
210
 
200
211
  const msg = err.stack || err.toString();
201
- console.error();
202
- console.error(msg.replace(/^/gm, ' '));
203
- console.error();
212
+ console.error(`\n${msg.replace(/^/gm, ' ')}\n`);
204
213
  }
205
214
  };
206
215
 
@@ -225,15 +234,21 @@ function respond(ctx) {
225
234
  return res.end();
226
235
  }
227
236
 
228
- if ('HEAD' == ctx.method) {
229
- if (!res.headersSent && isJSON(body)) {
230
- ctx.length = Buffer.byteLength(JSON.stringify(body));
237
+ if ('HEAD' === ctx.method) {
238
+ if (!res.headersSent && !ctx.response.has('Content-Length')) {
239
+ const { length } = ctx.response;
240
+ if (Number.isInteger(length)) ctx.length = length;
231
241
  }
232
242
  return res.end();
233
243
  }
234
244
 
235
245
  // status body
236
246
  if (null == body) {
247
+ if (ctx.response._explicitNullBody) {
248
+ ctx.response.remove('Content-Type');
249
+ ctx.response.remove('Transfer-Encoding');
250
+ return res.end();
251
+ }
237
252
  if (ctx.req.httpVersionMajor >= 2) {
238
253
  body = String(code);
239
254
  } else {
@@ -248,7 +263,7 @@ function respond(ctx) {
248
263
 
249
264
  // responses
250
265
  if (Buffer.isBuffer(body)) return res.end(body);
251
- if ('string' == typeof body) return res.end(body);
266
+ if ('string' === typeof body) return res.end(body);
252
267
  if (body instanceof Stream) return body.pipe(res);
253
268
 
254
269
  // body: json
package/lib/context.js CHANGED
@@ -110,7 +110,13 @@ const proto = module.exports = {
110
110
  // to node-style callbacks.
111
111
  if (null == err) return;
112
112
 
113
- if (!(err instanceof Error)) err = new Error(util.format('non-error thrown: %j', err));
113
+ // When dealing with cross-globals a normal `instanceof` check doesn't work properly.
114
+ // See https://github.com/koajs/koa/issues/1466
115
+ // We can probably remove it once jest fixes https://github.com/facebook/jest/issues/2549.
116
+ const isNativeError =
117
+ Object.prototype.toString.call(err) === '[object Error]' ||
118
+ err instanceof Error;
119
+ if (!isNativeError) err = new Error(util.format('non-error thrown: %j', err));
114
120
 
115
121
  let headerSent = false;
116
122
  if (this.headerSent || !this.writable) {
@@ -143,16 +149,18 @@ const proto = module.exports = {
143
149
  // force text/plain
144
150
  this.type = 'text';
145
151
 
152
+ let statusCode = err.status || err.statusCode;
153
+
146
154
  // ENOENT support
147
- if ('ENOENT' == err.code) err.status = 404;
155
+ if ('ENOENT' === err.code) statusCode = 404;
148
156
 
149
157
  // default to 500
150
- if ('number' != typeof err.status || !statuses[err.status]) err.status = 500;
158
+ if ('number' !== typeof statusCode || !statuses[statusCode]) statusCode = 500;
151
159
 
152
160
  // respond
153
- const code = statuses[err.status];
161
+ const code = statuses[statusCode];
154
162
  const msg = err.expose ? err.message : code;
155
- this.status = err.status;
163
+ this.status = err.status = statusCode;
156
164
  this.length = Buffer.byteLength(msg);
157
165
  res.end(msg);
158
166
  },
@@ -193,6 +201,7 @@ delegate(proto, 'response')
193
201
  .method('redirect')
194
202
  .method('remove')
195
203
  .method('vary')
204
+ .method('has')
196
205
  .method('set')
197
206
  .method('append')
198
207
  .method('flushHeaders')
package/lib/request.js CHANGED
@@ -272,7 +272,7 @@ module.exports = {
272
272
  get hostname() {
273
273
  const host = this.host;
274
274
  if (!host) return '';
275
- if ('[' == host[0]) return this.URL.hostname || ''; // IPv6
275
+ if ('[' === host[0]) return this.URL.hostname || ''; // IPv6
276
276
  return host.split(':', 1)[0];
277
277
  },
278
278
 
@@ -311,10 +311,10 @@ module.exports = {
311
311
  const s = this.ctx.status;
312
312
 
313
313
  // GET or HEAD for weak freshness validation only
314
- if ('GET' != method && 'HEAD' != method) return false;
314
+ if ('GET' !== method && 'HEAD' !== method) return false;
315
315
 
316
316
  // 2xx or 304 as per rfc2616 14.26
317
- if ((s >= 200 && s < 300) || 304 == s) {
317
+ if ((s >= 200 && s < 300) || 304 === s) {
318
318
  return fresh(this.header, this.response.header);
319
319
  }
320
320
 
@@ -382,7 +382,7 @@ module.exports = {
382
382
 
383
383
  get length() {
384
384
  const len = this.get('Content-Length');
385
- if (len == '') return;
385
+ if (len === '') return;
386
386
  return ~~len;
387
387
  },
388
388
 
@@ -415,7 +415,7 @@ module.exports = {
415
415
  */
416
416
 
417
417
  get secure() {
418
- return 'https' == this.protocol;
418
+ return 'https' === this.protocol;
419
419
  },
420
420
 
421
421
  /**
@@ -432,10 +432,14 @@ module.exports = {
432
432
 
433
433
  get ips() {
434
434
  const proxy = this.app.proxy;
435
- const val = this.get('X-Forwarded-For');
436
- return proxy && val
435
+ const val = this.get(this.app.proxyIpHeader);
436
+ let ips = proxy && val
437
437
  ? val.split(/\s*,\s*/)
438
438
  : [];
439
+ if (this.app.maxIpsCount > 0) {
440
+ ips = ips.slice(-this.app.maxIpsCount);
441
+ }
442
+ return ips;
439
443
  },
440
444
 
441
445
  /**
@@ -622,15 +626,14 @@ module.exports = {
622
626
  *
623
627
  * this.is('html'); // => false
624
628
  *
625
- * @param {String|Array} types...
629
+ * @param {String|String[]} [type]
630
+ * @param {String[]} [types]
626
631
  * @return {String|false|null}
627
632
  * @api public
628
633
  */
629
634
 
630
- is(types) {
631
- if (!types) return typeis(this.req);
632
- if (!Array.isArray(types)) types = [].slice.call(arguments);
633
- return typeis(this.req, types);
635
+ is(type, ...types) {
636
+ return typeis(this.req, type, ...types);
634
637
  },
635
638
 
636
639
  /**
package/lib/response.js CHANGED
@@ -6,10 +6,8 @@
6
6
  */
7
7
 
8
8
  const contentDisposition = require('content-disposition');
9
- const ensureErrorHandler = require('error-inject');
10
9
  const getType = require('cache-content-type');
11
10
  const onFinish = require('on-finished');
12
- const isJSON = require('koa-is-json');
13
11
  const escape = require('escape-html');
14
12
  const typeis = require('type-is').is;
15
13
  const statuses = require('statuses');
@@ -20,6 +18,7 @@ const vary = require('vary');
20
18
  const only = require('only');
21
19
  const util = require('util');
22
20
  const encodeUrl = require('encodeurl');
21
+ const Stream = require('stream');
23
22
 
24
23
  /**
25
24
  * Prototype.
@@ -139,6 +138,7 @@ module.exports = {
139
138
  // no content
140
139
  if (null == val) {
141
140
  if (!statuses.empty[this.status]) this.status = 204;
141
+ if (val === null) this._explicitNullBody = true;
142
142
  this.remove('Content-Type');
143
143
  this.remove('Content-Length');
144
144
  this.remove('Transfer-Encoding');
@@ -149,10 +149,10 @@ module.exports = {
149
149
  if (!this._explicitStatus) this.status = 200;
150
150
 
151
151
  // set the content-type only if not yet set
152
- const setType = !this.header['content-type'];
152
+ const setType = !this.has('Content-Type');
153
153
 
154
154
  // string
155
- if ('string' == typeof val) {
155
+ if ('string' === typeof val) {
156
156
  if (setType) this.type = /^\s*</.test(val) ? 'html' : 'text';
157
157
  this.length = Buffer.byteLength(val);
158
158
  return;
@@ -166,12 +166,13 @@ module.exports = {
166
166
  }
167
167
 
168
168
  // stream
169
- if ('function' == typeof val.pipe) {
169
+ if (val instanceof Stream) {
170
170
  onFinish(this.res, destroy.bind(null, val));
171
- ensureErrorHandler(val, err => this.ctx.onerror(err));
172
-
173
- // overwriting
174
- if (null != original && original != val) this.remove('Content-Length');
171
+ if (original != val) {
172
+ val.once('error', err => this.ctx.onerror(err));
173
+ // overwriting
174
+ if (null != original) this.remove('Content-Length');
175
+ }
175
176
 
176
177
  if (setType) this.type = 'bin';
177
178
  return;
@@ -201,18 +202,15 @@ module.exports = {
201
202
  */
202
203
 
203
204
  get length() {
204
- const len = this.header['content-length'];
205
- const body = this.body;
206
-
207
- if (null == len) {
208
- if (!body) return;
209
- if ('string' == typeof body) return Buffer.byteLength(body);
210
- if (Buffer.isBuffer(body)) return body.length;
211
- if (isJSON(body)) return Buffer.byteLength(JSON.stringify(body));
212
- return;
205
+ if (this.has('Content-Length')) {
206
+ return parseInt(this.get('Content-Length'), 10) || 0;
213
207
  }
214
208
 
215
- return Math.trunc(len) || 0;
209
+ const { body } = this;
210
+ if (!body || body instanceof Stream) return undefined;
211
+ if ('string' === typeof body) return Buffer.byteLength(body);
212
+ if (Buffer.isBuffer(body)) return body.length;
213
+ return Buffer.byteLength(JSON.stringify(body));
216
214
  },
217
215
 
218
216
  /**
@@ -260,7 +258,7 @@ module.exports = {
260
258
 
261
259
  redirect(url, alt) {
262
260
  // location
263
- if ('back' == url) url = this.ctx.get('Referrer') || alt || '/';
261
+ if ('back' === url) url = this.ctx.get('Referrer') || alt || '/';
264
262
  this.set('Location', encodeUrl(url));
265
263
 
266
264
  // status
@@ -327,7 +325,7 @@ module.exports = {
327
325
  */
328
326
 
329
327
  set lastModified(val) {
330
- if ('string' == typeof val) val = new Date(val);
328
+ if ('string' === typeof val) val = new Date(val);
331
329
  this.set('Last-Modified', val.toUTCString());
332
330
  },
333
331
 
@@ -389,16 +387,14 @@ module.exports = {
389
387
  * Check whether the response is one of the listed types.
390
388
  * Pretty much the same as `this.request.is()`.
391
389
  *
392
- * @param {String|Array} types...
390
+ * @param {String|String[]} [type]
391
+ * @param {String[]} [types]
393
392
  * @return {String|false}
394
393
  * @api public
395
394
  */
396
395
 
397
- is(types) {
398
- const type = this.type;
399
- if (!types) return type || false;
400
- if (!Array.isArray(types)) types = [].slice.call(arguments);
401
- return typeis(type, types);
396
+ is(type, ...types) {
397
+ return typeis(this.type, type, ...types);
402
398
  },
403
399
 
404
400
  /**
@@ -421,6 +417,29 @@ module.exports = {
421
417
  return this.header[field.toLowerCase()] || '';
422
418
  },
423
419
 
420
+ /**
421
+ * Returns true if the header identified by name is currently set in the outgoing headers.
422
+ * The header name matching is case-insensitive.
423
+ *
424
+ * Examples:
425
+ *
426
+ * this.has('Content-Type');
427
+ * // => true
428
+ *
429
+ * this.get('content-type');
430
+ * // => true
431
+ *
432
+ * @param {String} field
433
+ * @return {boolean}
434
+ * @api public
435
+ */
436
+ has(field) {
437
+ return typeof this.res.hasHeader === 'function'
438
+ ? this.res.hasHeader(field)
439
+ // Node < 7.7
440
+ : field.toLowerCase() in this.headers;
441
+ },
442
+
424
443
  /**
425
444
  * Set header `field` to `val`, or pass
426
445
  * an object of header fields.
@@ -439,7 +458,7 @@ module.exports = {
439
458
  set(field, val) {
440
459
  if (this.headerSent) return;
441
460
 
442
- if (2 == arguments.length) {
461
+ if (2 === arguments.length) {
443
462
  if (Array.isArray(val)) val = val.map(v => typeof v === 'string' ? v : String(v));
444
463
  else if (typeof val !== 'string') val = String(val);
445
464
  this.res.setHeader(field, val);
@@ -502,7 +521,11 @@ module.exports = {
502
521
 
503
522
  get writable() {
504
523
  // can't write any more after response finished
505
- if (this.res.finished) return false;
524
+ // response.writableEnded is available since Node > 12.9
525
+ // https://nodejs.org/api/http.html#http_response_writableended
526
+ // response.finished is undocumented feature of previous Node versions
527
+ // https://stackoverflow.com/questions/16254385/undocumented-response-finished-in-node-js
528
+ if (this.res.writableEnded || this.res.finished) return false;
506
529
 
507
530
  const socket = this.res.socket;
508
531
  // There are already pending outgoing res, but still writable
@@ -549,11 +572,12 @@ module.exports = {
549
572
  };
550
573
 
551
574
  /**
552
- * Custom inspection implementation for newer Node.js versions.
575
+ * Custom inspection implementation for node 6+.
553
576
  *
554
577
  * @return {Object}
555
578
  * @api public
556
579
  */
580
+ /* istanbul ignore else */
557
581
  if (util.inspect.custom) {
558
582
  module.exports[util.inspect.custom] = module.exports.inspect;
559
583
  }
package/package.json CHANGED
@@ -1,14 +1,23 @@
1
1
  {
2
2
  "name": "koa",
3
- "version": "2.10.0",
3
+ "version": "2.13.0",
4
4
  "description": "Koa web app framework",
5
5
  "main": "lib/application.js",
6
+ "exports": {
7
+ ".": {
8
+ "require": "./lib/application.js",
9
+ "import": "./dist/koa.mjs"
10
+ },
11
+ "./": "./"
12
+ },
6
13
  "scripts": {
7
14
  "test": "egg-bin test test",
8
15
  "test-cov": "egg-bin cov test",
9
16
  "lint": "eslint benchmarks lib test",
10
17
  "bench": "make -C benchmarks",
11
- "authors": "git log --format='%aN <%aE>' | sort -u > AUTHORS"
18
+ "authors": "git log --format='%aN <%aE>' | sort -u > AUTHORS",
19
+ "build": "gen-esm-wrapper . ./dist/koa.mjs",
20
+ "prepare": "npm run build"
12
21
  },
13
22
  "repository": "koajs/koa",
14
23
  "keywords": [
@@ -32,7 +41,6 @@
32
41
  "depd": "^1.1.2",
33
42
  "destroy": "^1.0.4",
34
43
  "encodeurl": "^1.0.2",
35
- "error-inject": "^1.0.0",
36
44
  "escape-html": "^1.0.3",
37
45
  "fresh": "~0.5.2",
38
46
  "http-assert": "^1.3.0",
@@ -40,7 +48,6 @@
40
48
  "is-generator-function": "^1.0.7",
41
49
  "koa-compose": "^4.1.0",
42
50
  "koa-convert": "^1.2.0",
43
- "koa-is-json": "^1.0.0",
44
51
  "on-finished": "^2.3.0",
45
52
  "only": "~0.0.2",
46
53
  "parseurl": "^1.3.2",
@@ -50,11 +57,14 @@
50
57
  },
51
58
  "devDependencies": {
52
59
  "egg-bin": "^4.13.0",
53
- "eslint": "^6.0.1",
60
+ "eslint": "^6.5.1",
54
61
  "eslint-config-koa": "^2.0.0",
55
- "eslint-config-standard": "^7.0.1",
56
- "eslint-plugin-promise": "^3.5.0",
57
- "eslint-plugin-standard": "^2.1.1",
62
+ "eslint-config-standard": "^14.1.0",
63
+ "eslint-plugin-import": "^2.18.2",
64
+ "eslint-plugin-node": "^10.0.0",
65
+ "eslint-plugin-promise": "^4.2.1",
66
+ "eslint-plugin-standard": "^4.0.1",
67
+ "gen-esm-wrapper": "^1.0.6",
58
68
  "mm": "^2.5.0",
59
69
  "supertest": "^3.1.0"
60
70
  },
@@ -62,6 +72,7 @@
62
72
  "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4"
63
73
  },
64
74
  "files": [
75
+ "dist",
65
76
  "lib"
66
77
  ]
67
78
  }