From 290ca57bf8e823f0baae0f3886cb1d5766cd3fb7 Mon Sep 17 00:00:00 2001 From: Imed Jaberi Date: Thu, 10 Sep 2020 18:43:27 +0100 Subject: [PATCH] update: ready to next release (#13) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update .gitignore file ๐Ÿž .. * rm -rf test file โŒ .. * setup coverage --nyc ๐Ÿ—ฝ .. * update ci pipeline ๐ŸŽฒ .. * improve the src --better โœจ .. * update test code --improve --coverge --100 ๐Ÿงช.. * update README.md ๐Ÿ“‹ .. * better pkg.json ๐ŸŽ— .. * update LICENSE ๐Ÿ— .. * update README.md ๐Ÿ“‹ .. --- .gitignore | 19 ++++++++++ .nycrc | 15 ++++++++ .travis.yml | 8 +++-- LICENSE | 2 +- README.md | 43 ++++++++++++++++++----- index.js | 71 ++++++++++++++++++++++++++++++------- test.js => index.spec.js | 75 +++++++++++++++++++++++++++------------- package.json | 64 ++++++++++++++++++++++++---------- 8 files changed, 228 insertions(+), 69 deletions(-) create mode 100644 .nycrc rename test.js => index.spec.js (79%) diff --git a/.gitignore b/.gitignore index 3c3629e..b2416d3 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,20 @@ + +# OS # +################### +.DS_Store +.idea +Thumbs.db +tmp +temp + + +# Node.js # +################### node_modules +package-lock.json + + +# NYC # +################### +coverage +.nyc_output diff --git a/.nycrc b/.nycrc new file mode 100644 index 0000000..f5320a0 --- /dev/null +++ b/.nycrc @@ -0,0 +1,15 @@ +{ + "extension": [ + ".js" + ], + "exclude": [ + "index.spec.js" + ], + "reporter": [ + "text-lcov", + "text", + "lcov" + ], + "report-dir": "./coverage", + "temp-dir": "./.nyc_output" +} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 82b24ee..cbdf0ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ language: node_js node_js: - - "4" - - "5" -script: "npm run test" + - 10 + - 12 + - 14 +script: + - npm run ci diff --git a/LICENSE b/LICENSE index 03d4071..b26678b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ The MIT License (MIT) Copyright (c) 2015 yunsong +Copyright (c) 2020 Koa.js contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -19,4 +20,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/README.md b/README.md index 388eaf8..d4474c3 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,34 @@ - # koa-convert -[![npm version](https://img.shields.io/npm/v/koa-convert.svg)](https://npmjs.org/package/koa-convert) -[![build status](https://travis-ci.org/koajs/convert.svg)](https://travis-ci.org/koajs/convert) +[![Build Status][travis-img]][travis-url] +[![NPM version][npm-badge]][npm-url] +[![License][license-badge]][license-url] +![Code Size][code-size-badge] + + + + + +[travis-img]: https://travis-ci.org/koajs/convert.svg?branch=master +[travis-url]: https://travis-ci.org/koajs/convert -Convert koa legacy ( 0.x & 1.x ) generator middleware to modern promise middleware ( 2.x ). + -It could also convert modern promise middleware back to legacy generator middleware ( useful to help modern middleware support koa 0.x or 1.x ). +[npm-badge]: https://img.shields.io/npm/v/koa-better-request-id.svg?style=flat +[npm-url]: https://www.npmjs.com/package/koa-better-request-id +[license-badge]: https://img.shields.io/badge/license-MIT-green.svg?style=flat-square +[license-url]: https://github.com/koajs/koa-convert/blob/master/LICENSE +[code-size-badge]: https://img.shields.io/github/languages/code-size/koajs/koa-convert + + + +Convert Koa legacy (0.x & 1.x) generator middleware to modern promise middleware (2.x). + +It could also convert modern promise middleware back to legacy generator middleware (useful to help modern middleware support Koa v0.x or v1.x). ## Note @@ -21,8 +43,11 @@ You may use following packages for [routing](https://github.com/koajs/koa/wiki#r ## Installation -``` -$ npm install koa-convert +```bash +# npm .. +$ npm i koa-convert +# yarn .. +$ yarn add koa-convert ``` ## Usage @@ -54,7 +79,7 @@ function modernMiddleware (ctx, next) { ## Distinguish legacy and modern middleware -In koa 0.x and 1.x ( without experimental flag ), `app.use` has an assertion that all ( legacy ) middleware must be generator function and it's tested with `fn.constructor.name == 'GeneratorFunction'` at [here](https://github.com/koajs/koa/blob/7fe29d92f1e826d9ce36029e1b9263b94cba8a7c/lib/application.js#L105). +In koa 0.x and 1.x (without experimental flag), `app.use` has an assertion that all (legacy) middleware must be generator function and it's tested with `fn.constructor.name == 'GeneratorFunction'` at [here](https://github.com/koajs/koa/blob/7fe29d92f1e826d9ce36029e1b9263b94cba8a7c/lib/application.js#L105). Therefore, we can distinguish legacy and modern middleware with `fn.constructor.name == 'GeneratorFunction'`. @@ -138,4 +163,4 @@ legacyMiddleware = convert.back(modernMiddleware) ## License -MIT +[MIT](LICENSE) diff --git a/index.js b/index.js index 5fff6b5..13afd74 100644 --- a/index.js +++ b/index.js @@ -1,28 +1,60 @@ 'use strict' +/** + * Module dependencies. + */ + const co = require('co') const compose = require('koa-compose') +/** + * Expose `convert()`. + */ + module.exports = convert +/** + * Convert Koa legacy generator-based middleware + * to modern promise-based middleware. + * + * + * @api public + * */ + function convert (mw) { if (typeof mw !== 'function') { throw new TypeError('middleware must be a function') } - if (mw.constructor.name !== 'GeneratorFunction') { - // assume it's Promise-based middleware + + // assume it's Promise-based middleware + if ( + mw.constructor.name !== 'GeneratorFunction' && + mw.constructor.name !== 'AsyncGeneratorFunction' + ) { return mw } + const converted = function (ctx, next) { - return co.call(ctx, mw.call(ctx, createGenerator(next))) + return co.call( + ctx, + mw.call( + ctx, + (function * (next) { return yield next() })(next) + )) } + converted._name = mw._name || mw.name return converted } -function * createGenerator (next) { - return yield next() -} +/** + * Convert and compose multiple middleware + * (could mix legacy and modern ones) + * and return modern promise middleware. + * + * + * @api public + * */ // convert.compose(mw, mw, mw) // convert.compose([mw, mw, mw]) @@ -30,31 +62,44 @@ convert.compose = function (arr) { if (!Array.isArray(arr)) { arr = Array.from(arguments) } + return compose(arr.map(convert)) } +/** + * Convert Koa modern promise-based middleware + * to legacy generator-based middleware. + * + * + * @api public + * */ + convert.back = function (mw) { if (typeof mw !== 'function') { throw new TypeError('middleware must be a function') } - if (mw.constructor.name === 'GeneratorFunction') { - // assume it's generator middleware + + // assume it's generator middleware + if (mw.constructor.name === 'GeneratorFunction' || mw.constructor.name === 'AsyncGeneratorFunction') { return mw } + const converted = function * (next) { - let ctx = this + const ctx = this let called = false - // no need try...catch here, it's ok even `mw()` throw exception - yield Promise.resolve(mw(ctx, function () { + + yield mw(ctx, function () { if (called) { // guard against multiple next() calls // https://github.com/koajs/compose/blob/4e3e96baf58b817d71bd44a8c0d78bb42623aa95/index.js#L36 - return Promise.reject(new Error('next() called multiple times')) + throw new Error('next() called multiple times') } + called = true return co.call(ctx, next) - })) + }) } + converted._name = mw._name || mw.name return converted } diff --git a/test.js b/index.spec.js similarity index 79% rename from test.js rename to index.spec.js index 9c1f11c..a22982f 100644 --- a/test.js +++ b/index.spec.js @@ -11,9 +11,9 @@ const request = require('supertest') describe('convert()', () => { it('should work', () => { - let call = [] - let ctx = {} - let mw = convert(function * (next) { + const call = [] + const ctx = {} + const mw = convert(function * (next) { assert.ok(ctx === this) call.push(1) }) @@ -26,14 +26,14 @@ describe('convert()', () => { }) it('should inherit the original middleware name', () => { - let mw = convert(function * testing (next) {}) + const mw = convert(function * testing (next) {}) assert.strictEqual(mw._name, 'testing') }) it('should work with `yield next`', () => { - let call = [] - let ctx = {} - let mw = convert(function * (next) { + const call = [] + const ctx = {} + const mw = convert(function * (next) { assert.ok(ctx === this) call.push(1) yield next @@ -49,12 +49,12 @@ describe('convert()', () => { }) it('should work with `yield* next`', () => { - let call = [] - let ctx = {} - let mw = convert(function * (next) { + const call = [] + const ctx = {} + const mw = convert(function * (next) { assert.ok(ctx === this) call.push(1) - yield* next + yield * next call.push(3) }) @@ -65,14 +65,18 @@ describe('convert()', () => { assert.deepEqual(call, [1, 2, 3]) }) }) + + it('should throw', () => { + assert.throws(() => convert('foo')) + }) }) describe('convert.compose()', () => { it('should work', () => { - let call = [] - let context = {} + const call = [] + const context = {} let _context - let mw = convert.compose([ + const mw = convert.compose([ function * name (next) { call.push(1) yield next @@ -86,7 +90,7 @@ describe('convert.compose()', () => { }, function * (next) { call.push(3) - yield* next + yield * next call.push(9) }, co.wrap(function * (ctx, next) { @@ -116,10 +120,10 @@ describe('convert.compose()', () => { }) it('should work too', () => { - let call = [] - let context = {} + const call = [] + const context = {} let _context - let mw = convert.compose( + const mw = convert.compose( (ctx, next) => { call.push(1) return next().catch(() => { @@ -133,7 +137,7 @@ describe('convert.compose()', () => { }, function * (next) { call.push(3) - yield* next + yield * next call.push(-1) // should not call this }, (ctx, next) => { @@ -151,7 +155,7 @@ describe('convert.compose()', () => { describe('convert.back()', () => { it('should work with koa 1', done => { - let app = new KoaV1() + const app = new KoaV1() app.use(function * (next) { this.body = [1] @@ -178,8 +182,27 @@ describe('convert.back()', () => { .end(done) }) + it('should work too', (done) => { + const app = new KoaV1() + + app.use(function * (next) { + this.body = [1] + yield next + this.body.push(3) + }) + + app.use(convert.back(function * (next) { + this.body.push(2) + })) + + request(app.callback()) + .get('/') + .expect(200, [1, 2, 3]) + .end(done) + }) + it('should guard multiple calls', done => { - let app = new KoaV1() + const app = new KoaV1() app.use(function * (next) { try { @@ -203,13 +226,17 @@ describe('convert.back()', () => { }) it('should inherit the original middleware name', () => { - let mw = convert.back(function testing (ctx, next) {}) + const mw = convert.back(function testing (ctx, next) {}) assert.strictEqual(mw._name, 'testing') }) + + it('should throw with koa 1', () => { + assert.throws(() => convert.back('foo')) + }) }) describe('migration snippet', () => { - let app = new Koa() + const app = new Koa() // snippet const _use = app.use @@ -231,7 +258,7 @@ describe('migration snippet', () => { app.use(function * (next) { this.body.push(3) - yield* next + yield * next this.body.push(7) }) diff --git a/package.json b/package.json index d741ce5..bce6fa6 100644 --- a/package.json +++ b/package.json @@ -1,38 +1,64 @@ { "name": "koa-convert", "version": "1.2.0", - "keywords": [ - "koa", - "middleware", - "convert" + "description": "convert modern Koa legacy generator-based middleware to promise-based middleware", + "main": "index.js", + "files": [ + "index.js" ], - "description": "convert koa legacy generator-based middleware to promise-based middleware", "repository": { "type": "git", "url": "git+https://github.com/gyson/koa-convert.git" }, - "main": "index.js", + "standard": { + "ignore": [ + "index.spec.js" + ] + }, "scripts": { - "test": "standard && mocha test.js" + "lint": "standard", + "pretest": "npm run lint", + "test": "mocha index.spec.js --exit", + "precoverage": "rimraf .nyc_output coverage", + "coverage": "nyc npm run test", + "ci": "npm run coverage" }, + "keywords": [ + "koa", + "middleware", + "convert", + "back", + "generator", + "promise", + "generator-based-middleware", + "promise-based-middleware", + "support" + ], "author": "gyson ", + "contributors": [ + "gyson ", + "Lloyd Brookes <75pound@gmail.com>", + "Imed Jaberi (https://www.3imed-jaberi.com)" + ], "license": "MIT", - "bugs": { - "url": "https://github.com/gyson/koa-convert/issues" - }, - "homepage": "https://github.com/gyson/koa-convert#readme", "dependencies": { "co": "^4.6.0", - "koa-compose": "^3.0.0" + "koa-compose": "^4.1.0" }, "devDependencies": { - "koa": "^2.0.0-alpha.2", - "koa-v1": "^1.0.0", - "mocha": "^2.3.3", - "standard": "^5.3.1", - "supertest": "^1.1.0" + "koa": "^2.13.0", + "koa-v1": "npm:koa@1.7.0", + "mocha": "^7.1.1", + "nyc": "^15.1.0", + "rimraf": "^3.0.2", + "standard": "^14.3.4", + "supertest": "^4.0.2" }, "engines": { - "node": ">= 4" - } + "node": ">= 10" + }, + "bugs": { + "url": "https://github.com/gyson/koa-convert/issues" + }, + "homepage": "https://github.com/gyson/koa-convert#readme" }