Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

route-trie

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

route-trie - npm Package Compare versions

Comparing version 0.2.1 to 1.0.0

2

bower.json

@@ -7,3 +7,3 @@ {

],
"version": "0.2.1",
"version": "1.0.0",
"main": "index.js",

@@ -10,0 +10,0 @@ "repository": {

@@ -7,3 +7,3 @@ {

],
"version": "0.2.1",
"version": "1.0.0",
"main": "index.js",

@@ -10,0 +10,0 @@ "repository": {

@@ -28,3 +28,5 @@ // **Github:** https://github.com/zensh/route-trie

Trie.prototype.define = function(pattern) {
if (typeof pattern !== 'string') throw new TypeError('Only strings can be defined.');
if (typeof pattern !== 'string')
throw new TypeError('Only strings can be defined.');
var _pattern = pattern

@@ -37,6 +39,7 @@ .replace(multiSlashReg, '\/')

if (node._nodeState.pattern == null) node._nodeState.pattern = pattern;
return node;
};
Trie.prototype.match = function(path) {
Trie.prototype.match = function(path, multiMatch) {
// the path should be normalized before match, just as path.normalize do in Node.js

@@ -46,37 +49,22 @@ path = path

.replace(trimSlashReg, '');
var frag = '';
var node = this.root;
var frags = path.split('/');
var result = {
params: {},
node: null
};
var node = this.root;
var child = null;
var frag = '';
var result = {params: {}};
if (multiMatch) result.nodes = [];
while (frags.length) {
frag = safeDecodeURIComponent(frags.shift());
if (frag === false) return null;
child = node._nodeState.childNodes[this.flags ? frag.toLowerCase() : frag];
if (!child) {
for (var i = 0, len = node._nodeState.regexChildNodes.length; i < len; i++) {
var regex = node._nodeState.regexChildNodes[i];
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;
child = regex[0];
break;
}
node = matchNode(node, frags, result.params, this.flags);
if (node) {
if (multiMatch && node._nodeState.endpoint) result.nodes.push(node);
continue;
}
if (!child) return null;
node = child;
if (!multiMatch) return null;
break;
}
if (multiMatch) return result;
if (!node._nodeState.endpoint) return null;
result.node = node;

@@ -115,2 +103,28 @@ return result;

function matchNode(node, frags, params, flags) {
var frag = safeDecodeURIComponent(frags.shift());
if (frag === false) return null;
var nodeState = node._nodeState;
var child = nodeState.childNodes[flags ? frag.toLowerCase() : frag];
if (child) return child;
for (var i = 0, len = nodeState.regexChildNodes.length; i < len; i++) {
var regex = nodeState.regexChildNodes[i];
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]) params[regex[1]] = frag;
child = regex[0];
break;
}
return child;
}
function parseNode(parentNode, frag, flags) {

@@ -146,5 +160,5 @@ var node = null;

if (regexNames[frag] >= 0) node = regexChildNodes[regexNames[frag]][0];
else if (lastRegexChildNode && lastRegexChildNode._nodeState.matchRemaining) {
else if (lastRegexChildNode && lastRegexChildNode._nodeState.matchRemaining)
throw new Error('Can not define more regex pattern while "*" pattern defined');
} else {
else {
node = new Node(frag, matchRemaining);

@@ -176,4 +190,4 @@ regexChildNodes.push([node, parameter, frag && new RegExp(frag, flags)]);

Trie.NAME = 'Trie';
Trie.VERSION = 'v0.2.1';
Trie.VERSION = 'v1.0.0';
return Trie;
}));

@@ -7,3 +7,3 @@ {

],
"version": "0.2.1",
"version": "1.0.0",
"main": "index.js",

@@ -10,0 +10,0 @@ "repository": {

@@ -8,3 +8,3 @@ route-trie

### [trie](http://en.wikipedia.org/wiki/Trie)
### About [trie](http://en.wikipedia.org/wiki/Trie)

@@ -39,7 +39,11 @@ ### [Trie-based request routing](http://blog.vulcanproxy.com/trie-based-http-requests-routing/)

npm install route-trie
```sh
npm install route-trie
```
**Bower:**
bower install route-trie
```sh
bower install route-trie
```

@@ -54,10 +58,11 @@ ## API

`flagI`: `Boolean`, default `false`, ignore case.
Create a trie.
```js
var trie = new Trie();
```
- `flagI`: {Boolean}, default `false`, ignore case
return `trie` object.
```js
var trie = new Trie(true); // ignore case for match
var trie1 = new Trie();
var trie2 = new Trie(true); // ignore case for match
```

@@ -67,2 +72,16 @@

Define a `node` for the `pattern`, The same pattern will always return the same `node`. The result `node`, will be an emtpy object, it has a private and not enumerable property `_nodeState`. `_nodeState` is a object that have `name`, `pattern`, `childNodes` and so on. You can mount properties and methods on the `node`, but not on `_nodeState`.
- `pattern`: {String}, each fragment of the pattern, delimited by a `/`, can have the following signature:
- `string` - ex `/post`
- `string|string` - `|` separated strings, ex `/post|task`
- `:name` - Wildcard route matched to a name, ex `/:type`
- `(regex)` - A regular expression match without saving the parameter (not recommended), ex `/(post|task)`, `/([a-z0-9]{6})`
- `: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`...
return a `node` object.
```js

@@ -77,30 +96,30 @@ var node = trie.define('/:type/:id([a-z0-9]{6})');

The result `node`, will be an emtpy object, it has a private and not enumerable property `_nodeState`.
### Trie.prototype.match(path[, multiMatch])
Each fragment of the pattern, delimited by a `/`, can have the following signature:
- `path`: {String}, URL pathname to match and get the defined `node`
- `multiMatch`: {Boolean}, *Optional*, default: `false`. If true, a path maybe matched one more `node`s.
- `string` - ex `/post`
- `string|string` - `|` separated strings, ex `/post|task`
- `:name` - Wildcard route matched to a name, ex `/:type`
- `(regex)` - A regular expression match without saving the parameter (not recommended), ex `/(post|task)`, `/([a-z0-9]{6})`
- `: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`...
Return `matched` object:
### Trie.prototype.match(path)
- **Default mode**: return `null` if no node matched, otherwise return an object with the following properties:
```js
var match = trie.match('/post');
// assert(match === null);
- `params`: {Object}, A list of named parameters, ex, `match.params.id === 'abc123'`.
- `node`: {Object}, The matched node.
match = trie.match('/post/abc123');
// assert(match.node === trie.define('/:type/:id([a-z0-9]{6}'));
// assert.deepEqual(match.params, {type: 'post', id: 'abc123'})
```
```js
var node = trie.define('/:type/:id([a-z0-9]{6}');
var match = trie.match('/post');
// assert(match === null);
The result `match`, unless `null`, will be an object with the following properties:
match = trie.match('/post/abc123');
// assert(match.node === node);
// assert.deepEqual(match.params, {type: 'post', id: 'abc123'})
```
- `params` - A list of named parameters, ex, `match.params.id === 'abc123'`.
- `node` - The matched node.
- **multiMatch mode**: will always return an object with the following properties:
- `params`: {Object}, A list of named parameters.
- `nodes`: {Array}, if no node matched, it will be a empty array, otherwise will be a array of matched nodes.
[npm-url]: https://npmjs.org/package/route-trie

@@ -107,0 +126,0 @@ [npm-image]: http://img.shields.io/npm/v/route-trie.svg

@@ -252,2 +252,40 @@ 'use strict';

});
it('trie.match, multiMatch', function() {
var trie = new Trie();
var node1 = trie.define('/');
var node2 = trie.define('/:type');
var node3 = trie.define('/:type/:id([a-z0-9]{6}');
var match = trie.match('/', true);
assert.strictEqual(match.nodes.length, 1);
assert.strictEqual(match.nodes[0], node1);
assert.deepEqual(match.params, {});
// should not match node1(root node)!
match = trie.match('/post', true);
assert.strictEqual(match.nodes.length, 1);
assert.strictEqual(match.nodes[0], node2);
assert.deepEqual(match.params, {type: 'post'});
match = trie.match('/post/abcdef', true);
assert.strictEqual(match.nodes.length, 2);
assert.strictEqual(match.nodes[0], node2);
assert.strictEqual(match.nodes[1], node3);
assert.deepEqual(match.params, {type: 'post', id: 'abcdef'});
match = trie.match('/post/abcdef/xyz', true);
assert.strictEqual(match.nodes.length, 2);
assert.strictEqual(match.nodes[0], node2);
assert.strictEqual(match.nodes[1], node3);
assert.deepEqual(match.params, {type: 'post', id: 'abcdef'});
match = trie.match('/post/abcdef/xyz/123', true);
assert.strictEqual(match.nodes.length, 2);
assert.strictEqual(match.nodes[0], node2);
assert.strictEqual(match.nodes[1], node3);
assert.deepEqual(match.params, {type: 'post', id: 'abcdef'});
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc