extract-params

Extract parameters from a string based on a pattern

Usage no npm install needed!

<script type="module">
  import extractParams from 'https://cdn.skypack.dev/extract-params';
</script>

README

Build Status Pull Requests stats NPM Downloads NPM Version

Extract Params

Installation

npm install extract-params --save

Then, in your app:

var extractParams = require('extract-params').extractParams;
// or
var extractParamsInFirstMatch = require('extract-params').extractParamsInFirstMatch;

API

extractParams(str, pattern)

Tests whether str matches the given parameterized pattern. If match is successful, it returns a hash of parameters and their values. Otherwise, extractParams returns null.

The match is considered successful only if str matches the pattern at the start and at the end (see examples 2 and 3 below).

Example 1

var params = extractParams(
  '/users/123/friends/456/photo',
  '/users/:userId/friends/:friendId/photo'
);

/* 
  Returns:
    {
      userId: '123',
      friendId: '456'
    }
*/

Example 2

var params = extractParams(
  '/home/users/123',
  '/users/:userId'
);

/* 
  Returns:
    null
      
  because `str` doesn't match the `pattern` at the start.
*/

Example 3

var params = extractParams(
  '/users/123/friends/456',
  '/users/:userId/friends'
);

/* 
  Returns:
    null
      
  because `str` doesn't match the `pattern` at the end.
*/

Example 4

var params = extractParams(
  '/USERS/123/Friends/456/photo',
  '/users/:userId/friends/:friendId/photo'
);

/* 
  Returns:
    null
    
  because the pattern is case sensitive by default
*/

Example 5

var params = extractParams(
  '/USERS/123/Friends/456/photo',
  {
    pattern: '/users/:userId/friends/:friendId/photo',
    caseSensitive: false
  }
);

/* 
  Returns:
    {
      userId: '123',
      friendId: '456'
    }
*/

Example 6

function lowercaseValues(params) {
  return Object.keys(params).reduce(function(result, param) {
    result[param] = params[param].toLowerCase();
    return result;
  }, {});
}

var params = extractParams(
  '/users/Misha/friends/MARK/photo',
  {
    pattern: '/users/:user/friends/:friend/photo',
    transform: lowercaseValues
  }
);

/* 
  Returns:
    {
      user: 'misha',
      friend: 'mark'
    }
*/

Example 7

var companyRegex = /^[a-zA-Z]+$/;
var employeeRegex = /^[a-z-]+$/;

function validator(params) {
  return typeof params.company === 'string' && companyRegex.test(params.company) &&
         typeof params.employee === 'string' && employeeRegex.test(params.employee) ? params : null;
}

var params = extractParams(
  '/companies/Yahoo7/employees/david-brown',
  {
    pattern: '/companies/:company/employees/:employee',
    transform: validator
  }
);

/* 
  Returns:
    null
    
  because 'Yahoo7' contains a number
*/

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 index and its parameters.

Example 1

var params = extractParamsInFirstMatch(
  '/users/123',
  [
    { pattern: '/users/:userId/friends/:friendId/photo' },
    { pattern: '/users/:userId/friends/:friendId' },
    { pattern: '/users/:userId/friends' },
    { pattern: '/users/:userId' },
    { pattern: '/users' }
  ]
);

/* 
  Returns:
    {
      patternIndex: 3,
      params: {
        userId: '123'
      }
    }
*/

Example 2

var params = extractParamsInFirstMatch(
  '/users/123/subscriptions',
  [
    { pattern: '/users/:userId/friends/:friendId/photo' },
    { pattern: '/users/:userId/friends/:friendId' },
    { pattern: '/users/:userId/friends' },
    { pattern: '/users/:userId' },
    { pattern: '/users' }
  ]
);

/* 
  Returns:
    null
    
  because none of the patterns match.
*/

Example 3

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
*/

Patterns

The functions in this library operate on a pattern type.

Basic patterns

In its simplest form, pattern is just a string, e.g. /users.

Patterns can have parameters, e.g. /users/:userId/friends/:friendId/photo.

Parameters must start with a :, and can contain letters only. Therefore, :username, :userName, and :USERNAME are valid parameters, but :user-name, :user_name and :iphone6 are not.

Advanced patterns

For more advanced patterns, an object with the following keys can be provided:

  • pattern - (required) The pattern string.
  • caseSensitive - (optional) Boolean indicating whether the pattern is considered case sensitive or not. Example
    Defaults to true.
  • transform - (optional) Function that takes the extracted params, and returns a manipulated version of them. Example
    If it returns null, the match fails. Example
    Defaults to the identity function.

Running Tests

npm test

License

MIT