page-path-builder
Version:
Uses a page.js-style routing string to build up a path you can link to
58 lines (46 loc) • 1.58 kB
JavaScript
var parser = require('./path-parser')
var stringifyQuerystring = require('query-string').stringify
module.exports = function(pathStr, parameters) {
var parsed = typeof pathStr === 'string' ? parser(pathStr) : pathStr
var allTokens = parsed.allTokens
var regex = parsed.regex
if (parameters) {
var path = allTokens.map(function(bit) {
if (bit.string) {
return bit.string
}
var defined = typeof parameters[bit.name] !== 'undefined'
if (!bit.optional && !defined) {
throw new Error('Must supply argument ' + bit.name + ' for path ' + pathStr)
}
return defined ? (bit.delimiter + encodeURIComponent(parameters[bit.name])) : ''
}).join('')
if (!regex.test(path)) {
throw new Error('Provided arguments do not match the original arguments')
}
return buildPathWithQuerystring(path, parameters, allTokens)
} else {
return parsed
}
}
function buildPathWithQuerystring(path, parameters, tokenArray) {
var parametersInQuerystring = getParametersWithoutMatchingToken(parameters, tokenArray)
if (Object.keys(parametersInQuerystring).length === 0) {
return path
}
return path + '?' + stringifyQuerystring(parametersInQuerystring)
}
function getParametersWithoutMatchingToken(parameters, tokenArray) {
var tokenHash = tokenArray.reduce(function(memo, bit) {
if (!bit.string) {
memo[bit.name] = bit
}
return memo
}, {})
return Object.keys(parameters).filter(function(param) {
return !tokenHash[param]
}).reduce(function(newParameters, param) {
newParameters[param] = parameters[param]
return newParameters
}, {})
}