mixdown-router
Advanced tools
Comparing version 0.1.0 to 0.2.0
112
index.js
@@ -5,2 +5,3 @@ var _ = require('lodash'); | ||
var url = require('url'); | ||
var querystring = require('querystring'); | ||
@@ -13,9 +14,10 @@ var Router = function() { | ||
var handler = Array.prototype.slice.call(arguments, 0)[0]; | ||
var httpContext = Array.prototype.slice.call(arguments, 1)[0]; | ||
var route = Array.prototype.slice.call(arguments, 1)[0]; | ||
var httpContext = Array.prototype.slice.call(arguments, 2)[0]; | ||
var context = _.clone(httpContext); | ||
context.app = this; | ||
context.route = route; | ||
handler.call(context, context); | ||
}; | ||
@@ -43,10 +45,26 @@ | ||
var newRouter = new plRouter(); | ||
var addParam = function (param, key) { | ||
_.each(options.params, function(regex, key) { | ||
newRouter.param(key, new RegExp(regex)); | ||
}); | ||
if (param && param.regex && /(rest|query)/i.test(param.kind)) { | ||
_.each(options.routes, function(route, key) { | ||
if (param.kind.toLowerCase() === "rest") { | ||
newRouter.param(key, new RegExp(param.regex)); | ||
} | ||
else if (param.kind.toLowerCase() === 'query') { | ||
newRouter.qparam(key, new RegExp(param.regex)); | ||
} | ||
} | ||
}; | ||
// add routes | ||
_.each(router.routes, function (route, key) { | ||
// add route-level params | ||
if (route.params) { | ||
_.each(route.params, addParam); | ||
} | ||
var handler = handlers[route.handler]; | ||
if (!_.isFunction(handler)) { | ||
@@ -57,3 +75,3 @@ handler = handlers.constructor.prototype[route.handler]; | ||
if (_.isFunction(handler)) { | ||
newRouter.use(route.method, route.path, _.bind(baseHandler, app, handler)); | ||
newRouter.use(route.method, route.path, _.bind(baseHandler, app, handler, route)); | ||
} | ||
@@ -72,16 +90,32 @@ | ||
var uri = url.parse(''); | ||
var routeObject = options.routes[route]; | ||
var routeObject = router.routes[route]; | ||
// if these are set on the route, then attach them. This will allow injection of FQ urls. | ||
uri.hostname = routeObject.hostname; | ||
uri.port = routeObject.port; | ||
uri.protocol = routeObject.protocol || null; | ||
uri.hostname = routeObject.hostname || null; | ||
uri.port = routeObject.port || null; | ||
uri.method = routeObject.method || null; | ||
// map the param fields to querystring as defined in route. | ||
if (routeObject.query) { | ||
uri.query = {}; | ||
var queryParams = {}; | ||
var restParams = {}; | ||
_.each(routeObject.query, function(q) { | ||
// split params into rest/query | ||
_.each(routeObject.params, function (param, key) { | ||
if (param.kind === 'rest') { | ||
restParams[key] = param; | ||
} | ||
else if (param.kind === 'query') { | ||
queryParams[key] = param; | ||
} | ||
}); | ||
if (params[q] !== null ) { | ||
uri.query[q] = params[q]; | ||
if (!_.isEmpty(queryParams)) { | ||
_.each(queryParams, function (param, key) { | ||
if (params[key] || param.default) { | ||
uri.query = uri.query || {}; | ||
// replace capturing group with value | ||
uri.query[key] = param.regex.replace(/\(.*\)/, params[key] || param.default); | ||
} | ||
@@ -93,33 +127,30 @@ }); | ||
uri.pathname = ''; | ||
var regexSplit = /(\?|\/)([^\?^\/]+)/g; | ||
var restParams = routeObject.path.match(regexSplit); | ||
// get url segments | ||
// drop first element in array, since a leading slash creates an empty segment | ||
var urlSegments = _.rest(routeObject.path.split('/')); | ||
if (!restParams || restParams.length === 0) { | ||
restParams = [routeObject.path]; | ||
} | ||
// replace named params with corresponding values and generate uri | ||
_.each(restParams, function(str, i) { | ||
var paramConfig = null; | ||
_.each(urlSegments, function (segment, i) { | ||
// is this a REST segment? | ||
if (/^\??:/.test(segment)) { | ||
// replace with param value if available. | ||
var pName = segment.replace(/^\??:/, ''); | ||
var pConfig = restParams[pName]; | ||
// find the corresponding parameter in param list. | ||
_.each(options.params, function(rx, name) { | ||
if (!paramConfig && str.substring(1) === ':' + name) { | ||
paramConfig = { | ||
name: name, | ||
format: rx | ||
}; | ||
} | ||
}); | ||
// now that we have the param spec, we can put the value in the format string. | ||
if (paramConfig) { | ||
var val = params[paramConfig.name]; | ||
uri.pathname += '/' + paramConfig.format.replace(/\(.*\)/, val); | ||
if (pConfig && pConfig.kind === 'rest') { | ||
// this is a rest param. replace the capturing group with our value. | ||
uri.pathname += '/' + pConfig.regex.replace(/\(.*\)/, params[pName] || pConfig.default ); | ||
} | ||
else { | ||
uri.pathname += str; | ||
} | ||
} | ||
else { | ||
// just append | ||
uri.pathname += '/' + segment; | ||
} | ||
}); | ||
uri.search = uri.query ? '?' + querystring.stringify(uri.query) : null; | ||
uri.path = uri.pathname + (uri.search || ''); | ||
uri.host = uri.hostname ? (uri.hostname + (uri.port ? ':' + uri.port : '')) : null; | ||
return uri; | ||
@@ -140,5 +171,4 @@ } | ||
this.router.routes = options.routes; | ||
this.router.params = options.params; | ||
}; | ||
module.exports = Router; |
{ | ||
"name": "mixdown-router", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "Router for mixdown.js", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -6,7 +6,2 @@ { | ||
"options": { | ||
"params": { | ||
"gender": "(\\w+)", | ||
"age": "(\\d+)", | ||
"id": "(\\d{1})" | ||
}, | ||
"routes": { | ||
@@ -31,5 +26,2 @@ "index": { | ||
"options": { | ||
"params": { | ||
"bark": "bark-(loud|quiet)" | ||
}, | ||
"routes": { | ||
@@ -39,10 +31,35 @@ "search": { | ||
"path": "/dogs/:gender/:bark/:age", | ||
"handler": "dogs" | ||
"handler": "dogs", | ||
"params": { | ||
"bark": { | ||
"regex": "bark-(loud|quiet)", | ||
"kind": "rest" | ||
}, | ||
"gender": { | ||
"regex": "(\\w+)", | ||
"kind": "rest" | ||
}, | ||
"age": { | ||
"regex": "(\\d+)", | ||
"kind": "rest" | ||
} | ||
} | ||
}, | ||
"single": { | ||
"method": "GET", | ||
"path": "/dog/:id", | ||
"query": [ "hidePictures" ], | ||
"handler": "dog" | ||
"handler": "dog", | ||
"params": { | ||
"hidePictures": { | ||
"kind": "query", | ||
"regex": "(true|false)" | ||
}, | ||
"id": { | ||
"regex": "(\\d{1})", | ||
"kind": "rest" | ||
} | ||
} | ||
}, | ||
"create": { | ||
@@ -52,3 +69,9 @@ "method": "POST", | ||
"body": [ "gender", "age", "phone" ], | ||
"handler": "create" | ||
"handler": "create", | ||
"params": { | ||
"id": { | ||
"kind": "rest", | ||
"regex": "(\\d{1})" | ||
} | ||
} | ||
} | ||
@@ -60,2 +83,3 @@ } | ||
}, | ||
{ | ||
@@ -68,5 +92,2 @@ "id": "cats", | ||
"options": { | ||
"params": { | ||
"claws": "claws-(yes|no)" | ||
}, | ||
"routes": { | ||
@@ -76,3 +97,17 @@ "search": { | ||
"path": "/cats/:gender/:claws/:age", | ||
"handler": "cats" | ||
"handler": "cats", | ||
"params": { | ||
"claws": { | ||
"regex": "claws-(yes|no)", | ||
"kind": "rest" | ||
}, | ||
"gender": { | ||
"regex": "(\\w+)", | ||
"kind": "rest" | ||
}, | ||
"age": { | ||
"regex": "(\\d+)", | ||
"kind": "rest" | ||
} | ||
} | ||
}, | ||
@@ -82,3 +117,9 @@ "single": { | ||
"path": "/cat/:id", | ||
"handler": "cat" | ||
"handler": "cat", | ||
"params": { | ||
"id": { | ||
"regex": "(\\d{1})", | ||
"kind": "rest" | ||
} | ||
} | ||
} | ||
@@ -96,17 +137,17 @@ } | ||
"logger": { | ||
"defaults": { | ||
"handleExceptions": false, | ||
"json": false, | ||
"timestamp": true, | ||
"colorize": true, | ||
"prettyPrint": true | ||
}, | ||
"transports": [{ | ||
"transport": "Console", | ||
"options": { | ||
"level": "info" | ||
} | ||
}] | ||
"defaults": { | ||
"handleExceptions": false, | ||
"json": false, | ||
"timestamp": true, | ||
"colorize": true, | ||
"prettyPrint": true | ||
}, | ||
"transports": [{ | ||
"transport": "Console", | ||
"options": { | ||
"level": "info" | ||
} | ||
}] | ||
} | ||
} | ||
} |
@@ -17,5 +17,5 @@ var _ = require('lodash'); | ||
t.equal(typeof(router.dispatch), 'function', 'router.dispatch should be a function.'); | ||
t.equal(router.params.length, 4, 'Should contain 4 params'); | ||
t.ok(router.params.length, 'Should contain some params'); | ||
t.end(); | ||
}) | ||
}); |
@@ -15,2 +15,3 @@ var _ = require('lodash'); | ||
}; | ||
var uri = app.plugins.router.url('search', params); | ||
@@ -34,2 +35,3 @@ var url = app.plugins.router.format('search', params); | ||
}; | ||
var uri = app.plugins.router.url('single', params); | ||
@@ -39,3 +41,3 @@ var url = app.plugins.router.format('single', params); | ||
pathname: '/dog/1234', | ||
query: { hidePictures: true } | ||
query: { hidePictures: 'true' } | ||
}; | ||
@@ -42,0 +44,0 @@ var goldUrl = '/dog/1234?hidePictures=true'; |
25239
12
477