From 0ac4ff00c678320ddd1e8a9c4a81b2257de78fc4 Mon Sep 17 00:00:00 2001 From: Martin Iwanowski Date: Mon, 14 Mar 2016 15:51:14 +0100 Subject: [PATCH] Convert generator-mw with deprecation warning --- Readme.md | 20 ++++++++++++-- lib/application.js | 11 +++++++- package.json | 2 ++ test/application/use.js | 61 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 87 insertions(+), 7 deletions(-) diff --git a/Readme.md b/Readme.md index bff3a66..0a6b382 100644 --- a/Readme.md +++ b/Readme.md @@ -88,9 +88,24 @@ app.use(co.wrap(function *(ctx, next) { })); ``` -### Old signature middleware (v1.x) +### Old signature middleware (v1.x) - Deprecated -If you want to use old signature or be compatible with old middleware, you must use [koa-convert](https://github.com/gyson/koa-convert) to convert legacy generator middleware to promise middleware. +**Old signature middleware (v1.x) support will be removed in v3** + +Koa v2.x will try to convert legacy signature, generator middleware on `app.use`, using [koa-convert](https://github.com/koajs/convert). +It is however recommended that you choose to migrate all v1.x middleware as soon as possible. + +```js +// Koa will convert +app.use(function *(next) { + const start = new Date(); + yield next; + const ms = new Date() - start; + console.log(`${this.method} ${this.url} - ${ms}ms`); +}); +``` + +You could do it manually as well, in which case Koa will not convert. ```js const convert = require('koa-convert'); @@ -103,7 +118,6 @@ app.use(convert(function *(next) { })); ``` - ## Babel setup For Node 4.0 and Babel 6.0 you can setup like this diff --git a/lib/application.js b/lib/application.js index 24ca17b..83b607f 100644 --- a/lib/application.js +++ b/lib/application.js @@ -21,6 +21,8 @@ const assert = require('assert'); const Stream = require('stream'); const http = require('http'); const only = require('only'); +const convert = require('koa-convert'); +const deprecate = require('depd')('koa'); /** * Expose `Application` class. @@ -93,6 +95,8 @@ module.exports = class Application extends Emitter { /** * Use the given middleware `fn`. * + * Old-style middleware will be converted. + * * @param {Function} fn * @return {Application} self * @api public @@ -100,7 +104,12 @@ module.exports = class Application extends Emitter { use(fn) { if (typeof fn !== 'function') throw new TypeError('middleware must be a function!'); - if (isGeneratorFunction(fn)) throw new TypeError('Support for generators has been removed. See the documentation for examples of how to convert old middleware https://github.com/koajs/koa/tree/v2.x#old-signature-middleware-v1x'); + if (isGeneratorFunction(fn)) { + deprecate('Support for generators will been removed in v3. ' + + 'See the documentation for examples of how to convert old middleware ' + + 'https://github.com/koajs/koa/tree/v2.x#old-signature-middleware-v1x'); + fn = convert(fn); + } debug('use %s', fn._name || fn.name || '-'); this.middleware.push(fn); return this; diff --git a/package.json b/package.json index eb48eb8..6cc5d34 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "cookies": "~0.6.1", "debug": "*", "delegates": "^1.0.0", + "depd": "^1.1.0", "destroy": "^1.0.3", "error-inject": "~1.0.0", "escape-html": "~1.0.1", @@ -32,6 +33,7 @@ "http-errors": "^1.2.8", "is-generator-function": "^1.0.3", "koa-compose": "^3.0.0", + "koa-convert": "^1.2.0", "koa-is-json": "^1.0.0", "mime-types": "^2.0.7", "on-finished": "^2.1.0", diff --git a/test/application/use.js b/test/application/use.js index 18229f8..268d785 100644 --- a/test/application/use.js +++ b/test/application/use.js @@ -2,6 +2,7 @@ 'use strict'; const request = require('supertest'); +const assert = require('assert'); const Koa = require('../..'); describe('app.use(fn)', () => { @@ -42,6 +43,43 @@ describe('app.use(fn)', () => { }); }); + it('should compose mixed middleware', done => { + process.once('deprecation', () => {}); // silence deprecation message + const app = new Koa(); + const calls = []; + + app.use((ctx, next) => { + calls.push(1); + return next().then(() => { + calls.push(6); + }); + }); + + app.use(function *(next){ + calls.push(2); + yield next; + calls.push(5); + }); + + app.use((ctx, next) => { + calls.push(3); + return next().then(() => { + calls.push(4); + }); + }); + + const server = app.listen(); + + request(server) + .get('/') + .expect(404) + .end(err => { + if (err) return done(err); + calls.should.eql([1, 2, 3, 4, 5, 6]); + done(); + }); + }); + // https://github.com/koajs/koa/pull/530#issuecomment-148138051 it('should catch thrown errors in non-async functions', done => { const app = new Koa(); @@ -54,16 +92,33 @@ describe('app.use(fn)', () => { .end(done); }); + it('should accept both generator and function middleware', done => { + process.once('deprecation', () => {}); // silence deprecation message + const app = new Koa(); + + app.use((ctx, next) => { return next(); }); + app.use(function *(next){ this.body = 'generator'; }); + + request(app.listen()) + .get('/') + .expect(200) + .expect('generator', done); + }); + it('should throw error for non function', () => { const app = new Koa(); [null, undefined, 0, false, 'not a function'].forEach(v => (() => app.use(v)).should.throw('middleware must be a function!')); }); - it('should throw error for generator', () => { - const app = new Koa(); + it('should output deprecation message for generator functions', done => { + process.once('deprecation', message => { + assert(/Support for generators will been removed/.test(message)); + done(); + }); - (() => app.use(function *(){})).should.throw(/.+/); + const app = new Koa(); + app.use(function *(){}); }); it('should throw error for non function', () => {