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

moved a logic for validate from Vatican.preprocess to ProcessingChain.add #19

Open
wants to merge 10 commits into
base: v1.3
Choose a base branch
from
40 changes: 28 additions & 12 deletions lib/processingChain.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ function ProcessingChain( ) {
}

ProcessingChain.prototype.add = function( proc ) {
proc.names = proc.names ?
( Array.isArray(proc.names) ? proc.names : Array(proc.names) )
: [];
if(proc.fn.length == 4) //it's an error handler
this.errorHandlers.push(proc);
else
Expand All @@ -23,9 +26,17 @@ ProcessingChain.prototype.pop = function() {
this.chain.pop();
}

ProcessingChain.prototype.runChain = function( req, res, finalFn, handler ) {
ProcessingChain.prototype.runChain = function( params ) {
params = params || {};
var req = params.req;
var res = params.res;
var finalFn = params.finalFn;
var handler = params.handler;
var endPrep = (params.endPrep && {fn: params.endPrep}) || []; //last preprocessor

var currentItem = 0;
var totalItems = this.chain.length;
var chain = [].concat(this.chain, endPrep);
var totalItems = chain.length;
var self = this;
if(totalItems == 0) {
if(typeof finalFn == 'function') finalFn(req, res);
Expand All @@ -42,18 +53,23 @@ ProcessingChain.prototype.runChain = function( req, res, finalFn, handler ) {
}

var next = function(err) {
var chain = self.chain;
//chain is taken from the closure
if ( err ) { //If there is an error, switch to the error handlers chain
chain = self.errorHandlers;
currentItem = -1;
totalItems = self.errorHandlers.length;
}
if ( currentItem < totalItems - 1 ) {
for(var idx = currentItem + 1; idx < chain.length; idx++) {
if( (chain[idx].names && chain[idx].names.indexOf(handler.name) != -1) || !chain[idx].names) {
break
var idx = ++currentItem;

if( handler && handler.name) {
for(; idx < chain.length; idx++) {
if( !chain[idx].names || ( ! chain[idx].names.length ) || ~chain[idx].names.indexOf(handler.name)) {
break
}
}
}
}

currentItem = idx
if(err) {
chain[currentItem].fn(err, req, res, nextError)
Expand All @@ -65,16 +81,16 @@ ProcessingChain.prototype.runChain = function( req, res, finalFn, handler ) {
}
}
if(handler) {
var firstItem = self.findFirstValidItem(handler.name)
var firstItem = self.findFirstValidItem(handler.name, chain)
firstItem.fn(req, res, next)
} else {
this.chain[0].fn(req, res, next )
chain[0].fn(req, res, next )
}
};

ProcessingChain.prototype.findFirstValidItem = function(name) {
if(!name) return this.chain[0]
return _.find(this.chain, function(item) {
ProcessingChain.prototype.findFirstValidItem = function(name, chain) {
if(!name) return chain[0]
return _.find(chain, function(item) {
if(item.names && Array.isArray(item.names) && item.names.length > 0) {
return item.names.indexOf(name) != -1
} else {
Expand Down
46 changes: 32 additions & 14 deletions lib/vatican.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ var http = require("http"),
handlerParser = require("./handlerParser"),
processingChain = require("./processingChain"),
mongoose = require("mongoose"),
_ = require("lodash");
_ = require("lodash"),
path = require("path");


module.exports = Vatican;
Expand Down Expand Up @@ -37,22 +38,20 @@ function Vatican(options) {
this.parseHandlers();
this.paths = [];
this.server = null;
this.totalPreprocessors = 0;
this.preprocessors = new processingChain();
this.postprocessors = new processingChain();
}

Vatican.prototype.preprocess = function(fn, endpointNames) {
this.preprocessors.add({fn: fn, names: endpointNames ? endpointNames : []})
this.totalPreprocessors = this.preprocessors.getTotal();
this.preprocessors.add({fn: fn, names: endpointNames})
}

Vatican.prototype.postprocess = function(fn, endpointNames) {
this.postprocessors.add({fn: fn, names: endpointNames ? endpointNames : []});
this.postprocessors.add({fn: fn, names: endpointNames});
}

Vatican.prototype.parseHandlers = function(cb) {
var dir = this.options.handlers;
var dir = path.isAbsolute(this.options.handlers) ? this.options.handlers : process.cwd() + "/" + this.options.handlers;
var self = this;
handlerParser.parse(dir, function(err, path) {
if(typeof cb == 'function' && err) return cb(err)
Expand Down Expand Up @@ -148,18 +147,20 @@ Vatican.prototype.requestHandler = function (req, res) {
} else {
try {
var request = this.createRequest(req);
var hdlr = this.loadHandler(process.cwd() + "/" + methodFound.handlerPath);
var hdlr = this.loadHandler(methodFound.handlerPath);
res = vaticanResp.improveResponse(res, request, this.options, this.postprocessors);
//Parse the request to grab the parameters
this.parseRequest(request, methodFound.url, req, function(newRequest) {
//Run the pre-process chain and finally, call the handler
if(self.preprocessors.getTotal() > self.totalPreprocessors) {
self.preprocessors.pop();
}
var hdlrInstance = new hdlr(self.getCorrectModel(methodFound))

hdlrInstance.models = self.dbmodels //Let the handler access all other models in case they're neeeded
self.preprocessors.add({fn: hdlrInstance[methodFound.action].bind(hdlrInstance)})
self.preprocessors.runChain(newRequest, res, null, methodFound);

self.preprocessors.runChain({
req: newRequest,
res: res,
handler: methodFound,
endPrep: hdlrInstance[methodFound.action].bind(hdlrInstance),
});
});
} catch (ex) {
logger.error("Error instantiating handler: " + ex.message);
Expand All @@ -171,7 +172,7 @@ Vatican.prototype.requestHandler = function (req, res) {

Vatican.prototype.getCorrectModel = function(handler) {
var modelName = handler.handlerName.replace("Hdlr", '')
return this.dbmodels[modelName]
return this.dbmodels && this.dbmodels[modelName]
}

/**
Expand All @@ -181,6 +182,7 @@ Vatican.prototype.start = function(cb) {
try {
this.server = http.createServer(this.requestHandler.bind(this));
this.server.listen(this.options.port);
console.log(this.server);
logger.info("Server started on port: " + this.options.port);
if(typeof cb == 'function') {
cb();
Expand All @@ -191,6 +193,22 @@ Vatican.prototype.start = function(cb) {
}
};

/**
Close the server
*/
Vatican.prototype.close = function(cb) {
try {
this.server.close();
logger.info("Server closed");
if(typeof cb == 'function') {
cb();
}
} catch (ex) {
logger.error("Error closing server: " + ex.message);
return false;
}
}

Vatican.prototype.dbStart = function(opts, cb) {
if(typeof opts === 'function') {
cb = opts
Expand Down
40 changes: 22 additions & 18 deletions lib/vaticanResponse.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,30 @@ VaticanResponse.prototype.send = function(txt) {
var headers = {};
var self = this;
this.body = txt;
this.ppChain.runChain(this.request, this, function(req, resp) {
//Check for CORS config
if(self.options.cors !== false) {
headers = _getCORSHeaders(self.options.cors);
}
this.ppChain.runChain({
req: this.request,
res: this,
finalFn: function(req, resp) {
//Check for CORS config
if(self.options.cors !== false) {
headers = _getCORSHeaders(self.options.cors);
}

//Adds the rest of the headers
for(var i in resp.headers) {
headers = _.assign(headers, resp.headers[i]);
}
//Adds the rest of the headers
for(var i in resp.headers) {
headers = _.assign(headers, resp.headers[i]);
}

//Write the headers
resp.response.writeHead(resp.statusCode, headers);
if( typeof resp.body == 'object') {
resp.body = JSON.stringify(resp.body);
}
//Write the headers
resp.response.writeHead(resp.statusCode, headers);
if( typeof resp.body == 'object') {
resp.body = JSON.stringify(resp.body);
}

//Write out the response text
resp.response.write(resp.body);
resp.response.end();
//Write out the response text
resp.response.write(resp.body);
resp.response.end();
},
})

};
Expand Down Expand Up @@ -95,4 +99,4 @@ function _getCORSHeaders(corsOpts) {
module.exports = {
improveResponse: _improveResponse,
writeNotFound: _writeNotFound
};
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"devDependencies": {
"should": "4.0.4",
"mocha": "1.21.4",
"supertest": "0.13.0",
"istanbul": "0.3.0"
}
}
6 changes: 6 additions & 0 deletions test/fixtures/vaticanConfig/handlers/people.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = People;
function People() {}
@endpoint (url: /people method: get)
People.prototype.getPeople = function(req, res) {
res.send('ok');
}
22 changes: 22 additions & 0 deletions test/fixtures/vaticanHttpMethods/handlers/people.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = People;
var peeps = [ 'user0', 'user1'];
function People() {}
@endpoint (url: /people method: get)
People.prototype.getPeople = function(req, res) {
res.send('get,' + peeps.join(','));
}

@endpoint (url: /people method: post)
People.prototype.postPeople = function(req, res) {
res.send('post,' + peeps.join(','));
}

@endpoint (url: /people method: put)
People.prototype.putPeople = function(req, res) {
res.send('put,' + peeps.join(','));
}

@endpoint (url: /people method: delete)
People.prototype.deletePeople = function(req, res) {
res.send('delete,' + peeps.join(','));
}
Loading