From 795b2e3e870302a9a19de7f749b858bf9280e577 Mon Sep 17 00:00:00 2001 From: 3imed-jaberi Date: Wed, 15 Jul 2020 15:07:26 +0200 Subject: [PATCH 01/10] =?UTF-8?q?=20update=20.gitignore=20file=20?= =?UTF-8?q?=F0=9F=90=9E=20..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) 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 From ea86df9c3dbffa55102f83f7dc7bff92ec150a05 Mon Sep 17 00:00:00 2001 From: 3imed-jaberi Date: Wed, 15 Jul 2020 15:08:38 +0200 Subject: [PATCH 02/10] =?UTF-8?q?=20rm=20-rf=20test=20file=20=E2=9D=8C=20.?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test.js | 254 -------------------------------------------------------- 1 file changed, 254 deletions(-) delete mode 100644 test.js diff --git a/test.js b/test.js deleted file mode 100644 index 9c1f11c..0000000 --- a/test.js +++ /dev/null @@ -1,254 +0,0 @@ -/* global describe, it */ - -'use strict' - -const co = require('co') -const Koa = require('koa') -const KoaV1 = require('koa-v1') -const assert = require('assert') -const convert = require('./index') -const request = require('supertest') - -describe('convert()', () => { - it('should work', () => { - let call = [] - let ctx = {} - let mw = convert(function * (next) { - assert.ok(ctx === this) - call.push(1) - }) - - return mw(ctx, function () { - call.push(2) - }).then(function () { - assert.deepEqual(call, [1]) - }) - }) - - it('should inherit the original middleware name', () => { - let 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) { - assert.ok(ctx === this) - call.push(1) - yield next - call.push(3) - }) - - return mw(ctx, function () { - call.push(2) - return Promise.resolve() - }).then(function () { - assert.deepEqual(call, [1, 2, 3]) - }) - }) - - it('should work with `yield* next`', () => { - let call = [] - let ctx = {} - let mw = convert(function * (next) { - assert.ok(ctx === this) - call.push(1) - yield* next - call.push(3) - }) - - return mw(ctx, function () { - call.push(2) - return Promise.resolve() - }).then(function () { - assert.deepEqual(call, [1, 2, 3]) - }) - }) -}) - -describe('convert.compose()', () => { - it('should work', () => { - let call = [] - let context = {} - let _context - let mw = convert.compose([ - function * name (next) { - call.push(1) - yield next - call.push(11) - }, - (ctx, next) => { - call.push(2) - return next().then(() => { - call.push(10) - }) - }, - function * (next) { - call.push(3) - yield* next - call.push(9) - }, - co.wrap(function * (ctx, next) { - call.push(4) - yield next() - call.push(8) - }), - function * (next) { - try { - call.push(5) - yield next - } catch (e) { - call.push(7) - } - }, - (ctx, next) => { - _context = ctx - call.push(6) - throw new Error() - } - ]) - - return mw(context).then(() => { - assert.equal(context, _context) - assert.deepEqual(call, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) - }) - }) - - it('should work too', () => { - let call = [] - let context = {} - let _context - let mw = convert.compose( - (ctx, next) => { - call.push(1) - return next().catch(() => { - call.push(4) - }) - }, - function * (next) { - call.push(2) - yield next - call.push(-1) // should not call this - }, - function * (next) { - call.push(3) - yield* next - call.push(-1) // should not call this - }, - (ctx, next) => { - _context = ctx - return Promise.reject(new Error()) - } - ) - - return mw(context).then(() => { - assert.equal(context, _context) - assert.deepEqual(call, [1, 2, 3, 4]) - }) - }) -}) - -describe('convert.back()', () => { - it('should work with koa 1', done => { - let app = new KoaV1() - - app.use(function * (next) { - this.body = [1] - yield next - this.body.push(6) - }) - - app.use(convert.back((ctx, next) => { - ctx.body.push(2) - return next().then(() => { - ctx.body.push(5) - }) - })) - - app.use(convert.back(co.wrap(function * (ctx, next) { - ctx.body.push(3) - yield next() - ctx.body.push(4) - }))) - - request(app.callback()) - .get('/') - .expect(200, [1, 2, 3, 4, 5, 6]) - .end(done) - }) - - it('should guard multiple calls', done => { - let app = new KoaV1() - - app.use(function * (next) { - try { - this.body = [1] - yield next - } catch (e) { - this.body.push(e.message) - } - }) - - app.use(convert.back(co.wrap(function * (ctx, next) { - ctx.body.push(2) - yield next() - yield next() // this should throw new Error('next() called multiple times') - }))) - - request(app.callback()) - .get('/') - .expect(200, [1, 2, 'next() called multiple times']) - .end(done) - }) - - it('should inherit the original middleware name', () => { - let mw = convert.back(function testing (ctx, next) {}) - assert.strictEqual(mw._name, 'testing') - }) -}) - -describe('migration snippet', () => { - let app = new Koa() - - // snippet - const _use = app.use - app.use = x => _use.call(app, convert(x)) - // end - - app.use((ctx, next) => { - ctx.body = [1] - return next().then(() => { - ctx.body.push(9) - }) - }) - - app.use(function * (next) { - this.body.push(2) - yield next - this.body.push(8) - }) - - app.use(function * (next) { - this.body.push(3) - yield* next - this.body.push(7) - }) - - app.use(co.wrap(function * (ctx, next) { - ctx.body.push(4) - yield next() - ctx.body.push(6) - })) - - app.use(ctx => { - ctx.body.push(5) - }) - - it('should work', done => { - request(app.callback()) - .get('/') - .expect(200, [1, 2, 3, 4, 5, 6, 7, 8, 9]) - .end(done) - }) -}) From f9c484224fe49e8cac2d2c0fedb304bc50ace60d Mon Sep 17 00:00:00 2001 From: 3imed-jaberi Date: Wed, 15 Jul 2020 15:09:30 +0200 Subject: [PATCH 03/10] =?UTF-8?q?=20setup=20coverage=20--nyc=20?= =?UTF-8?q?=F0=9F=97=BD=20..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .nycrc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .nycrc 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 From e08dc523aff9463dcd3fdfa5c509dfa62cc812de Mon Sep 17 00:00:00 2001 From: 3imed-jaberi Date: Wed, 15 Jul 2020 15:09:58 +0200 Subject: [PATCH 04/10] =?UTF-8?q?=20update=20ci=20pipeline=20=F0=9F=8E=B2?= =?UTF-8?q?=20..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 From 4d937ec46fa458d62e0767911f34ab1bf619572b Mon Sep 17 00:00:00 2001 From: 3imed-jaberi Date: Wed, 15 Jul 2020 15:10:42 +0200 Subject: [PATCH 05/10] =?UTF-8?q?=20improve=20the=20src=20--better=20?= =?UTF-8?q?=E2=9C=A8=20..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.js | 71 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 13 deletions(-) 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 } From 7352cb788115827f03a1ad47506be52755e6e991 Mon Sep 17 00:00:00 2001 From: 3imed-jaberi Date: Wed, 15 Jul 2020 15:11:35 +0200 Subject: [PATCH 06/10] =?UTF-8?q?=20update=20test=20code=20--improve=20--c?= =?UTF-8?q?overge=20--100=20=F0=9F=A7=AA..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.spec.js | 281 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 index.spec.js diff --git a/index.spec.js b/index.spec.js new file mode 100644 index 0000000..a22982f --- /dev/null +++ b/index.spec.js @@ -0,0 +1,281 @@ +/* global describe, it */ + +'use strict' + +const co = require('co') +const Koa = require('koa') +const KoaV1 = require('koa-v1') +const assert = require('assert') +const convert = require('./index') +const request = require('supertest') + +describe('convert()', () => { + it('should work', () => { + const call = [] + const ctx = {} + const mw = convert(function * (next) { + assert.ok(ctx === this) + call.push(1) + }) + + return mw(ctx, function () { + call.push(2) + }).then(function () { + assert.deepEqual(call, [1]) + }) + }) + + it('should inherit the original middleware name', () => { + const mw = convert(function * testing (next) {}) + assert.strictEqual(mw._name, 'testing') + }) + + it('should work with `yield next`', () => { + const call = [] + const ctx = {} + const mw = convert(function * (next) { + assert.ok(ctx === this) + call.push(1) + yield next + call.push(3) + }) + + return mw(ctx, function () { + call.push(2) + return Promise.resolve() + }).then(function () { + assert.deepEqual(call, [1, 2, 3]) + }) + }) + + it('should work with `yield* next`', () => { + const call = [] + const ctx = {} + const mw = convert(function * (next) { + assert.ok(ctx === this) + call.push(1) + yield * next + call.push(3) + }) + + return mw(ctx, function () { + call.push(2) + return Promise.resolve() + }).then(function () { + assert.deepEqual(call, [1, 2, 3]) + }) + }) + + it('should throw', () => { + assert.throws(() => convert('foo')) + }) +}) + +describe('convert.compose()', () => { + it('should work', () => { + const call = [] + const context = {} + let _context + const mw = convert.compose([ + function * name (next) { + call.push(1) + yield next + call.push(11) + }, + (ctx, next) => { + call.push(2) + return next().then(() => { + call.push(10) + }) + }, + function * (next) { + call.push(3) + yield * next + call.push(9) + }, + co.wrap(function * (ctx, next) { + call.push(4) + yield next() + call.push(8) + }), + function * (next) { + try { + call.push(5) + yield next + } catch (e) { + call.push(7) + } + }, + (ctx, next) => { + _context = ctx + call.push(6) + throw new Error() + } + ]) + + return mw(context).then(() => { + assert.equal(context, _context) + assert.deepEqual(call, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) + }) + }) + + it('should work too', () => { + const call = [] + const context = {} + let _context + const mw = convert.compose( + (ctx, next) => { + call.push(1) + return next().catch(() => { + call.push(4) + }) + }, + function * (next) { + call.push(2) + yield next + call.push(-1) // should not call this + }, + function * (next) { + call.push(3) + yield * next + call.push(-1) // should not call this + }, + (ctx, next) => { + _context = ctx + return Promise.reject(new Error()) + } + ) + + return mw(context).then(() => { + assert.equal(context, _context) + assert.deepEqual(call, [1, 2, 3, 4]) + }) + }) +}) + +describe('convert.back()', () => { + it('should work with koa 1', done => { + const app = new KoaV1() + + app.use(function * (next) { + this.body = [1] + yield next + this.body.push(6) + }) + + app.use(convert.back((ctx, next) => { + ctx.body.push(2) + return next().then(() => { + ctx.body.push(5) + }) + })) + + app.use(convert.back(co.wrap(function * (ctx, next) { + ctx.body.push(3) + yield next() + ctx.body.push(4) + }))) + + request(app.callback()) + .get('/') + .expect(200, [1, 2, 3, 4, 5, 6]) + .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 => { + const app = new KoaV1() + + app.use(function * (next) { + try { + this.body = [1] + yield next + } catch (e) { + this.body.push(e.message) + } + }) + + app.use(convert.back(co.wrap(function * (ctx, next) { + ctx.body.push(2) + yield next() + yield next() // this should throw new Error('next() called multiple times') + }))) + + request(app.callback()) + .get('/') + .expect(200, [1, 2, 'next() called multiple times']) + .end(done) + }) + + it('should inherit the original middleware name', () => { + 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', () => { + const app = new Koa() + + // snippet + const _use = app.use + app.use = x => _use.call(app, convert(x)) + // end + + app.use((ctx, next) => { + ctx.body = [1] + return next().then(() => { + ctx.body.push(9) + }) + }) + + app.use(function * (next) { + this.body.push(2) + yield next + this.body.push(8) + }) + + app.use(function * (next) { + this.body.push(3) + yield * next + this.body.push(7) + }) + + app.use(co.wrap(function * (ctx, next) { + ctx.body.push(4) + yield next() + ctx.body.push(6) + })) + + app.use(ctx => { + ctx.body.push(5) + }) + + it('should work', done => { + request(app.callback()) + .get('/') + .expect(200, [1, 2, 3, 4, 5, 6, 7, 8, 9]) + .end(done) + }) +}) From dc982a1e28569f43f1f67c42d44aae33539305be Mon Sep 17 00:00:00 2001 From: 3imed-jaberi Date: Wed, 15 Jul 2020 15:12:00 +0200 Subject: [PATCH 07/10] =?UTF-8?q?=20update=20README.md=20=F0=9F=93=8B=20..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 388eaf8..5ee69af 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'`. From a1b73a0d0aa0b0f1facf34b6a12a7d6fb0888fd5 Mon Sep 17 00:00:00 2001 From: 3imed-jaberi Date: Wed, 15 Jul 2020 15:15:26 +0200 Subject: [PATCH 08/10] =?UTF-8?q?=20better=20pkg.json=20=F0=9F=8E=97=20..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 64 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 19 deletions(-) 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" } From f97875465835eabaa4c99d9525ff7a2573410640 Mon Sep 17 00:00:00 2001 From: Imed Jaberi Date: Thu, 10 Sep 2020 19:35:08 +0200 Subject: [PATCH 09/10] =?UTF-8?q?update=20LICENSE=20=F0=9F=97=9D=20..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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. - From 150599376eb270db564ae9deadbb2f818e2788ad Mon Sep 17 00:00:00 2001 From: Imed Jaberi Date: Thu, 10 Sep 2020 19:35:57 +0200 Subject: [PATCH 10/10] =?UTF-8?q?update=20README.md=20=F0=9F=93=8B=20..?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ee69af..d4474c3 100644 --- a/README.md +++ b/README.md @@ -163,4 +163,4 @@ legacyMiddleware = convert.back(modernMiddleware) ## License -MIT +[MIT](LICENSE)