| 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 | |
| }; | |