UNPKG

uritemplate

Version:

An UriTemplate implementation of rfc 6570

218 lines (203 loc) 7.59 kB
/*jshint unused:false */ /*global pctEncoder, rfcCharHelper, isDefined, objectHelper, encodingHelper*/ var VariableExpression = (function () { "use strict"; // helper function if JSON is not available function prettyPrint (value) { return (JSON && JSON.stringify) ? JSON.stringify(value) : value; } function isEmpty (value) { if (!isDefined(value)) { return true; } if (objectHelper.isString(value)) { return value === ''; } if (objectHelper.isNumber(value) || objectHelper.isBoolean(value)) { return false; } if (objectHelper.isArray(value)) { return value.length === 0; } for (var propertyName in value) { if (value.hasOwnProperty(propertyName)) { return false; } } return true; } function propertyArray (object) { var result = [], propertyName; for (propertyName in object) { if (object.hasOwnProperty(propertyName)) { result.push({name: propertyName, value: object[propertyName]}); } } return result; } function VariableExpression (templateText, operator, varspecs) { this.templateText = templateText; this.operator = operator; this.varspecs = varspecs; } VariableExpression.prototype.toString = function () { return this.templateText; }; function expandSimpleValue(varspec, operator, value) { var result = ''; value = value.toString(); if (operator.named) { result += encodingHelper.encodeLiteral(varspec.varname); if (value === '') { result += operator.ifEmpty; return result; } result += '='; } if (varspec.maxLength !== null) { value = value.substr(0, varspec.maxLength); } result += operator.encode(value); return result; } function valueDefined (nameValue) { return isDefined(nameValue.value); } function expandNotExploded(varspec, operator, value) { var arr = [], result = ''; if (operator.named) { result += encodingHelper.encodeLiteral(varspec.varname); if (isEmpty(value)) { result += operator.ifEmpty; return result; } result += '='; } if (objectHelper.isArray(value)) { arr = value; arr = objectHelper.filter(arr, isDefined); arr = objectHelper.map(arr, operator.encode); result += objectHelper.join(arr, ','); } else { arr = propertyArray(value); arr = objectHelper.filter(arr, valueDefined); arr = objectHelper.map(arr, function (nameValue) { return operator.encode(nameValue.name) + ',' + operator.encode(nameValue.value); }); result += objectHelper.join(arr, ','); } return result; } function expandExplodedNamed (varspec, operator, value) { var isArray = objectHelper.isArray(value), arr = []; if (isArray) { arr = value; arr = objectHelper.filter(arr, isDefined); arr = objectHelper.map(arr, function (listElement) { var tmp = encodingHelper.encodeLiteral(varspec.varname); if (isEmpty(listElement)) { tmp += operator.ifEmpty; } else { tmp += '=' + operator.encode(listElement); } return tmp; }); } else { arr = propertyArray(value); arr = objectHelper.filter(arr, valueDefined); arr = objectHelper.map(arr, function (nameValue) { var tmp = encodingHelper.encodeLiteral(nameValue.name); if (isEmpty(nameValue.value)) { tmp += operator.ifEmpty; } else { tmp += '=' + operator.encode(nameValue.value); } return tmp; }); } return objectHelper.join(arr, operator.separator); } function expandExplodedUnnamed (operator, value) { var arr = [], result = ''; if (objectHelper.isArray(value)) { arr = value; arr = objectHelper.filter(arr, isDefined); arr = objectHelper.map(arr, operator.encode); result += objectHelper.join(arr, operator.separator); } else { arr = propertyArray(value); arr = objectHelper.filter(arr, function (nameValue) { return isDefined(nameValue.value); }); arr = objectHelper.map(arr, function (nameValue) { return operator.encode(nameValue.name) + '=' + operator.encode(nameValue.value); }); result += objectHelper.join(arr, operator.separator); } return result; } VariableExpression.prototype.expand = function (variables) { var expanded = [], index, varspec, value, valueIsArr, oneExploded = false, operator = this.operator; // expand each varspec and join with operator's separator for (index = 0; index < this.varspecs.length; index += 1) { varspec = this.varspecs[index]; value = variables[varspec.varname]; // if (!isDefined(value)) { // if (variables.hasOwnProperty(varspec.name)) { if (value === null || value === undefined) { continue; } if (varspec.exploded) { oneExploded = true; } valueIsArr = objectHelper.isArray(value); if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { expanded.push(expandSimpleValue(varspec, operator, value)); } else if (varspec.maxLength && isDefined(value)) { // 2.4.1 of the spec says: "Prefix modifiers are not applicable to variables that have composite values." throw new Error('Prefix modifiers are not applicable to variables that have composite values. You tried to expand ' + this + " with " + prettyPrint(value)); } else if (!varspec.exploded) { if (operator.named || !isEmpty(value)) { expanded.push(expandNotExploded(varspec, operator, value)); } } else if (isDefined(value)) { if (operator.named) { expanded.push(expandExplodedNamed(varspec, operator, value)); } else { expanded.push(expandExplodedUnnamed(operator, value)); } } } if (expanded.length === 0) { return ""; } else { return operator.first + objectHelper.join(expanded, operator.separator); } }; return VariableExpression; }());