Skip to content

Commit

Permalink
expose tokens to regexp/function methods
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeembrey committed May 12, 2015
1 parent 34bacaa commit a0397c4
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 14 deletions.
7 changes: 7 additions & 0 deletions Readme.md
Expand Up @@ -163,6 +163,13 @@ console.log(result)

**Note:** The generated function will throw on any invalid input. It will execute all necessary checks to ensure the generated path is valid. This method only works with strings.

### Working with Tokens

Path-To-RegExp exposes the two functions used internally that accept an array of tokens.

* `pathToRegexp.tokensToRegExp(tokens, options)` Transform an array of tokens into a matching regular expression.
* `pathToRegexp.tokensToFunction(tokens)` Transform an array of tokens into a path generator function.

## Compatibility with Express <= 4.x

Path-To-RegExp breaks compatibility with Express <= 4.x in a few ways:
Expand Down
59 changes: 45 additions & 14 deletions index.js
Expand Up @@ -6,6 +6,8 @@ var isarray = require('isarray')
module.exports = pathToRegexp
module.exports.parse = parse
module.exports.compile = compile
module.exports.tokensToFunction = tokensToFunction
module.exports.tokensToRegExp = tokensToRegExp

/**
* The main path matching regexp utility.
Expand Down Expand Up @@ -96,12 +98,20 @@ function parse (str) {
* @return {Function}
*/
function compile (str) {
var keys = parse(str)
return tokensToFunction(parse(str))
}

/**
* Expose a method for transforming tokens into the path function.
*/
function tokensToFunction (tokens) {
// Compile all the tokens into regexps.
var matches = new Array(tokens.length)

// Compile all the patterns before compilation.
for (var i = 0; i < keys.length; i++) {
if (typeof keys[i] === 'object') {
keys[i].regexp = new RegExp('^' + keys[i].pattern + '$')
for (var i = 0; i < tokens.length; i++) {
if (typeof tokens[i] === 'object') {
matches[i] = new RegExp('^' + tokens[i].pattern + '$')
}
}

Expand All @@ -110,8 +120,8 @@ function compile (str) {

obj = obj || {}

for (var i = 0; i < keys.length; i++) {
var key = keys[i]
for (var i = 0; i < tokens.length; i++) {
var key = tokens[i]

if (typeof key === 'string') {
path += key
Expand Down Expand Up @@ -143,7 +153,7 @@ function compile (str) {
}

for (var j = 0; j < value.length; j++) {
if (!key.regexp.test(value[j])) {
if (!matches[i].test(value[j])) {
throw new TypeError('Expected all "' + key.name + '" to match "' + key.pattern + '"')
}

Expand All @@ -153,7 +163,7 @@ function compile (str) {
continue
}

if (!key.regexp.test(value)) {
if (!matches[i].test(value)) {
throw new TypeError('Expected "' + key.name + '" to match "' + key.pattern + '"')
}

Expand Down Expand Up @@ -262,11 +272,35 @@ function arrayToRegexp (path, keys, options) {
* @return {RegExp}
*/
function stringToRegexp (path, keys, options) {
var tokens = parse(path)
var re = tokensToRegExp(tokens, options)

// Attach keys back to the regexp.
for (var i = 0; i < tokens.length; i++) {
if (typeof tokens[i] !== 'string') {
keys.push(tokens[i])
}
}

return attachKeys(re, keys)
}

/**
* Expose a function for taking tokens and returning a RegExp.
*
* @param {Array} tokens
* @param {Array} keys
* @param {Object} options
* @return {RegExp}
*/
function tokensToRegExp (tokens, options) {
options = options || {}

var strict = options.strict
var end = options.end !== false
var route = ''
var endsWithSlash = path.charAt(path.length - 1) === '/'
var tokens = parse(path)
var lastToken = tokens[tokens.length - 1]
var endsWithSlash = typeof lastToken === 'string' && /\/$/.test(lastToken)

// Iterate over the tokens and create our regexp string.
for (var i = 0; i < tokens.length; i++) {
Expand All @@ -278,9 +312,6 @@ function stringToRegexp (path, keys, options) {
var prefix = escapeString(token.prefix)
var capture = token.pattern

// Push non-string tokens into the keys array.
keys.push(token)

if (token.repeat) {
capture += '(?:' + prefix + capture + ')*'
}
Expand Down Expand Up @@ -315,7 +346,7 @@ function stringToRegexp (path, keys, options) {
route += strict && endsWithSlash ? '' : '(?=\\/|$)'
}

return attachKeys(new RegExp('^' + route, flags(options)), keys)
return new RegExp('^' + route, flags(options))
}

/**
Expand Down
16 changes: 16 additions & 0 deletions test.js
Expand Up @@ -1647,6 +1647,22 @@ describe('path-to-regexp', function () {
})
})

describe('tokens', function () {
var tokens = pathToRegexp.parse(TEST_PATH)

it('should expose method to compile tokens to regexp', function () {
var re = pathToRegexp.tokensToRegExp(tokens)

expect(exec(re, '/user/123')).to.deep.equal(['/user/123', '123'])
})

it('should expose method to compile tokens to a path function', function () {
var fn = pathToRegexp.tokensToFunction(tokens)

expect(fn({ id: 123 })).to.equal('/user/123')
})
})

describe('rules', function () {
TESTS.forEach(function (test) {
var path = test[0]
Expand Down

0 comments on commit a0397c4

Please sign in to comment.