mirror of
https://github.com/titanscouting/tra-analysis.git
synced 2025-02-22 17:35:46 +00:00
185 lines
6.6 KiB
JavaScript
185 lines
6.6 KiB
JavaScript
/*
|
|
*
|
|
* 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
|