Comparing version 0.7.0 to 0.7.1
@@ -28,8 +28,13 @@ /** | ||
var self = this; | ||
return Promise.try(function() { | ||
return self.controller.delete(query); | ||
}) | ||
return this.readListQuery(query, req, res) | ||
.bind(this) | ||
.then(function (queryFinal) { | ||
return Promise.try(function() { | ||
return self.controller.delete(queryFinal); | ||
}); | ||
}) | ||
.bind(this) | ||
.then(this.mkSuccessHandler(req, res, enums.CrudOps.DELETE)) | ||
.catch(this.mkErrorHandler(req, res, enums.CrudOps.DELETE)); | ||
}); |
@@ -35,3 +35,3 @@ /** | ||
var items; | ||
return this.getLimitAndCount(query, pp.skip, pp.limit) | ||
return this.getLimitAndCount(query, pp.skip, pp.limit, req, res) | ||
.spread(function(results, count) { | ||
@@ -160,14 +160,21 @@ items = results; | ||
* @param {number} limit how many records to fetch. | ||
* @param {Object} req The request Object. | ||
* @param {Object} res The response Object. | ||
* @return {Promise} A promise. | ||
*/ | ||
Pagination.prototype.getLimitAndCount = function(query, skip, limit) { | ||
Pagination.prototype.getLimitAndCount = function(query, skip, limit, req, res) { | ||
var self = this; | ||
return Promise.all([ | ||
Promise.try(function() { | ||
return self.controller.readLimit(query, skip, limit); | ||
}), | ||
Promise.try(function() { | ||
return self.controller.count(query); | ||
}), | ||
]); | ||
return this.readListQuery(query, req, res) | ||
.bind(this) | ||
.then(function (queryFinal) { | ||
return Promise.all([ | ||
Promise.try(function() { | ||
return self.controller.readLimit(queryFinal, skip, limit); | ||
}), | ||
Promise.try(function() { | ||
return self.controller.count(queryFinal); | ||
}), | ||
]); | ||
}); | ||
}; |
@@ -44,6 +44,9 @@ /** | ||
var self = this; | ||
return Promise.try(function() { | ||
return self.controller.read(query); | ||
}) | ||
return this.readListQuery(query, req, res) | ||
.bind(this) | ||
.then(function (queryFinal) { | ||
return Promise.try(function() { | ||
return self.controller.read(queryFinal); | ||
}); | ||
}) | ||
.then(this.mkSuccessHandler(req, res, enums.CrudOps.READ)) | ||
@@ -67,6 +70,9 @@ .catch(this.mkErrorHandler(req, res, enums.CrudOps.READ)); | ||
var self = this; | ||
return Promise.try(function() { | ||
return self.controller.readOne(query); | ||
}) | ||
return this.readOneQuery(query, req, res) | ||
.bind(this) | ||
.then(function (queryFinal) { | ||
return Promise.try(function() { | ||
return self.controller.readOne(queryFinal); | ||
}); | ||
}) | ||
.then(this.mkSuccessHandler(req, res, enums.CrudOps.READ_ONE)) | ||
@@ -73,0 +79,0 @@ .catch(this.mkErrorHandler(req, res, enums.CrudOps.READ_ONE)); |
@@ -39,7 +39,10 @@ /** | ||
var self = this; | ||
return Promise.try(function() { | ||
return self.controller.update(query, req.body); | ||
}) | ||
return this.updateQuery(query, req, res) | ||
.bind(this) | ||
.then(function (queryFinal) { | ||
var self = this; | ||
return Promise.try(function() { | ||
return self.controller.update(queryFinal, req.body); | ||
}); | ||
}) | ||
.then(this.controller.readOne.bind(null, query)) | ||
@@ -46,0 +49,0 @@ .then(this.mkSuccessHandler(req, res, enums.CrudOps.UPDATE)) |
@@ -11,2 +11,3 @@ /*jshint camelcase:false */ | ||
var appErr = require('nodeon-error'); | ||
var middlewarify = require('middlewarify'); | ||
@@ -63,11 +64,21 @@ var Create = require('./crud-ops/create'); | ||
// define CRUD handlers | ||
this.create = [this._create.bind(this)]; | ||
this.readOne = [this._readOne.bind(this)]; | ||
this.readList = [this._readList.bind(this)]; | ||
this.update = [this._update.bind(this)]; | ||
this.delete = [this._delete.bind(this)]; | ||
// define CRUD middleware | ||
this.create = []; | ||
this.readOne = []; | ||
this.readList = []; | ||
this.update = []; | ||
this.delete = []; | ||
// define CRUD Query middleware | ||
function noopReturn(query) {return query;} | ||
middlewarify.make(this, 'createQuery', noopReturn); | ||
middlewarify.make(this, 'readOneQuery', noopReturn); | ||
middlewarify.make(this, 'readListQuery', noopReturn); | ||
middlewarify.make(this, 'updateQuery', noopReturn); | ||
middlewarify.make(this, 'deleteQuery', noopReturn); | ||
var self = this; | ||
function use(middleware) { | ||
this.unshift(middleware); | ||
this.push(middleware); | ||
return self; | ||
} | ||
@@ -152,2 +163,17 @@ this.create.use = use; | ||
/** | ||
* Applies query middleware to all CRUD OPs. | ||
* | ||
* @param {Function} middleware The middleware to insert. | ||
* @return {self} Chainable. | ||
*/ | ||
Crude.prototype.useQuery = function(middleware) { | ||
this.readOneQuery.use(middleware); | ||
this.readListQuery.use(middleware); | ||
this.updateQuery.use(middleware); | ||
this.deleteQuery.use(middleware); | ||
return this; | ||
}; | ||
/** | ||
* The actual route add operation, decoupled from add to skip instanceof checks. | ||
@@ -161,8 +187,8 @@ * | ||
Crude.prototype.addRoutes = function(express) { | ||
express.get(this.baseUrl, this.readList); | ||
express.post(this.baseUrl, this.create); | ||
express.get(this.baseUrl + '/:id', this.readOne); | ||
express.put(this.baseUrl + '/:id', this.update); | ||
express.patch(this.baseUrl + '/:id', this.update); | ||
express.delete(this.baseUrl + '/:id', this.delete); | ||
express.get(this.baseUrl, [this.readList, this._readList.bind(this)]); | ||
express.post(this.baseUrl, [this.create, this._create.bind(this)]); | ||
express.get(this.baseUrl + '/:id', [this.readOne, this._readOne.bind(this)]); | ||
express.put(this.baseUrl + '/:id', [this.update, this._update.bind(this)]); | ||
express.patch(this.baseUrl + '/:id', [this.update, this._update.bind(this)]); | ||
express.delete(this.baseUrl + '/:id', [this.delete, this._delete.bind(this)]); | ||
@@ -169,0 +195,0 @@ this.express = express; |
{ | ||
"name": "crude", | ||
"description": "Creates CRUD RESTfull endpoints for a given route", | ||
"version": "0.7.0", | ||
"version": "0.7.1", | ||
"homepage": "https://github.com/thanpolas/crude", | ||
@@ -6,0 +6,0 @@ "author": { |
@@ -56,2 +56,5 @@ # Crude | ||
- **v0.7.1**, *16 Sep 2014* | ||
- Switched CRUD middleware to FIFO. | ||
- Added [Query Middleware](https://github.com/thanpolas/crude/wiki/Api#query-middleware) on all CRUD OPs. | ||
- **v0.7.0**, *14 Sep 2014* | ||
@@ -58,0 +61,0 @@ - Middleware are now of express type vs being Promises. |
@@ -17,49 +17,137 @@ /** | ||
this.reqres = tester.reqres(); | ||
this.query = {a: 1}; | ||
this.stub = sinon.stub(); | ||
this.stubTwo = sinon.stub(); | ||
this.stubThree = sinon.stub(); | ||
}); | ||
function runMiddleware(op) { | ||
op.forEach(function (midd) { | ||
midd(this.reqres.req, this.reqres.res); | ||
}, this); | ||
} | ||
describe('Express type middleware', function () { | ||
function runMiddleware(op) { | ||
op.forEach(function (midd) { | ||
midd(this.reqres.req, this.reqres.res); | ||
}, this); | ||
} | ||
function runAssert () { | ||
expect(this.stub).to.have.been.calledOnce; | ||
expect(this.stub).to.have.been.calledWith(this.reqres.req, this.reqres.res); | ||
} | ||
function runAssert () { | ||
expect(this.stub).to.have.been.calledOnce; | ||
expect(this.stubTwo).to.have.been.calledOnce; | ||
expect(this.stubThree).to.have.been.calledOnce; | ||
expect(this.stub).to.have.been.calledWith(this.reqres.req, this.reqres.res); | ||
expect(this.stubTwo).to.have.been.calledWith(this.reqres.req, this.reqres.res); | ||
expect(this.stubThree).to.have.been.calledWith(this.reqres.req, this.reqres.res); | ||
expect(this.stub).to.have.been.calledBefore(this.stubTwo); | ||
expect(this.stubTwo).to.have.been.calledBefore(this.stubThree); | ||
} | ||
function createTests (isSingle, operation) { | ||
it('should add middleware for ' + operation + ' OP, single: ' + isSingle, function (done) { | ||
if (isSingle) { | ||
this.crude[operation].use(this.stub); | ||
} else { | ||
this.crude.use(this.stub); | ||
} | ||
runMiddleware.call(this, this.crude[operation]); | ||
runAssert.call(this); | ||
done(); | ||
function createTests (isSingle, operation) { | ||
it('should add middleware for ' + operation + ' OP, single: ' + isSingle, function (done) { | ||
if (isSingle) { | ||
this.crude[operation].use(this.stub); | ||
this.crude[operation].use(this.stubTwo); | ||
this.crude[operation].use(this.stubThree); | ||
} else { | ||
this.crude.use(this.stub); | ||
this.crude.use(this.stubTwo); | ||
this.crude.use(this.stubThree); | ||
} | ||
runMiddleware.call(this, this.crude[operation]); | ||
runAssert.call(this); | ||
done(); | ||
}); | ||
} | ||
describe('Per CRUD OP', function () { | ||
// create tests | ||
[ | ||
'create', | ||
'readList', | ||
'readOne', | ||
'update', | ||
'delete', | ||
].forEach(createTests.bind(null, true)); | ||
}); | ||
} | ||
describe('CRUD wide middleware', function () { | ||
// create tests | ||
[ | ||
'create', | ||
'readList', | ||
'readOne', | ||
'update', | ||
'delete', | ||
].forEach(createTests.bind(null, false)); | ||
}); | ||
}); | ||
describe('Per CRUD OP', function () { | ||
// create tests | ||
[ | ||
'create', | ||
'readList', | ||
'readOne', | ||
'update', | ||
'delete', | ||
].forEach(createTests.bind(null, true)); | ||
describe('Query type middleware', function () { | ||
function runAsserts () { | ||
it('should call stub One once', function () { | ||
expect(this.stub).to.have.been.calledOnce; | ||
}); | ||
it('should call stub Two once', function () { | ||
expect(this.stubTwo).to.have.been.calledOnce; | ||
}); | ||
it('should call stub Three once', function () { | ||
expect(this.stubThree).to.have.been.calledOnce; | ||
}); | ||
it('should call stub One with expected arguments', function () { | ||
expect(this.stub).to.have.been.calledWith(this.query); | ||
}); | ||
it('should call stub Two with expected arguments', function () { | ||
expect(this.stubTwo).to.have.been.calledWith(this.query); | ||
}); | ||
it('should call stub Three with expected arguments', function () { | ||
expect(this.stubThree).to.have.been.calledWith(this.query); | ||
}); | ||
it('should call stub One before stub Two', function () { | ||
expect(this.stub).to.have.been.calledBefore(this.stubTwo); | ||
}); | ||
it('should call stub Two before stub Three', function () { | ||
expect(this.stubTwo).to.have.been.calledBefore(this.stubThree); | ||
}); | ||
} | ||
function createTests (isSingle, operation) { | ||
beforeEach(function () { | ||
this.stub = sinon.stub(); | ||
this.stubTwo = sinon.stub(); | ||
this.stubThree = sinon.stub(); | ||
if (isSingle) { | ||
this.crude[operation].use(this.stub); | ||
this.crude[operation].use(this.stubTwo); | ||
this.crude[operation].use(this.stubThree); | ||
} else { | ||
this.crude.useQuery(this.stub); | ||
this.crude.useQuery(this.stubTwo); | ||
this.crude.useQuery(this.stubThree); | ||
} | ||
// invoke and test | ||
return this.crude[operation](this.query); | ||
}); | ||
describe('Testing Operation: ' + operation + ', Is Single:' + isSingle, function () { | ||
runAsserts(); | ||
}); | ||
} | ||
describe('Per CRUD OP', function () { | ||
// create tests | ||
[ | ||
'readListQuery', | ||
'readOneQuery', | ||
'updateQuery', | ||
'deleteQuery', | ||
].forEach(createTests.bind(null, true)); | ||
}); | ||
describe('CRUD wide middleware', function () { | ||
// create tests | ||
[ | ||
'readListQuery', | ||
'readOneQuery', | ||
'updateQuery', | ||
'deleteQuery', | ||
].forEach(createTests.bind(null, false)); | ||
}); | ||
}); | ||
describe('CRUD wide middleware', function () { | ||
// create tests | ||
[ | ||
'create', | ||
'readList', | ||
'readOne', | ||
'update', | ||
'delete', | ||
].forEach(createTests.bind(null, false)); | ||
}); | ||
}); |
73750
1747
92