Skip to content

Commit 1c5e498

Browse files
committed
feat: push splats to the end of a children list
1 parent 575a41d commit 1c5e498

5 files changed

Lines changed: 88 additions & 14 deletions

File tree

README.md

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,49 @@
1+
[![Build Status](https://travis-ci.org/troch/route-node.svg?branch=master)](https://travis-ci.org/troch/route-node)
2+
13
# route-node
2-
A package to create a tree of named routes
4+
5+
A package to create a tree (trie) of named routes. It is similar to [routington](https://www.npmjs.com/package/routington) except that nodes are not added by splitting path by segment ("/"). Instead the trie is built with the supplied nodes, meaning each node is a valid route.
6+
7+
## Install
8+
9+
$ npm install route-node --save
10+
11+
## Usage
12+
13+
```javascript
14+
var RootNode = require('route-node');
15+
16+
// Create nodes
17+
var usersNode = new RouteNode('users', '/users', [
18+
new RouteNode('list', '/list'),
19+
new RouteNode('view', '/view/:id')
20+
]);
21+
22+
var ordersNode = new RouteNode('orders', '/orders', [
23+
new RouteNode('pending', '/pending'),
24+
new RouteNode('completed', '/completed'),
25+
new RouteNode('view', '/view/:id')
26+
]);
27+
28+
// Creating a top node
29+
var rootNode = new RouteNode('', '', [
30+
ordersNode,
31+
usersNode
32+
]);
33+
34+
// Add nodes programmatically
35+
rootNode.add(new RouteNode('home', '/home'));
36+
37+
rootNode.getPath('users.view'); // => "/users/view/:id"
38+
rootNode.buildPath('users.view', {id: 1}); // => "/users/view/1"
39+
40+
rootNode.matchPath('/users/view/1'); // => {name: "users.view", params: {id: "1"}}
41+
```
42+
43+
## Related packages
44+
45+
- [routington](https://www.npmjs.com/package/routington)
46+
47+
## Based on
48+
49+
- [parth-parser](https://www.npmjs.com/package/path-parser) for parsing, matching and building paths.

index.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ var RouteNode = (function () {
6565
}
6666

6767
this.children.push(route);
68+
// Push greedy splats to the bottom of the pile
69+
this.children.sort(function (childA, childB) {
70+
return childA.hasSplatParam ? -1 : 1;
71+
});
6872
}
6973
}, {
7074
key: '_findRouteByName',
@@ -92,13 +96,14 @@ var RouteNode = (function () {
9296
return matched ? segments : [];
9397
}
9498
}, {
95-
key: 'matchRoute',
96-
value: function matchRoute(path) {
99+
key: 'matchPath',
100+
value: function matchPath(path) {
97101
var segments = [];
98102

99103
var matchChildren = function matchChildren(node, pathSegment, matched) {
100104
var _loop = function (i) {
101105
var child = node.children[i];
106+
// Partially match path
102107
var match = child.parser.partialMatch(pathSegment);
103108
if (match) {
104109
// Append name and extend params
@@ -114,7 +119,7 @@ var RouteNode = (function () {
114119
v: matched
115120
};
116121
}
117-
// If no children to match against but segment left
122+
// If no children to match against but unmatched path left
118123
if (!child.children.length) {
119124
return {
120125
v: false

lib/RouteNode.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ export default class RouteNode {
3535
}
3636

3737
this.children.push(route)
38+
// Push greedy splats to the bottom of the pile
39+
this.children.sort((childA, childB) => childA.hasSplatParam ? -1 : 1)
3840
}
3941

4042
_findRouteByName(routeName) {
@@ -59,7 +61,7 @@ export default class RouteNode {
5961
return matched ? segments : []
6062
}
6163

62-
matchRoute(path) {
64+
matchPath(path) {
6365
let segments = []
6466

6567
let matchChildren = (node, pathSegment, matched) => {

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "route-node",
3-
"version": "0.0.0",
3+
"version": "0.0.1",
44
"description": "A package to create a tree of named routes#",
55
"main": "index.js",
66
"scripts": {
@@ -28,6 +28,6 @@
2828
"mocha": "^2.2.5"
2929
},
3030
"dependencies": {
31-
"path-parser": "0.0.2"
31+
"path-parser": "~0.0.3"
3232
}
3333
}

test/main.js

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,24 +80,44 @@ describe('RouteNode', function () {
8080
}).should.throw();
8181
});
8282

83-
it('should find a nested route by path', function () {
83+
it('should find a nested route by matching a path', function () {
8484
var node = getRoutes();
8585
// Building paths
86-
node.matchRoute('/users/view/1').should.eql({name: 'users.view', params: {id: '1'}});
87-
node.matchRoute('/users/profile/1').should.be.false;
88-
node.matchRoute('/users/view/profile/1').should.be.false;
86+
node.matchPath('/users/view/1').should.eql({name: 'users.view', params: {id: '1'}});
87+
node.matchPath('/users/profile/1').should.be.false;
88+
node.matchPath('/users/view/profile/1').should.be.false;
89+
});
90+
91+
it('should find a nested route by matching a path with a splat', function () {
92+
var node = getRoutesWithSplat();
93+
// Building paths
94+
node.matchPath('/users/view/1').should.eql({name: 'users.view', params: {id: '1'}});
95+
node.matchPath('/users/profile/1').should.eql({name: 'users.splat', params: {id: 'profile/1'}});
96+
node.matchPath('/users/view/profile/1').should.be.false;
8997
});
9098
});
9199

92100

93101
function getRoutes() {
94102
var usersNode = new RouteNode('users', '/users', [
95-
new RouteNode('list', '/list'),
96-
new RouteNode('view', '/view/:id')
97-
])
103+
new RouteNode('list', '/list'),
104+
new RouteNode('view', '/view/:id')
105+
]);
98106

99107
return new RouteNode('', '', [
100108
new RouteNode('home', '/home'),
101109
usersNode
102110
]);
103111
}
112+
113+
function getRoutesWithSplat() {
114+
var usersNode = new RouteNode('users', '/users', [
115+
new RouteNode('splat', '/*id'),
116+
new RouteNode('list', '/list'),
117+
new RouteNode('view', '/view/:id')
118+
]);
119+
120+
return new RouteNode('', '', [
121+
usersNode
122+
]);
123+
}

0 commit comments

Comments
 (0)