/* * * Copyright 2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); /* * Path template utility. */ var _ = require("lodash"); var util = require("util"); var extras = require("./parser_extras"); var parser = require('./path_template_parser'); var PathTemplate = /** @class */ (function () { /** * @param {String} data the of the template * * @constructor */ function PathTemplate(data) { this.parseResult = extras.finishParse(parser.parse(data)); } Object.defineProperty(PathTemplate.prototype, "size", { get: function () { return this.parseResult.size; }, enumerable: true, configurable: true }); Object.defineProperty(PathTemplate.prototype, "segments", { get: function () { return this.parseResult.segments; }, enumerable: true, configurable: true }); /** * Matches a fully-qualified path template string. * * @param {String} path a fully-qualified path template string * @return {Object} contains const names matched to binding values * @throws {TypeError} if path can't be matched to this template */ PathTemplate.prototype.match = function (path) { var pathSegments = path.split('/'); var bindings = {}; var segmentCount = this.size; var current; var index = 0; this.segments.forEach(function (segment) { if (index > pathSegments.length) { return; } if (segment.kind === extras.BINDING) { current = segment.literal; } else if (segment.kind === extras.TERMINAL) { if (segment.literal === '*') { bindings[current] = pathSegments[index]; index += 1; } else if (segment.literal === '**') { var size = pathSegments.length - segmentCount + 1; segmentCount += size - 1; bindings[current] = pathSegments.slice(index, index + size).join('/'); index += size; } else if (segment.literal === pathSegments[index]) { index += 1; } else { var msg = util.format('mismatched literal (index=%d): \'%s\' != \'%s\'', index, segment.literal, pathSegments[index]); throw new TypeError(msg); } } }); if (index !== pathSegments.length || index !== segmentCount) { var msg = util.format('match error: could not instantiate a path template from %s', path); throw new TypeError(msg); } return bindings; }; /** * Renders a path template using the provided bindings. * * @param {Object} bindings a mapping of const names to binding strings * @return {String} a rendered representation of the path template * @throws {TypeError} if a key is missing, or if a sub-template cannot be * parsed */ PathTemplate.prototype.render = function (bindings) { var out = []; var inABinding = false; this.segments.forEach(function (segment) { if (segment.kind === extras.BINDING) { if (!_.has(bindings, segment.literal)) { var msg = util.format('Value for key %s is not provided in %s', segment.literal, bindings); throw new TypeError(msg); } var tmp = new PathTemplate(bindings[segment.literal]); Array.prototype.push.apply(out, tmp.segments); inABinding = true; } else if (segment.kind === extras.END_BINDING) { inABinding = false; } else if (inABinding) { return; } else { out.push(segment); } }); var result = formatSegments(out); this.match(result); return result; }; /** * Renders the path template. * * @return {string} contains const names matched to binding values */ PathTemplate.prototype.inspect = function () { return formatSegments(this.segments); }; return PathTemplate; }()); exports.PathTemplate = PathTemplate; /** * Creates the string representattion for the segments. * @param {Object[]} segments - The array of segments. * @return {string} - A string representing segments in the path template * format. */ function formatSegments(segments) { var out = ''; var slash = true; segments.forEach(function (segment) { if (segment.kind === extras.TERMINAL) { if (slash) { out += '/'; } out += segment.literal; return; } slash = true; if (segment.kind === extras.BINDING) { out += '/{' + segment.literal + '='; slash = false; } else { out += segment.literal + '}'; } }); return out.substring(1); } //# sourceMappingURL=path_template.js.map