owltech
Version:
This a backend for OwlTech Company
176 lines • 6.34 kB
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.
*
*/
Object.defineProperty(exports, "__esModule", { value: true });
/*
* Path template utility.
*/
const has = require("lodash.has");
const util = require("util");
const extras = require("./parserExtras");
const parser = require('./pathTemplateParser');
class PathTemplate {
get size() {
return this.parseResult.size;
}
get segments() {
return this.parseResult.segments;
}
/**
* @param {String} data the of the template
*
* @constructor
*/
constructor(data) {
this.parseResult = extras.finishParse(parser.parse(data));
}
/**
* 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
*/
match(path) {
const pathSegments = path.split('/');
const bindings = {};
let segmentCount = this.size;
let current;
let index = 0;
this.segments.forEach(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 === '**') {
const 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 {
const msg = util.format('mismatched literal (index=%d): \'%s\' != \'%s\'', index, segment.literal, pathSegments[index]);
throw new TypeError(msg);
}
}
});
if (index !== pathSegments.length || index !== segmentCount) {
const 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
*/
render(bindings) {
const out = [];
let inABinding = false;
this.segments.forEach(segment => {
if (segment.kind === extras.BINDING) {
if (!has(bindings, segment.literal)) {
const msg = util.format('Value for key %s is not provided in %s', segment.literal, bindings);
throw new TypeError(msg);
}
const 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);
}
});
const result = formatSegments(out);
this.match(result);
return result;
}
/**
* Renders the path template.
*
* @return {string} contains const names matched to binding values
*/
inspect() {
return formatSegments(this.segments);
}
}
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) {
let out = '';
let slash = true;
segments.forEach(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=pathTemplate.js.map