| 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 = ["+", "#", ".", "/", ";", "?", "&"]; |
| template = 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); |
| } |
| } |
| ); |
| if (template === "/") { |
| return template; |
| } else { |
| return template.replace(/\/$/, ""); |
| } |
| } |
| export { |
| parseUrl |
| }; |