path-params
Version:
Replace path params based on express route notation
108 lines (91 loc) • 3.04 kB
JavaScript
/*! path-params - MIT License - https://github.com/h2non/path-params */
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['exports'], factory)
} else if (typeof exports === 'object') {
factory(exports)
if (typeof module === 'object' && module !== null) {
module.exports = exports = exports.pathParams
}
} else {
factory(root)
}
}(this, function (exports) {
'use strict'
// Originally taken from pillarjs/path-to-regexp package:
var PATH_REGEXP = new RegExp([
// Match escaped characters that would otherwise appear in future matches.
// This allows the user to escape special characters that won't transform.
'(\\\\.)',
// Match Express-style parameters and un-named parameters with a prefix
// and optional suffixes. Matches appear as:
//
// "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined]
// "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined]
// "/*" => ["/", undefined, undefined, undefined, undefined, "*"]
'([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^()])+)\\))?|\\(((?:\\\\.|[^()])+)\\))([+*?])?|(\\*))'
].join('|'), 'g')
function pathParams (path, params) {
return parse(path).reduce(function (path, token) {
if (path instanceof Error) return path
if (typeof token === 'string') return path
var value = params[token.name]
if (value == null) {
return new Error('Missing path param: ' + token.name)
}
var type = typeof value
if (type !== 'string' && type !== 'number') {
return new Error('Invalid type for path param: ' + token.name + ' = ' + type)
}
var replace = new RegExp(':' + token.name, 'g')
return path.replace(replace, value)
}, path)
}
function parse (str) {
var tokens = []
var key = 0
var index = 0
var path = ''
var res
while ((res = PATH_REGEXP.exec(str)) != null) {
var m = res[0]
var escaped = res[1]
var offset = res.index
path += str.slice(index, offset)
index = offset + m.length
// Ignore already escaped sequences.
if (escaped) {
path += escaped[1]
continue
}
// Push the current path onto the tokens.
if (path) {
tokens.push(path)
path = ''
}
var prefix = res[2]
var name = res[3]
var suffix = res[6]
var repeat = suffix === '+' || suffix === '*'
var optional = suffix === '?' || suffix === '*'
var delimiter = prefix || '/'
tokens.push({
name: name || key++,
prefix: prefix || '',
delimiter: delimiter,
optional: optional,
repeat: repeat
})
}
// Match any characters still remaining.
if (index < str.length) {
path += str.substr(index)
}
// If the path exists, push it onto the end.
if (path) {
tokens.push(path)
}
return tokens
}
exports.pathParams = pathParams
}))