UNPKG

mozu-node-sdk

Version:

Mozu JavaScript SDK for Node.js and Arc.js environments

173 lines (155 loc) 4.65 kB
/* eslint complexity:0 */ 'use strict' /** * @constructor */ ; function UrlTemplate() {} /** * @private * @param {string} str * @return {string} */ UrlTemplate.prototype.encodeReserved = function (str) { return str.split(/(%[0-9A-Fa-f]{2})/g).map(function (part) { if (!/%[0-9A-Fa-f]/.test(part)) { part = encodeURI(part); } return part; }).join(''); }; /** * @private * @param {string} operator * @param {string} value * @param {string} key * @return {string} */ UrlTemplate.prototype.encodeValue = function (operator, value, key) { if (operator !== '+') { value = operator === '#' ? this.encodeReserved(value) : encodeURIComponent(value); } if (key) { return encodeURIComponent(key) + '=' + value; } else { return value; } }; /** * @private * @param {*} value * @return {boolean} */ UrlTemplate.prototype.isDefined = function (value) { return value !== undefined && value !== null; }; /** * @private * @param {string} * @return {boolean} */ UrlTemplate.prototype.isKeyOperator = function (operator) { return operator === ';' || operator === '&' || operator === '?'; }; /** * @private * @param {Object} context * @param {string} operator * @param {string} key * @param {string} modifier */ UrlTemplate.prototype.getValues = function (context, operator, key, modifier) { var value = context[key], result = []; if (this.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(this.encodeValue(operator, value, this.isKeyOperator(operator) ? key : null)); } else { if (modifier === '*') { if (Array.isArray(value)) { value.filter(this.isDefined).forEach(function (value) { result.push(this.encodeValue(operator, value, this.isKeyOperator(operator) ? key : null)); }, this); } else { Object.keys(value).forEach(function (k) { if (this.isDefined(value[k])) { result.push(this.encodeValue(operator, value[k], k)); } }, this); } } else { var tmp = []; if (Array.isArray(value)) { value.filter(this.isDefined).forEach(function (value) { tmp.push(this.encodeValue(operator, value)); }, this); } else { Object.keys(value).forEach(function (k) { if (this.isDefined(value[k])) { tmp.push(encodeURIComponent(k)); tmp.push(this.encodeValue(operator, value[k].toString())); } }, this); } if (this.isKeyOperator(operator)) { result.push(encodeURIComponent(key) + '=' + tmp.join(',')); } else if (tmp.length !== 0) { result.push(tmp.join(',')); } } } } else { if (operator === ';') { result.push(encodeURIComponent(key)); } else if (value === '' && (operator === '&' || operator === '?')) { result.push(encodeURIComponent(key) + '='); } else if (value === '') { result.push(''); } } return result; }; /** * @param {string} template * @return {function(Object):string} */ UrlTemplate.prototype.parse = function (template) { var that = this; var operators = ['+', '#', '.', '/', ';', '?', '&']; return { expand: function expand(context) { return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) { if (expression) { var operator = null, 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.apply(values, that.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 that.encodeReserved(literal); } }); } }; }; module.exports = new UrlTemplate();