extract-params
Advanced tools
Comparing version 1.0.0 to 2.0.0
@@ -8,6 +8,17 @@ var paramRegex = /:[a-zA-Z]+/g; | ||
module.exports = function extractParams(str, pattern) { | ||
function identity(params) { | ||
return params; | ||
} | ||
module.exports = function extractParams(str, pattern, transform) { | ||
if (typeof transform === 'undefined') { | ||
transform = identity; | ||
} else if (typeof transform !== 'function') { | ||
throw new Error('\'transform\' must be a function'); | ||
return null; | ||
} | ||
var valuesRegex = new RegExp('^' + pattern.split(paramRegex).map(function(patternPart) { | ||
return escapeRegexCharacters(patternPart); | ||
}).join('(.+)')); | ||
}).join('(.+)') + '$'); | ||
@@ -23,3 +34,3 @@ var valuesMatch = str.match(valuesRegex); | ||
if (paramsMatch === null) { | ||
return {}; | ||
return transform({}); | ||
} | ||
@@ -31,6 +42,6 @@ | ||
return valuesMatch.slice(1).reduce(function(result, value, index) { | ||
return transform(valuesMatch.slice(1).reduce(function(result, value, index) { | ||
result[params[index]] = value; | ||
return result; | ||
}, {}); | ||
}, {})); | ||
}; |
@@ -7,7 +7,7 @@ var extractParams = require('./extractParams'); | ||
for (var i = 0; i < patternsCount; i++) { | ||
var params = extractParams(str, patterns[i]); | ||
var params = extractParams(str, patterns[i].pattern, patterns[i].transform); | ||
if (params !== null) { | ||
return { | ||
pattern: patterns[i], | ||
patternIndex: i, | ||
params: params | ||
@@ -14,0 +14,0 @@ }; |
{ | ||
"name": "extract-params", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"description": "Extract parameters from a string based on a pattern", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -32,10 +32,12 @@ <a href="https://codeship.com/projects/119982" target="_blank"> | ||
* [`extractParams(str, pattern)`](#extractParams) | ||
* [`extractParams(str, pattern, transform)`](#extractParams) | ||
* [`extractParamsInFirstMatch(str, patterns)`](#extractParamsInFirstMatch) | ||
<a name="extractParams"></a> | ||
### extractParams(str, pattern) | ||
### extractParams(str, pattern, transform) | ||
Tests whether `str` matches the given parameterized `pattern`, and returns a key-value object of parameters and their values in case of a successful match. | ||
An optional `transform` function can be passed to manipulate the extracted params. If `transform` returns `null`, the match fails. `transform` can be used, for example, to lowercase the values in `params`, or to validate them (return `null` if validation fails). | ||
`pattern` parameters must be in the following format: `:camelCase` | ||
@@ -81,6 +83,27 @@ | ||
#### Example 3 | ||
```js | ||
var params = extractParams( | ||
'/users/1234/friends/456/photo', | ||
'/users/:userId/friends/:friendId/photo', | ||
function(params) { | ||
var userId = parseInt(params.userId, 10); | ||
return userId >= 1 && userId <= 999 ? params : null; | ||
} | ||
); | ||
/* | ||
Returns: | ||
null | ||
because userId > 999 | ||
*/ | ||
``` | ||
<a name="extractParamsInFirstMatch"></a> | ||
### extractParamsInFirstMatch(str, patterns) | ||
Tests whether `str` matches one of the parameterized `patterns`. If none of the `patterns` match, `extractParamsInFirstMatch` returns `null`. Otherwise, it returns the matching pattern and its parameters. | ||
Tests whether `str` matches one of the parameterized `patterns`. Every pattern can have an optional `transform` function. If none of the `patterns` match, `extractParamsInFirstMatch` returns `null`. Otherwise, it returns the matching pattern index and its parameters. | ||
@@ -93,7 +116,7 @@ #### Example 1 | ||
[ | ||
'/users/:userId/friends/:friendId/photo', | ||
'/users/:userId/friends/:friendId', | ||
'/users/:userId/friends', | ||
'/users/:userId', | ||
'/users' | ||
{ pattern: '/users/:userId/friends/:friendId/photo' }, | ||
{ pattern: '/users/:userId/friends/:friendId' }, | ||
{ pattern: '/users/:userId/friends' }, | ||
{ pattern: '/users/:userId' }, | ||
{ pattern: '/users' } | ||
] | ||
@@ -105,3 +128,3 @@ ); | ||
{ | ||
pattern: '/users/:userId', | ||
patternIndex: 3, | ||
params: { | ||
@@ -120,7 +143,7 @@ userId: '123' | ||
[ | ||
'/users/:userId/friends/:friendId/photo', | ||
'/users/:userId/friends/:friendId', | ||
'/users/:userId/friends', | ||
'/users/:userId', | ||
'/users' | ||
{ pattern: '/users/:userId/friends/:friendId/photo' }, | ||
{ pattern: '/users/:userId/friends/:friendId' }, | ||
{ pattern: '/users/:userId/friends' }, | ||
{ pattern: '/users/:userId' }, | ||
{ pattern: '/users' } | ||
] | ||
@@ -137,3 +160,39 @@ ); | ||
#### Example 3 | ||
```js | ||
function userIdValidator(params) { | ||
if (!('userId' in params)) { | ||
return params; | ||
} | ||
// Without this check, '/users/1234/friends/567' would match '/users/:userId' | ||
// with { userId: '1234/friends/567' } | ||
if (!(/^\d+$/.test(params.userId))) { | ||
return null; | ||
} | ||
var userId = parseInt(params.userId, 10); | ||
return userId >= 1 && userId <= 999 ? params : null; | ||
} | ||
var params = extractParamsInFirstMatch( | ||
'/users/1234/friends/567', | ||
[ | ||
{ pattern: '/users/:userId/friends/:friendId/photo', transform: userIdValidator }, | ||
{ pattern: '/users/:userId/friends/:friendId', transform: userIdValidator }, | ||
{ pattern: '/users/:userId/friends', transform: userIdValidator }, | ||
{ pattern: '/users/:userId', transform: userIdValidator }, | ||
{ pattern: '/users' } | ||
] | ||
); | ||
/* | ||
Returns: | ||
null | ||
because userId > 999 | ||
*/ | ||
``` | ||
## Running Tests | ||
@@ -140,0 +199,0 @@ |
@@ -18,2 +18,8 @@ var expect = require('chai').expect; | ||
{ | ||
should: 'return null if there is match but not at the end', | ||
str: 'language-elm-is-awesome', | ||
pattern: 'language-:lang-is', | ||
result: null | ||
}, | ||
{ | ||
should: 'return {} if there is match but the pattern has no parameters', | ||
@@ -25,2 +31,21 @@ str: 'react-is-awesome', | ||
{ | ||
should: 'return use the transform function if there is match but the pattern has no parameters', | ||
str: 'react-is-awesome', | ||
pattern: 'react-is-awesome', | ||
transform: function(params) { | ||
var newParams = { | ||
mood: 'awesome' | ||
}; | ||
for (var param in params) { | ||
newParams[param] = params[param]; | ||
} | ||
return newParams; | ||
}, | ||
result: { | ||
mood: 'awesome' | ||
} | ||
}, | ||
{ | ||
should: 'extract single parameter', | ||
@@ -50,2 +75,31 @@ str: 'my-name-is-Misha', | ||
} | ||
}, | ||
{ | ||
should: 'transform the extracted params using the transform function', | ||
str: '/users/123/friends/456/photo', | ||
pattern: '/users/:userId/friends/:friendId/photo', | ||
transform: function(params) { | ||
var newParams = {}; | ||
for (var param in params) { | ||
newParams[param] = '**' + params[param] + '**'; | ||
} | ||
return newParams; | ||
}, | ||
result: { | ||
userId: '**123**', | ||
friendId: '**456**' | ||
} | ||
}, | ||
{ | ||
should: 'fail the match if the transform function returns null', | ||
str: '/users/1234/friends/456/photo', | ||
pattern: '/users/:userId/friends/:friendId/photo', | ||
transform: function(params) { | ||
var userId = parseInt(params.userId, 10); | ||
return userId >= 1 && userId <= 999 ? params : null; | ||
}, | ||
result: null | ||
} | ||
@@ -57,5 +111,5 @@ ]; | ||
it(testCase.should, function() { | ||
expect(extractParams(testCase.str, testCase.pattern)).to.deep.equal(testCase.result); | ||
expect(extractParams(testCase.str, testCase.pattern, testCase.transform)).to.deep.equal(testCase.result); | ||
}); | ||
}); | ||
}); |
var expect = require('chai').expect; | ||
var extractParamsInFirstMatch = require('../lib/extractParamsInFirstMatch'); | ||
function userIdValidator(params) { | ||
if (!('userId' in params)) { | ||
return params; | ||
} | ||
// Without this check, '/users/1234/friends/567' would match '/users/:userId' | ||
// with { userId: '1234/friends/567' } | ||
if (!(/^\d+$/.test(params.userId))) { | ||
return null; | ||
} | ||
var userId = parseInt(params.userId, 10); | ||
return userId >= 1 && userId <= 999 ? params : null; | ||
} | ||
var testCases = [ | ||
@@ -15,5 +31,5 @@ { | ||
patterns: [ | ||
'he-said-that-:language-is-:description', | ||
'/user/:userId/friends/:friendId', | ||
':who-knows-that-:language-is-great' | ||
{ pattern: 'he-said-that-:language-is-:description' }, | ||
{ pattern: '/user/:userId/friends/:friendId' }, | ||
{ pattern: ':who-knows-that-:language-is-great' } | ||
], | ||
@@ -26,10 +42,10 @@ result: null | ||
patterns: [ | ||
'/users/:userId/friends/:friendId/photo', | ||
'/users/:userId/friends/:friendId', | ||
'/users/:userId/friends', | ||
'/users/:userId', | ||
'/users' | ||
{ pattern: '/users/:userId/friends/:friendId/photo' }, | ||
{ pattern: '/users/:userId/friends/:friendId' }, | ||
{ pattern: '/users/:userId/friends' }, | ||
{ pattern: '/users/:userId' }, | ||
{ pattern: '/users' } | ||
], | ||
result: { | ||
pattern: '/users/:userId', | ||
patternIndex: 3, | ||
params: { | ||
@@ -39,2 +55,14 @@ userId: '123' | ||
} | ||
}, | ||
{ | ||
should: 'use the transform function to return the first match', | ||
str: '/users/1234/friends/456', | ||
patterns: [ | ||
{ pattern: '/users/:userId/friends/:friendId/photo', transform: userIdValidator }, | ||
{ pattern: '/users/:userId/friends/:friendId', transform: userIdValidator }, | ||
{ pattern: '/users/:userId/friends', transform: userIdValidator }, | ||
{ pattern: '/users/:userId', transform: userIdValidator }, | ||
{ pattern: '/users' } | ||
], | ||
result: null | ||
} | ||
@@ -41,0 +69,0 @@ ]; |
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
13121
226
201