route-trie
Advanced tools
Comparing version 0.1.2 to 0.2.0
@@ -7,3 +7,3 @@ { | ||
], | ||
"version": "0.1.2", | ||
"version": "0.2.0", | ||
"main": "index.js", | ||
@@ -10,0 +10,0 @@ "repository": { |
@@ -7,3 +7,3 @@ { | ||
], | ||
"version": "0.1.2", | ||
"version": "0.2.0", | ||
"main": "index.js", | ||
@@ -10,0 +10,0 @@ "repository": { |
47
index.js
@@ -6,3 +6,3 @@ // **Github:** https://github.com/zensh/route-trie | ||
/* global module, define */ | ||
;(function (root, factory) { | ||
;(function(root, factory) { | ||
'use strict'; | ||
@@ -14,3 +14,3 @@ | ||
}(typeof window === 'object' ? window : this, function () { | ||
}(typeof window === 'object' ? window : this, function() { | ||
'use strict'; | ||
@@ -29,3 +29,3 @@ | ||
Trie.prototype.define = function (pattern) { | ||
Trie.prototype.define = function(pattern) { | ||
if (typeof pattern !== 'string') throw new TypeError('Only strings can be defined.'); | ||
@@ -40,3 +40,3 @@ pattern = pattern | ||
Trie.prototype.match = function (path) { | ||
Trie.prototype.match = function(path) { | ||
// the path should be normalized before match, just as path.normalize do in Node.js | ||
@@ -47,3 +47,6 @@ path = path | ||
var frags = path.split('/'); | ||
var result = {params: {}, node: null}; | ||
var result = { | ||
params: {}, | ||
node: null | ||
}; | ||
var node = this.root; | ||
@@ -62,2 +65,9 @@ var child = null; | ||
if (regex[2] && !regex[2].test(frag)) continue; | ||
if (regex[0]._nodeState.matchRemaining) { | ||
while (frags.length) { | ||
var _frag = safeDecodeURIComponent(frags.shift()); | ||
if (_frag === false) return null; | ||
frag += '/' + _frag; | ||
} | ||
} | ||
if (regex[1]) result.params[regex[1]] = frag; | ||
@@ -84,8 +94,10 @@ child = regex[0]; | ||
} | ||
if (child._nodeState.matchRemaining) throw new Error('Can not define regex pattern after "*" pattern'); | ||
return define(child, frags, flags); | ||
} | ||
function NodeState(frag) { | ||
function NodeState(frag, matchRemaining) { | ||
this.name = frag; | ||
this.endpoint = false; | ||
this.matchRemaining = matchRemaining; | ||
this.childNodes = Object.create(null); | ||
@@ -96,3 +108,3 @@ this.regexNames = Object.create(null); | ||
function Node(frag) { | ||
function Node(frag, matchRemaining) { | ||
Object.defineProperty(this, '_nodeState', { | ||
@@ -102,3 +114,3 @@ enumerable: false, | ||
writable: false, | ||
value: new NodeState(frag) | ||
value: new NodeState(frag, matchRemaining) | ||
}); | ||
@@ -109,2 +121,3 @@ } | ||
var node = null; | ||
var matchRemaining = false; | ||
var parameter = ''; | ||
@@ -114,3 +127,6 @@ var childNodes = parentNode._nodeState.childNodes; | ||
var regexChildNodes = parentNode._nodeState.regexChildNodes; | ||
var lastRegexChildNode = regexChildNodes[regexChildNodes.length - 1]; | ||
lastRegexChildNode = lastRegexChildNode && lastRegexChildNode[0]; | ||
// Is a simple string | ||
@@ -122,3 +138,3 @@ if (isValidSlug(frag)) { | ||
// Find a parameter name for the string | ||
frag = frag.replace(parameterReg, function (str) { | ||
frag = frag.replace(parameterReg, function(str) { | ||
parameter = str.slice(1); | ||
@@ -128,7 +144,14 @@ return ''; | ||
if (frag === '*' || frag === '(*)') { | ||
frag = '.*'; | ||
matchRemaining = true; | ||
} | ||
if (frag) frag = wrapRegex(frag); | ||
if (regexNames[frag] >= 0) node = regexChildNodes[regexNames[frag]][0]; | ||
else { | ||
node = new Node(frag); | ||
else if (lastRegexChildNode && lastRegexChildNode._nodeState.matchRemaining) { | ||
throw new Error('Can not define more regex pattern while "*" pattern defined'); | ||
} else { | ||
node = new Node(frag, matchRemaining); | ||
regexChildNodes.push([node, parameter, frag && new RegExp(frag, flags)]); | ||
@@ -159,4 +182,4 @@ regexNames[frag] = regexChildNodes.length - 1; | ||
Trie.NAME = 'Trie'; | ||
Trie.VERSION = 'v0.1.2'; | ||
Trie.VERSION = 'v0.2.0'; | ||
return Trie; | ||
})); |
@@ -7,3 +7,3 @@ { | ||
], | ||
"version": "0.1.2", | ||
"version": "0.2.0", | ||
"main": "index.js", | ||
@@ -10,0 +10,0 @@ "repository": { |
@@ -1,2 +0,2 @@ | ||
route-trie v0.1.2 [![Build Status](https://travis-ci.org/zensh/route-trie.svg)](https://travis-ci.org/zensh/route-trie) | ||
route-trie v0.2.0 [![Build Status](https://travis-ci.org/zensh/route-trie.svg)](https://travis-ci.org/zensh/route-trie) | ||
==== | ||
@@ -30,5 +30,2 @@ A trie-based URL router. | ||
```js | ||
``` | ||
## Installation | ||
@@ -81,2 +78,4 @@ | ||
- `:name(regex)`- Named regular expression match ex `/:type/:id([a-z0-9]{6})` | ||
- `*` - Match remaining path without saving the parameter (not recommended), ex `/*` will match all path. | ||
- `:name(*)`- Named regular expression match, match remaining path, ex `/:type/:other(*)` will match `/post/x` or `/task/x/y` or `/any/x/y/z`... | ||
@@ -83,0 +82,0 @@ ### Trie.prototype.match(path) |
@@ -7,7 +7,7 @@ 'use strict'; | ||
describe('route-trie', function () { | ||
it('trie.define', function () { | ||
describe('route-trie', function() { | ||
it('trie.define', function() { | ||
var trie = new Trie(); | ||
assert.throws(function () { | ||
assert.throws(function() { | ||
trie.define(1); | ||
@@ -36,5 +36,17 @@ }, Error); | ||
assert.notStrictEqual(trie.define('/Post'), trie.define('/post')); | ||
trie = new Trie(); | ||
node = trie.define('/*'); | ||
assert.notStrictEqual(node, trie.define('/')); | ||
assert.notStrictEqual(node, trie.define('/post')); | ||
assert.strictEqual(node, trie.define('/(*)')); | ||
assert.throws(function() { | ||
trie.define('/(a|b)'); | ||
}, null, 'Can not define more regex pattern while "*" pattern defined'); | ||
assert.throws(function() { | ||
trie.define('/(*)/post'); | ||
}, null, 'Can not define regex pattern after "*" pattern'); | ||
}); | ||
it('trie.match', function () { | ||
it('trie.match', function() { | ||
var trie = new Trie(); | ||
@@ -53,3 +65,5 @@ | ||
match = trie.match('/post'); | ||
assert.deepEqual(match.params, {type: 'post'}); | ||
assert.deepEqual(match.params, { | ||
type: 'post' | ||
}); | ||
assert.strictEqual(node, match.node); | ||
@@ -61,3 +75,6 @@ assert.strictEqual(node, trie.match('/task').node); | ||
match = trie.match('/post/a12345'); | ||
assert.deepEqual(match.params, {type: 'post', id: 'a12345'}); | ||
assert.deepEqual(match.params, { | ||
type: 'post', | ||
id: 'a12345' | ||
}); | ||
assert.strictEqual(node, match.node); | ||
@@ -87,5 +104,11 @@ assert.strictEqual(node, trie.match('/task/aaabbb').node); | ||
assert.strictEqual(trie.define('/:type1(post|task)/[1-9a-z]{6}'), node); | ||
assert.deepEqual(trie.match('/post/a12345').params, {type: 'post', id: 'a12345'}); | ||
assert.deepEqual(trie.match('/post/a12345').params, { | ||
type: 'post', | ||
id: 'a12345' | ||
}); | ||
assert.strictEqual(trie.match('/post/a12345').node, node); | ||
assert.deepEqual(trie.match('/task/a12345').params, {type: 'task', id: 'a12345'}); | ||
assert.deepEqual(trie.match('/task/a12345').params, { | ||
type: 'task', | ||
id: 'a12345' | ||
}); | ||
assert.strictEqual(trie.match('/task/a12345').node, node); | ||
@@ -96,9 +119,19 @@ | ||
var node2 = trie.define('/:type/:id'); | ||
assert.deepEqual(trie.match('/post').params, {type: 'post'}); | ||
assert.deepEqual(trie.match('/post').params, { | ||
type: 'post' | ||
}); | ||
assert.strictEqual(trie.match('/post').node, node1); | ||
assert.deepEqual(trie.match('/task').params, {type: 'task'}); | ||
assert.deepEqual(trie.match('/task').params, { | ||
type: 'task' | ||
}); | ||
assert.strictEqual(trie.match('/task').node, node1); | ||
assert.deepEqual(trie.match('/post/123456').params, {type: 'post', id: '123456'}); | ||
assert.deepEqual(trie.match('/post/123456').params, { | ||
type: 'post', | ||
id: '123456' | ||
}); | ||
assert.strictEqual(trie.match('/post/123456').node, node2); | ||
assert.deepEqual(trie.match('/task/123456').params, {type: 'task', id: '123456'}); | ||
assert.deepEqual(trie.match('/task/123456').params, { | ||
type: 'task', | ||
id: '123456' | ||
}); | ||
assert.strictEqual(trie.match('/task/123456').node, node2); | ||
@@ -109,10 +142,22 @@ | ||
node2 = trie.define('/:type(post|task)/:id([a-z]{6})'); | ||
assert.deepEqual(trie.match('/post/aaaaaa').params, {type: 'post', id: 'aaaaaa'}); | ||
assert.deepEqual(trie.match('/post/aaaaaa').params, { | ||
type: 'post', | ||
id: 'aaaaaa' | ||
}); | ||
assert.strictEqual(trie.match('/post/aaaaaa').node, node2); | ||
assert.deepEqual(trie.match('/task/aaaaaa').params, {type: 'task', id: 'aaaaaa'}); | ||
assert.deepEqual(trie.match('/task/aaaaaa').params, { | ||
type: 'task', | ||
id: 'aaaaaa' | ||
}); | ||
assert.strictEqual(trie.match('/task/aaaaaa').node, node2); | ||
assert.strictEqual(trie.match('/task/111111'), null); | ||
assert.deepEqual(trie.match('/admin/123456').params, {user: 'admin', id: '123456'}); | ||
assert.deepEqual(trie.match('/admin/123456').params, { | ||
user: 'admin', | ||
id: '123456' | ||
}); | ||
assert.strictEqual(trie.match('/admin/123456').node, node1); | ||
assert.deepEqual(trie.match('/user/123456').params, {user: 'user', id: '123456'}); | ||
assert.deepEqual(trie.match('/user/123456').params, { | ||
user: 'user', | ||
id: '123456' | ||
}); | ||
assert.strictEqual(trie.match('/user/123456').node, node1); | ||
@@ -123,3 +168,5 @@ assert.strictEqual(trie.match('/user/aaaaaa'), null); | ||
trie.define('/post/:id([a-z]+)'); | ||
assert.deepEqual(trie.match('/post/abc').params, {id: 'abc'}); | ||
assert.deepEqual(trie.match('/post/abc').params, { | ||
id: 'abc' | ||
}); | ||
assert.strictEqual(trie.match('/post/ABC'), null); | ||
@@ -130,7 +177,83 @@ assert.strictEqual(trie.match('/Post/abc'), null); | ||
trie.define('/post/:id([a-z]+)'); | ||
assert.deepEqual(trie.match('/post/abc').params, {id: 'abc'}); | ||
assert.deepEqual(trie.match('/post/ABC').params, {id: 'ABC'}); | ||
assert.deepEqual(trie.match('/Post/abc').params, {id: 'abc'}); | ||
assert.deepEqual(trie.match('/post/abc').params, { | ||
id: 'abc' | ||
}); | ||
assert.deepEqual(trie.match('/post/ABC').params, { | ||
id: 'ABC' | ||
}); | ||
assert.deepEqual(trie.match('/Post/abc').params, { | ||
id: 'abc' | ||
}); | ||
trie = new Trie(); | ||
node = trie.define('*'); | ||
assert.strictEqual(trie.match('').node, node); | ||
assert.strictEqual(trie.match('/').node, node); | ||
assert.strictEqual(trie.match('/x').node, node); | ||
assert.strictEqual(trie.match('/x/y/z').node, node); | ||
assert.deepEqual(trie.match('/post/abc').params, {}); | ||
trie = new Trie(); | ||
node = trie.define(':all*'); | ||
assert.strictEqual(trie.define(':all(*)'), node); | ||
assert.strictEqual(trie.define('*'), node); | ||
assert.deepEqual(trie.match('').params, { | ||
all: '' | ||
}); | ||
assert.deepEqual(trie.match('/').params, { | ||
all: '' | ||
}); | ||
assert.deepEqual(trie.match('/post/abc').params, { | ||
all: 'post/abc' | ||
}); | ||
trie = new Trie(); | ||
node = trie.define('/:all*'); | ||
trie.define(''); | ||
assert.notStrictEqual(trie.define(''), node); | ||
assert.notStrictEqual(trie.match('/').node, node); | ||
assert.strictEqual(trie.match('/x').node, node); | ||
assert.deepEqual(trie.match('').params, {}); | ||
assert.deepEqual(trie.match('/').params, {}); | ||
assert.deepEqual(trie.match('/post/abc').params, { | ||
all: 'post/abc' | ||
}); | ||
trie = new Trie(); | ||
node = trie.define('/:all*'); | ||
assert.strictEqual(trie.match('').node, node); | ||
assert.strictEqual(trie.match('/').node, node); | ||
assert.strictEqual(trie.match('/x').node, node); | ||
trie = new Trie(); | ||
node = trie.define('/:type/:other(*)'); | ||
assert.strictEqual(trie.match('/post'), null); | ||
assert.strictEqual(trie.match('/post/x').node, node); | ||
trie = new Trie(); | ||
node = trie.define('/:type/:other(*)'); | ||
trie.define('/:type'); | ||
trie.define('/post'); | ||
assert.notStrictEqual(trie.define('/post'), node); | ||
assert.notStrictEqual(trie.define('/:type'), node); | ||
assert.strictEqual(trie.match('/post/abc'), null); | ||
assert.deepEqual(trie.match('').params, { | ||
type: '' | ||
}); | ||
assert.deepEqual(trie.match('/').params, { | ||
type: '' | ||
}); | ||
assert.deepEqual(trie.match('/post').params, {}); | ||
assert.deepEqual(trie.match('/task').params, { | ||
type: 'task' | ||
}); | ||
assert.deepEqual(trie.match('/task/abc').params, { | ||
type: 'task', | ||
other: 'abc' | ||
}); | ||
assert.deepEqual(trie.match('/event/x/y/z').params, { | ||
type: 'event', | ||
other: 'x/y/z' | ||
}); | ||
}); | ||
}); |
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
20703
456
95