From 69f3cbc987fce9373f0f8e97d0ae3daba9d8a89f Mon Sep 17 00:00:00 2001 From: Jan Zaloudek Date: Tue, 8 Oct 2019 16:23:21 +0200 Subject: [PATCH 1/5] chore(deps): bump joi version BREAKING CHANGE: joi 16.x.x contains breaking changes (https://github.com/hapijs/joi/issues/2037) --- joi-router.js | 3 ++- output-validation-rule.js | 6 ++++-- package.json | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/joi-router.js b/joi-router.js index 0fc1bee..a7d205f 100644 --- a/joi-router.js +++ b/joi-router.js @@ -474,7 +474,8 @@ function validateInput(prop, ctx, validate) { debug('validating %s', prop); const request = ctx.request; - const res = Joi.validate(request[prop], validate[prop]); + const schema = Joi.compile(validate[prop]); + const res = schema.validate(request[prop]); if (res.error) { res.error.status = validate.failure; diff --git a/output-validation-rule.js b/output-validation-rule.js index 739a191..22a5139 100644 --- a/output-validation-rule.js +++ b/output-validation-rule.js @@ -70,14 +70,16 @@ OutputValidationRule.prototype.validateOutput = function validateOutput(ctx) { let result; if (this.spec.headers) { - result = Joi.validate(ctx.response.headers, this.spec.headers); + const schema = Joi.compile(this.spec.headers) + result = schema.validate(ctx.response.headers); if (result.error) return result.error; // use casted values ctx.set(result.value); } if (this.spec.body) { - result = Joi.validate(ctx.body, this.spec.body); + const schema = Joi.compile(this.spec.body) + result = schema.validate(ctx.body); if (result.error) return result.error; // use casted values ctx.body = result.value; diff --git a/package.json b/package.json index 5025210..177a6f5 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ }, "homepage": "https://github.com/koajs/joi-router", "dependencies": { - "@hapi/joi": "15.0.0", + "@hapi/joi": "^16.1.7", "await-busboy": "1.0.3", "clone": "2.1.2", "co-body": "6.0.0", From 9dd2144aa24d8c55699f57bbe616fcd5a194d7e4 Mon Sep 17 00:00:00 2001 From: Jan Zaloudek Date: Tue, 8 Oct 2019 16:23:40 +0200 Subject: [PATCH 2/5] 7.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 177a6f5..b92bb38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "koa-joi-router", - "version": "6.0.0", + "version": "7.0.0", "description": "Configurable, input validated routing for koa.", "main": "joi-router.js", "keywords": [ From 49b24a24c8509fcb5561f67ad47eb41b6fa1241d Mon Sep 17 00:00:00 2001 From: Jan Zaloudek Date: Tue, 8 Oct 2019 16:31:48 +0200 Subject: [PATCH 3/5] docs --- History.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/History.md b/History.md index 5665ad3..c734bda 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,7 @@ +7.0.0 / 2019-10-08 +================== + + * deps; [semver-major] bump @hapi/joi from 15.x -> 16.x 6.0.0 / 2019-04-27 ================== From becfc80c8f39446b18975ea891acc96e24e1d9b7 Mon Sep 17 00:00:00 2001 From: Jan Zaloudek Date: Thu, 10 Oct 2019 16:41:10 +0200 Subject: [PATCH 4/5] remove Joi dependency --- output-validation-rule.js | 11 +++++------ output-validator.js | 4 ++-- package.json | 12 ++++++------ joi-router.js => router.js | 29 +++++++++++++++++------------ test/index.js | 25 ++++++++++++++++--------- 5 files changed, 46 insertions(+), 35 deletions(-) rename joi-router.js => router.js (95%) diff --git a/output-validation-rule.js b/output-validation-rule.js index 22a5139..4e9a09f 100644 --- a/output-validation-rule.js +++ b/output-validation-rule.js @@ -1,7 +1,6 @@ 'use strict'; const assert = require('assert'); -const Joi = require('@hapi/joi'); const helpMsg = ' -> see: https://github.com/koajs/joi-router/#validating-output'; module.exports = OutputValidationRule; @@ -66,20 +65,20 @@ OutputValidationRule.prototype.matches = function matches(ctx) { * Validates this rule against the given `ctx`. */ -OutputValidationRule.prototype.validateOutput = function validateOutput(ctx) { +OutputValidationRule.prototype.validateOutput = function validateOutput(ctx, validatorBuilder) { let result; if (this.spec.headers) { - const schema = Joi.compile(this.spec.headers) - result = schema.validate(ctx.response.headers); + const validator = validatorBuilder(this.spec.headers) + result = validator(ctx.response.headers); if (result.error) return result.error; // use casted values ctx.set(result.value); } if (this.spec.body) { - const schema = Joi.compile(this.spec.body) - result = schema.validate(ctx.body); + const validator = validatorBuilder(this.spec.body) + result = validator(ctx.body); if (result.error) return result.error; // use casted values ctx.body = result.value; diff --git a/output-validator.js b/output-validator.js index 6e65620..a118bc3 100644 --- a/output-validator.js +++ b/output-validator.js @@ -39,13 +39,13 @@ function assertNoOverlappingStatusRules(rules) { } }; -OutputValidator.prototype.validate = function(ctx) { +OutputValidator.prototype.validate = function(ctx, validatorBuilder) { assert(ctx, 'missing request context!'); for (let i = 0; i < this.rules.length; ++i) { const rule = this.rules[i]; if (rule.matches(ctx)) { - return rule.validateOutput(ctx); + return rule.validateOutput(ctx, validatorBuilder); } } }; diff --git a/package.json b/package.json index b92bb38..8c2c5b4 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { - "name": "koa-joi-router", + "name": "koa-not-so-joi-router", "version": "7.0.0", "description": "Configurable, input validated routing for koa.", - "main": "joi-router.js", + "main": "router.js", "keywords": [ "joi", "koa", @@ -26,14 +26,13 @@ "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/koajs/joi-router.git" + "url": "https://github.com/janzal/not-so-joi-router.git" }, "bugs": { - "url": "https://github.com/koajs/joi-router/issues" + "url": "https://github.com/janzal/not-so-joi-router/issues" }, - "homepage": "https://github.com/koajs/joi-router", + "homepage": "https://github.com/janzal/not-so-joi-router", "dependencies": { - "@hapi/joi": "^16.1.7", "await-busboy": "1.0.3", "clone": "2.1.2", "co-body": "6.0.0", @@ -46,6 +45,7 @@ "sliced": "1.0.1" }, "devDependencies": { + "@hapi/joi": "^16.1.7", "eslint": "^5", "koa": "^2.1", "mocha": "^6.0.2", diff --git a/joi-router.js b/router.js similarity index 95% rename from joi-router.js rename to router.js index a7d205f..b4e65fa 100644 --- a/joi-router.js +++ b/router.js @@ -8,7 +8,6 @@ const methods = require('methods'); const KoaRouter = require('koa-router'); const busboy = require('await-busboy'); const parse = require('co-body'); -const Joi = require('@hapi/joi'); const slice = require('sliced'); const delegate = require('delegates'); const clone = require('clone'); @@ -16,16 +15,22 @@ const OutputValidator = require('./output-validator'); module.exports = Router; -// expose Joi for use in applications -Router.Joi = Joi; +function identity(obj) { + return obj; +} -function Router() { +function Router({ + validatorBuilder +} = { validatorBuilder: identity }) { if (!(this instanceof Router)) { - return new Router(); + return new Router({ + validatorBuilder + }); } this.routes = []; this.router = new KoaRouter(); + this.validatorBuilder = validatorBuilder } /** @@ -116,7 +121,7 @@ Router.prototype._addRoute = function addRoute(spec) { const bodyParser = makeBodyParser(spec); const specExposer = makeSpecExposer(spec); - const validator = makeValidator(spec); + const validator = makeValidator(spec, this.validatorBuilder); const preHandlers = spec.pre ? flatten(spec.pre) : []; const handlers = flatten(spec.handler); @@ -400,7 +405,7 @@ function captureError(ctx, type, err) { * @api private */ -function makeValidator(spec) { +function makeValidator(spec, validatorBuilder) { const props = 'header query params body'.split(' '); return async function validator(ctx, next) { @@ -412,7 +417,7 @@ function makeValidator(spec) { const prop = props[i]; if (spec.validate[prop]) { - err = validateInput(prop, ctx, spec.validate); + err = validateInput(prop, ctx, spec.validate, validatorBuilder); if (err) { captureError(ctx, prop, err); @@ -426,7 +431,7 @@ function makeValidator(spec) { if (spec.validate._outputValidator) { debug('validating output'); - err = spec.validate._outputValidator.validate(ctx); + err = spec.validate._outputValidator.validate(ctx, validatorBuilder); if (err) { err.status = 500; return ctx.throw(err); @@ -470,12 +475,12 @@ async function prepareRequest(ctx, next) { * @api private */ -function validateInput(prop, ctx, validate) { +function validateInput(prop, ctx, validate, validatorBuilder) { debug('validating %s', prop); const request = ctx.request; - const schema = Joi.compile(validate[prop]); - const res = schema.validate(request[prop]); + const validator = validatorBuilder(validate[prop]); + const res = validator(request[prop]); if (res.error) { res.error.status = validate.failure; diff --git a/test/index.js b/test/index.js index a4d3247..311bcaa 100644 --- a/test/index.js +++ b/test/index.js @@ -1,6 +1,6 @@ 'use strict'; -const router = require('../'); +const routerFactory = require('../'); const Koa = require('koa'); const assert = require('assert'); const request = require('supertest'); @@ -10,6 +10,19 @@ const methods = require('methods'); const slice = require('sliced'); const MiddlewareGenerator = require('./test-utils').MiddlewareGenerator; +function joiValidatorBuilder(schema) { + const validator = Joi.compile(schema); + return (obj) => { + return validator.validate(obj) + } +} + +const router = () => { + return routerFactory({ + validatorBuilder: joiValidatorBuilder + }) +} + function makeRouterApp(router) { const app = new Koa(); app.use(router.middleware()); @@ -20,7 +33,7 @@ function test(app) { return request(http.createServer(app.callback())); } -describe('koa-joi-router', () => { +describe('koa-not-so-joi-router', () => { it('exposes a function', (done) => { assert.equal('function', typeof router); done(); @@ -28,12 +41,7 @@ describe('koa-joi-router', () => { it('is a constructor', (done) => { const r = router(); - assert(r instanceof router); - done(); - }); - - it('exposes the Joi module', (done) => { - assert.equal(router.Joi, Joi); + assert(r instanceof routerFactory); done(); }); @@ -182,7 +190,6 @@ describe('koa-joi-router', () => { return next(); }, handler: (ctx) => { - console.log('ctx.request.body', ctx.request.body); ctx.body = ctx.request.body; } }); From ab84aa59618032438bb77693f12132dd3cb14dd9 Mon Sep 17 00:00:00 2001 From: Jan Zaloudek Date: Thu, 10 Oct 2019 16:41:19 +0200 Subject: [PATCH 5/5] 7.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8c2c5b4..f5d35a2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "koa-not-so-joi-router", - "version": "7.0.0", + "version": "7.1.0", "description": "Configurable, input validated routing for koa.", "main": "router.js", "keywords": [