Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Joi dependency #1

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -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
==================
Expand Down
9 changes: 5 additions & 4 deletions output-validation-rule.js
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -66,18 +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) {
result = Joi.validate(ctx.response.headers, this.spec.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) {
result = Joi.validate(ctx.body, this.spec.body);
const validator = validatorBuilder(this.spec.body)
result = validator(ctx.body);
if (result.error) return result.error;
// use casted values
ctx.body = result.value;
Expand Down
4 changes: 2 additions & 2 deletions output-validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
};
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "koa-joi-router",
"version": "6.0.0",
"name": "koa-not-so-joi-router",
"version": "7.1.0",
"description": "Configurable, input validated routing for koa.",
"main": "joi-router.js",
"main": "router.js",
"keywords": [
"joi",
"koa",
Expand All @@ -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": "15.0.0",
"await-busboy": "1.0.3",
"clone": "2.1.2",
"co-body": "6.0.0",
Expand All @@ -46,6 +45,7 @@
"sliced": "1.0.1"
},
"devDependencies": {
"@hapi/joi": "^16.1.7",
"eslint": "^5",
"koa": "^2.1",
"mocha": "^6.0.2",
Expand Down
28 changes: 17 additions & 11 deletions joi-router.js → router.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,29 @@ 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');
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
}

/**
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -470,11 +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 res = Joi.validate(request[prop], validate[prop]);
const validator = validatorBuilder(validate[prop]);
const res = validator(request[prop]);

if (res.error) {
res.error.status = validate.failure;
Expand Down
25 changes: 16 additions & 9 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const router = require('../');
const routerFactory = require('../');
const Koa = require('koa');
const assert = require('assert');
const request = require('supertest');
Expand All @@ -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());
Expand All @@ -20,20 +33,15 @@ 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();
});

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();
});

Expand Down Expand Up @@ -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;
}
});
Expand Down