Comparing version 0.1.0 to 1.0.0
17
index.js
var Routes = require('routes') | ||
, extend = require('xtend') | ||
, extend = require('deep-extend') | ||
module.exports = createRouter | ||
function createRouter(noMatch, _verbs) { | ||
function createRouter(defaultRoute, _root, _verbs) { | ||
var routers = {} | ||
, root = _root || '' | ||
, verbs = _verbs || ['get', 'post', 'put', 'patch', 'delete'] | ||
@@ -22,4 +23,10 @@ , routeFn | ||
result = routers[method].match(route) | ||
if (root.length && route.indexOf(root) === 0) { | ||
route = route.slice(root.length, route.length) | ||
} | ||
if(routers[method]) { | ||
result = routers[method].match(route) | ||
} | ||
if(!result) { | ||
@@ -33,4 +40,4 @@ result = routers.any.match(route) | ||
} else { | ||
if(typeof noMatch === 'function') { | ||
noMatch.apply(null, args) | ||
if(typeof defaultRoute === 'function') { | ||
defaultRoute.apply(null, args) | ||
@@ -37,0 +44,0 @@ return |
{ | ||
"name": "commuter", | ||
"version": "0.1.0", | ||
"description": "A minimal, composable router with sub-routes.", | ||
"version": "1.0.0", | ||
"description": "A minimal, composable router that supports sub-routes.", | ||
"main": "index.js", | ||
@@ -15,3 +15,4 @@ "scripts": { | ||
"router", | ||
"routes" | ||
"routes", | ||
"http" | ||
], | ||
@@ -25,4 +26,4 @@ "author": "Nathan Wittstock <nate@milkandtang.com>", | ||
"dependencies": { | ||
"routes": "^2.0.0", | ||
"xtend": "^4.0.0" | ||
"deep-extend": "^0.3.2", | ||
"routes": "^2.0.0" | ||
}, | ||
@@ -29,0 +30,0 @@ "devDependencies": { |
# commuter | ||
A minimal, composable router with sub-routes. | ||
A minimal, composable router that supports sub-routes. | ||
[![Build Status](http://img.shields.io/travis/fardog/commuter/master.svg?style=flat)](https://travis-ci.org/fardog/commuter) | ||
[![npm install](http://img.shields.io/npm/dm/commuter.svg?style=flat)](https://www.npmjs.org/package/commuter) | ||
## Example | ||
@@ -46,4 +49,55 @@ | ||
## API | ||
- `commuter([defaultRoute] [, root] [, verbs])` - Create a new router. Accepts | ||
the following parameters: | ||
- `defaultRoute` - A function to be called if no routes are matched | ||
- `root` - A string to be ignored at the begging of any URL; for example, | ||
passing `/some/string` will cause the route `/some/string/with/more` to | ||
be matched using only `/with/more` | ||
- `verbs` - By default, the standard HTTP verbs are supported: _get, post, | ||
put, patch, delete_. If you need different verbs, pass them here. It will | ||
replace the defaults, excepting the special _any_ route, which is always | ||
available. | ||
The `router` that is returned has the following methods: | ||
- `router(request, [args ...])` - Route a `request` through the router. Routes | ||
are matched in the order they were added. | ||
- `request` - An [http.IncomingMessage][request], as called by an | ||
[http.Server][server] or similar. | ||
- `args` - Any number of arguments which will be passed to the matched | ||
function. | ||
- `router.<method>(pattern, fn)` - Define a route on your router | ||
- `<method>` - Any of the standard HTTP verbs, or the verbs you defined; for | ||
example, `router.get`, `router.post`, or `router.any`. | ||
- `pattern` - A string that is either a Cucumber-style pattern describing a | ||
URL or a Regex string (not a RegEx object). commuter uses [routes][routes] | ||
for it's pattern matching, and follows those docs and rules. | ||
- `fn` - The function to be called when your route is matched. This function | ||
should take the same form as your `router.<method>` function; that is, if | ||
your router was called as `router(req, res)`, your function will be called | ||
with `fn(req, res)` | ||
The `request` object only needs to be "request-like"; that is, the only | ||
properties that are used are `request.url` to match the url, and optionally | ||
`request.method`, which will default to the `router.any` routes if missing. | ||
As the `request` passes through the router, a few additional properties are | ||
added to it: | ||
- `request.params` - A key/value object of the matched parameters from your | ||
pattern, and their captures values. | ||
- `request.splats` - An array of the matched splats | ||
- `request.route` - The last route `pattern` that was matched. | ||
There are a few other additions that come via [routes][routes] and are | ||
explained in their docs. | ||
## License | ||
MIT. See [LICENSE](./LICENSE) for details. | ||
[request]: http://nodejs.org/api/http.html#http_http_incomingmessage | ||
[server]: http://nodejs.org/api/http.html#http_class_http_server | ||
[routes]: https://www.npmjs.com/package/routes |
103
test.js
@@ -22,3 +22,3 @@ var test = require('tape') | ||
test('passes through any additional parameters provided', function(t) { | ||
t.plan(1) | ||
t.plan(2) | ||
@@ -28,9 +28,11 @@ var router = commuter() | ||
, res = {ok: function() {}} | ||
, superflous = {} | ||
router.get(req.url, onRoute) | ||
router(req, res) | ||
router(req, res, superflous) | ||
function onRoute(request, response) { | ||
function onRoute(request, response, unnecessary) { | ||
t.strictEqual(res, response) | ||
t.strictEqual(superflous, unnecessary) | ||
@@ -98,3 +100,3 @@ t.end() | ||
, subRouter = commuter() | ||
, req = {url:'/admin/section/home', method: 'GET'} | ||
, req = {url: '/admin/section/home', method: 'GET'} | ||
, res = {ok: function() {}} | ||
@@ -115,4 +117,97 @@ | ||
test('strips root from url when provided', function(t) { | ||
t.plan(1) | ||
var router = commuter(null, '/strip') | ||
, req = {url: '/strip/admin/section/home', method: 'GET'} | ||
router.get('/admin*', onRoute) | ||
router(req) | ||
function onRoute(request) { | ||
t.ok(request) | ||
t.end() | ||
} | ||
}) | ||
test('root url does not affect sub-routes', function(t) { | ||
t.plan(2) | ||
var router = commuter(null, '/strip') | ||
, subRouter = commuter() | ||
, req = {url: '/strip/admin/section/home', method: 'GET'} | ||
, res = {ok: function() {}} | ||
router.get('/admin*', subRouter) | ||
subRouter.get('/section/:panel', onRoute) | ||
router(req, res) | ||
function onRoute(request, response) { | ||
t.equal(request.params.panel, 'home') | ||
t.strictEqual(response, res) | ||
t.end() | ||
} | ||
}) | ||
test('arbitrary verbs can be defined', function(t) { | ||
t.plan(1) | ||
var router = commuter(null, null, ['leap']) | ||
, req = {url: '/path', method: 'leap'} | ||
router.leap(req.url, onRoute) | ||
router(req) | ||
function onRoute() { | ||
t.ok(true) | ||
t.end() | ||
} | ||
}) | ||
test('"any" route is always present', function(t) { | ||
t.plan(1) | ||
var router = commuter(null, null, ['leap']) | ||
, req = {url: '/path', method: 'wut'} | ||
router.any(req.url, onRoute) | ||
router(req) | ||
function onRoute() { | ||
t.ok(true) | ||
t.end() | ||
} | ||
}) | ||
test('latest defined parameter takes precedence', function(t) { | ||
t.plan(2) | ||
var router = commuter() | ||
, subRouter = commuter() | ||
, req = {url: '/admin/item/go/section/home', method: 'GET'} | ||
, res = {ok: function() {}} | ||
router.get('/admin/:panel/:section/*', subRouter) | ||
subRouter.get('section/:section', onRoute) | ||
router(req, res) | ||
function onRoute(request, response) { | ||
t.equal(request.params.panel, 'item') | ||
t.equal(request.params.section, 'home') | ||
t.end() | ||
} | ||
}) | ||
function noop() { | ||
// | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
10977
8
189
0
103
+ Addeddeep-extend@^0.3.2
+ Addeddeep-extend@0.3.3(transitive)
- Removedxtend@^4.0.0
- Removedxtend@4.0.2(transitive)