|
function encodeReserved(str) { |
|
return str.split(/(%[0-9A-Fa-f]{2})/g).map(function(part) { |
|
if (!/%[0-9A-Fa-f]/.test(part)) { |
|
part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]"); |
|
} |
|
return part; |
|
}).join(""); |
|
} |
|
function encodeUnreserved(str) { |
|
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { |
|
return "%" + c.charCodeAt(0).toString(16).toUpperCase(); |
|
}); |
|
} |
|
function encodeValue(operator, value, key) { |
|
value = operator === "+" || operator === "#" ? encodeReserved(value) : encodeUnreserved(value); |
|
if (key) { |
|
return encodeUnreserved(key) + "=" + value; |
|
} else { |
|
return value; |
|
} |
|
} |
|
function isDefined(value) { |
|
return value !== void 0 && value !== null; |
|
} |
|
function isKeyOperator(operator) { |
|
return operator === ";" || operator === "&" || operator === "?"; |
|
} |
|
function getValues(context, operator, key, modifier) { |
|
var value = context[key], result = []; |
|
if (isDefined(value) && value !== "") { |
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { |
|
value = value.toString(); |
|
if (modifier && modifier !== "*") { |
|
value = value.substring(0, parseInt(modifier, 10)); |
|
} |
|
result.push( |
|
encodeValue(operator, value, isKeyOperator(operator) ? key : "") |
|
); |
|
} else { |
|
if (modifier === "*") { |
|
if (Array.isArray(value)) { |
|
value.filter(isDefined).forEach(function(value2) { |
|
result.push( |
|
encodeValue(operator, value2, isKeyOperator(operator) ? key : "") |
|
); |
|
}); |
|
} else { |
|
Object.keys(value).forEach(function(k) { |
|
if (isDefined(value[k])) { |
|
result.push(encodeValue(operator, value[k], k)); |
|
} |
|
}); |
|
} |
|
} else { |
|
const tmp = []; |
|
if (Array.isArray(value)) { |
|
value.filter(isDefined).forEach(function(value2) { |
|
tmp.push(encodeValue(operator, value2)); |
|
}); |
|
} else { |
|
Object.keys(value).forEach(function(k) { |
|
if (isDefined(value[k])) { |
|
tmp.push(encodeUnreserved(k)); |
|
tmp.push(encodeValue(operator, value[k].toString())); |
|
} |
|
}); |
|
} |
|
if (isKeyOperator(operator)) { |
|
result.push(encodeUnreserved(key) + "=" + tmp.join(",")); |
|
} else if (tmp.length !== 0) { |
|
result.push(tmp.join(",")); |
|
} |
|
} |
|
} |
|
} else { |
|
if (operator === ";") { |
|
if (isDefined(value)) { |
|
result.push(encodeUnreserved(key)); |
|
} |
|
} else if (value === "" && (operator === "&" || operator === "?")) { |
|
result.push(encodeUnreserved(key) + "="); |
|
} else if (value === "") { |
|
result.push(""); |
|
} |
|
} |
|
return result; |
|
} |
|
function parseUrl(template) { |
|
return { |
|
expand: expand.bind(null, template) |
|
}; |
|
} |
|
function expand(template, context) { |
|
var operators = ["+", "#", ".", "/", ";", "?", "&"]; |
|
return template.replace( |
|
/\{([^\{\}]+)\}|([^\{\}]+)/g, |
|
function(_, expression, literal) { |
|
if (expression) { |
|
let operator = ""; |
|
const values = []; |
|
if (operators.indexOf(expression.charAt(0)) !== -1) { |
|
operator = expression.charAt(0); |
|
expression = expression.substr(1); |
|
} |
|
expression.split(/,/g).forEach(function(variable) { |
|
var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable); |
|
values.push(getValues(context, operator, tmp[1], tmp[2] || tmp[3])); |
|
}); |
|
if (operator && operator !== "+") { |
|
var separator = ","; |
|
if (operator === "?") { |
|
separator = "&"; |
|
} else if (operator !== "#") { |
|
separator = operator; |
|
} |
|
return (values.length !== 0 ? operator : "") + values.join(separator); |
|
} else { |
|
return values.join(","); |
|
} |
|
} else { |
|
return encodeReserved(literal); |
|
} |
|
} |
|
); |
|
} |
|
export { |
|
parseUrl |
|
}; |
|
|