UNPKG

hurt

Version:

HTTP and SPA routing using RFC 6570 URI templates

138 lines (118 loc) 12.1 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; exports.default = trie; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /** * A prefix tree supporting add and filter operations. * Inner nodes are represented as objects mapping prefixes to subtrees. * Leaf-nodes are arrays containing potential matches. */ function trie() { var root = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return { flatten: function flatten() { return _flatten(root); }, match: function match(key, output) { return _match(root, key, output); }, add: function add(key) { for (var _len = arguments.length, items = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { items[_key - 1] = arguments[_key]; } return root = _add(root, key, items); } }; } /** * Return a new trie containing the items of the given trie plus * the given items stored at the given key. */ function _add(trie, key, items) { if (!trie || Array.isArray(trie) && trie.length === 0) { return key ? _defineProperty({}, key, items) : items; } if (Array.isArray(trie)) { return key ? _defineProperty({ '': trie }, key, items) : trie.concat(items); } if (!key) { return _extends({}, trie, { '': _add(trie[''], '', items) }); } for (var k in trie) { if (k && trie.hasOwnProperty(k)) { var p = prefix(k, key); if (p === k) { return _extends({}, trie, _defineProperty({}, p, _add(trie[k], key.substr(p.length), items))); } else if (p) { var _p; return rmprop(k, _extends({}, trie, _defineProperty({}, p, (_p = {}, _defineProperty(_p, k.substr(p.length), trie[k]), _defineProperty(_p, key.substr(p.length), items), _p)))); } } } return _extends({}, trie, _defineProperty({}, key, items)); } /** * Return a map of all items whose keys are prefixes of the given key. * Place matching items in a map, where the key is the suffix of the given * key that exceeds the prefix. * For example, when filtering with '/users/123', with an item '/users/' * and an item '/users/123' present, the result will be a map containing the * key '123' pointing to the value stored at '/users' and the key '' pointing * to the value stored at '/users/123'. */ exports.add = _add; function _match(trie, key) { var output = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (Array.isArray(trie)) { if (Array.isArray(output)) { Array.prototype.push.apply(output, trie); } else { output[key] = trie; } } else { Object.keys(trie).filter(function (k) { return key.substr(0, k.length) === k; }).forEach(function (k) { return _match(trie[k], key.substr(k.length), output); }); } return output; } /** * Return a map of all stored keys and values as a plain object. */ exports.match = _match; function _flatten(trie) { var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; var output = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; if (Array.isArray(trie)) { output[key] = trie; } else { Object.keys(trie).forEach(function (k) { return _flatten(trie[k], key + k, output); }); } return output; } /** * Remove the given property from the object and return the object. */ exports.flatten = _flatten; function rmprop(prop, obj) { delete obj[prop]; return obj; } /** * Return the common prefix of strings a and b. */ function prefix(a, b) { var i = void 0; for (i = 0; a[i] === b[i] && i < a.length; i++) {} return a.substr(0, i); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy90cmllLmpzIl0sIm5hbWVzIjpbInRyaWUiLCJyb290IiwiZmxhdHRlbiIsIm1hdGNoIiwia2V5Iiwib3V0cHV0IiwiYWRkIiwiaXRlbXMiLCJBcnJheSIsImlzQXJyYXkiLCJsZW5ndGgiLCJjb25jYXQiLCJrIiwiaGFzT3duUHJvcGVydHkiLCJwIiwicHJlZml4Iiwic3Vic3RyIiwicm1wcm9wIiwicHJvdG90eXBlIiwicHVzaCIsImFwcGx5IiwiT2JqZWN0Iiwia2V5cyIsImZpbHRlciIsImZvckVhY2giLCJwcm9wIiwib2JqIiwiYSIsImIiLCJpIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztrQkFLd0JBLEk7Ozs7QUFMeEI7Ozs7O0FBS2UsU0FBU0EsSUFBVCxHQUF5QjtBQUFBLE1BQVhDLElBQVcsdUVBQUosRUFBSTs7QUFDdEMsU0FBTztBQUNMQyxXQURLLHFCQUNLO0FBQ1IsYUFBT0EsU0FBUUQsSUFBUixDQUFQO0FBQ0QsS0FISTtBQUlMRSxTQUpLLGlCQUlDQyxHQUpELEVBSU1DLE1BSk4sRUFJYztBQUNqQixhQUFPRixPQUFNRixJQUFOLEVBQVlHLEdBQVosRUFBaUJDLE1BQWpCLENBQVA7QUFDRCxLQU5JO0FBT0xDLE9BUEssZUFPREYsR0FQQyxFQU9jO0FBQUEsd0NBQVBHLEtBQU87QUFBUEEsYUFBTztBQUFBOztBQUNqQixhQUFPTixPQUFPSyxLQUFJTCxJQUFKLEVBQVVHLEdBQVYsRUFBZUcsS0FBZixDQUFkO0FBQ0Q7QUFUSSxHQUFQO0FBV0Q7O0FBRUQ7Ozs7QUFJTyxTQUFTRCxJQUFULENBQWFOLElBQWIsRUFBbUJJLEdBQW5CLEVBQXdCRyxLQUF4QixFQUErQjtBQUNwQyxNQUFJLENBQUNQLElBQUQsSUFBVVEsTUFBTUMsT0FBTixDQUFjVCxJQUFkLEtBQXVCQSxLQUFLVSxNQUFMLEtBQWdCLENBQXJELEVBQXlEO0FBQ3ZELFdBQU9OLDBCQUFVQSxHQUFWLEVBQWlCRyxLQUFqQixJQUEyQkEsS0FBbEM7QUFDRDs7QUFFRCxNQUFJQyxNQUFNQyxPQUFOLENBQWNULElBQWQsQ0FBSixFQUF5QjtBQUN2QixXQUFPSSx3QkFBUSxJQUFJSixJQUFaLElBQW9CSSxHQUFwQixFQUEyQkcsS0FBM0IsSUFBcUNQLEtBQUtXLE1BQUwsQ0FBWUosS0FBWixDQUE1QztBQUNEOztBQUVELE1BQUksQ0FBQ0gsR0FBTCxFQUFVO0FBQ1Isd0JBQ0tKLElBREw7QUFFRSxVQUFJTSxLQUFJTixLQUFLLEVBQUwsQ0FBSixFQUFjLEVBQWQsRUFBa0JPLEtBQWxCO0FBRk47QUFJRDs7QUFFRCxPQUFLLElBQU1LLENBQVgsSUFBZ0JaLElBQWhCLEVBQXNCO0FBQ3BCLFFBQUlZLEtBQUtaLEtBQUthLGNBQUwsQ0FBb0JELENBQXBCLENBQVQsRUFBaUM7QUFDL0IsVUFBTUUsSUFBSUMsT0FBT0gsQ0FBUCxFQUFVUixHQUFWLENBQVY7O0FBRUEsVUFBSVUsTUFBTUYsQ0FBVixFQUFhO0FBQ1gsNEJBQ0taLElBREwsc0JBRUljLENBRkosRUFFU1IsS0FBSU4sS0FBS1ksQ0FBTCxDQUFKLEVBQWFSLElBQUlZLE1BQUosQ0FBV0YsRUFBRUosTUFBYixDQUFiLEVBQW1DSCxLQUFuQyxDQUZUO0FBSUQsT0FMRCxNQU1LLElBQUlPLENBQUosRUFBTztBQUFBOztBQUNWLGVBQU9HLE9BQU9MLENBQVAsZUFDRlosSUFERSxzQkFFSGMsQ0FGRyxnQ0FHREYsRUFBRUksTUFBRixDQUFTRixFQUFFSixNQUFYLENBSEMsRUFHcUJWLEtBQUtZLENBQUwsQ0FIckIsdUJBSURSLElBQUlZLE1BQUosQ0FBV0YsRUFBRUosTUFBYixDQUpDLEVBSXVCSCxLQUp2QixTQUFQO0FBT0Q7QUFDRjtBQUNGOztBQUVELHNCQUNLUCxJQURMLHNCQUVJSSxHQUZKLEVBRVdHLEtBRlg7QUFJRDs7QUFFRDs7Ozs7Ozs7OztBQVNPLFNBQVNKLE1BQVQsQ0FBZUgsSUFBZixFQUFxQkksR0FBckIsRUFBdUM7QUFBQSxNQUFiQyxNQUFhLHVFQUFKLEVBQUk7O0FBQzVDLE1BQUlHLE1BQU1DLE9BQU4sQ0FBY1QsSUFBZCxDQUFKLEVBQXlCO0FBQ3ZCLFFBQUlRLE1BQU1DLE9BQU4sQ0FBY0osTUFBZCxDQUFKLEVBQTJCO0FBQ3pCRyxZQUFNVSxTQUFOLENBQWdCQyxJQUFoQixDQUFxQkMsS0FBckIsQ0FBMkJmLE1BQTNCLEVBQW1DTCxJQUFuQztBQUNELEtBRkQsTUFHSztBQUNISyxhQUFRRCxHQUFSLElBQWdCSixJQUFoQjtBQUNEO0FBQ0YsR0FQRCxNQVFLO0FBQ0hxQixXQUFPQyxJQUFQLENBQVl0QixJQUFaLEVBQ0d1QixNQURILENBQ1U7QUFBQSxhQUFNbkIsSUFBSVksTUFBSixDQUFXLENBQVgsRUFBY0osRUFBRUYsTUFBaEIsTUFBNEJFLENBQWxDO0FBQUEsS0FEVixFQUVHWSxPQUZILENBRVc7QUFBQSxhQUFLckIsT0FBTUgsS0FBS1ksQ0FBTCxDQUFOLEVBQWVSLElBQUlZLE1BQUosQ0FBV0osRUFBRUYsTUFBYixDQUFmLEVBQXFDTCxNQUFyQyxDQUFMO0FBQUEsS0FGWDtBQUdEO0FBQ0QsU0FBT0EsTUFBUDtBQUNEOztBQUVEOzs7O0FBR08sU0FBU0gsUUFBVCxDQUFpQkYsSUFBakIsRUFBOEM7QUFBQSxNQUF2QkksR0FBdUIsdUVBQWpCLEVBQWlCO0FBQUEsTUFBYkMsTUFBYSx1RUFBSixFQUFJOztBQUNuRCxNQUFJRyxNQUFNQyxPQUFOLENBQWNULElBQWQsQ0FBSixFQUF5QjtBQUN2QkssV0FBUUQsR0FBUixJQUFnQkosSUFBaEI7QUFDRCxHQUZELE1BR0s7QUFDSHFCLFdBQU9DLElBQVAsQ0FBWXRCLElBQVosRUFDR3dCLE9BREgsQ0FDVztBQUFBLGFBQUt0QixTQUFRRixLQUFLWSxDQUFMLENBQVIsRUFBaUJSLE1BQU1RLENBQXZCLEVBQTBCUCxNQUExQixDQUFMO0FBQUEsS0FEWDtBQUVEO0FBQ0QsU0FBT0EsTUFBUDtBQUNEOztBQUVEOzs7O0FBR0EsU0FBU1ksTUFBVCxDQUFnQlEsSUFBaEIsRUFBc0JDLEdBQXRCLEVBQTJCO0FBQ3pCLFNBQU9BLElBQUlELElBQUosQ0FBUDtBQUNBLFNBQU9DLEdBQVA7QUFDRDs7QUFFRDs7O0FBR0EsU0FBU1gsTUFBVCxDQUFnQlksQ0FBaEIsRUFBbUJDLENBQW5CLEVBQXNCO0FBQ3BCLE1BQUlDLFVBQUo7QUFDQSxPQUFLQSxJQUFJLENBQVQsRUFBWUYsRUFBRUUsQ0FBRixNQUFTRCxFQUFFQyxDQUFGLENBQVQsSUFBaUJBLElBQUlGLEVBQUVqQixNQUFuQyxFQUEyQ21CLEdBQTNDO0FBQ0EsU0FBT0YsRUFBRVgsTUFBRixDQUFTLENBQVQsRUFBWWEsQ0FBWixDQUFQO0FBQ0QiLCJmaWxlIjoidHJpZS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQSBwcmVmaXggdHJlZSBzdXBwb3J0aW5nIGFkZCBhbmQgZmlsdGVyIG9wZXJhdGlvbnMuXG4gKiBJbm5lciBub2RlcyBhcmUgcmVwcmVzZW50ZWQgYXMgb2JqZWN0cyBtYXBwaW5nIHByZWZpeGVzIHRvIHN1YnRyZWVzLlxuICogTGVhZi1ub2RlcyBhcmUgYXJyYXlzIGNvbnRhaW5pbmcgcG90ZW50aWFsIG1hdGNoZXMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRyaWUocm9vdCA9IHt9KSB7XG4gIHJldHVybiB7XG4gICAgZmxhdHRlbigpIHtcbiAgICAgIHJldHVybiBmbGF0dGVuKHJvb3QpO1xuICAgIH0sXG4gICAgbWF0Y2goa2V5LCBvdXRwdXQpIHtcbiAgICAgIHJldHVybiBtYXRjaChyb290LCBrZXksIG91dHB1dCk7XG4gICAgfSxcbiAgICBhZGQoa2V5LCAuLi5pdGVtcykge1xuICAgICAgcmV0dXJuIHJvb3QgPSBhZGQocm9vdCwga2V5LCBpdGVtcyk7XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIFJldHVybiBhIG5ldyB0cmllIGNvbnRhaW5pbmcgdGhlIGl0ZW1zIG9mIHRoZSBnaXZlbiB0cmllIHBsdXNcbiAqIHRoZSBnaXZlbiBpdGVtcyBzdG9yZWQgYXQgdGhlIGdpdmVuIGtleS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZCh0cmllLCBrZXksIGl0ZW1zKSB7XG4gIGlmICghdHJpZSB8fCAoQXJyYXkuaXNBcnJheSh0cmllKSAmJiB0cmllLmxlbmd0aCA9PT0gMCkpIHtcbiAgICByZXR1cm4ga2V5ID8geyBbIGtleSBdOiBpdGVtcyB9IDogaXRlbXM7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheSh0cmllKSkge1xuICAgIHJldHVybiBrZXkgPyB7ICcnOiB0cmllLCBbIGtleSBdOiBpdGVtcyB9IDogdHJpZS5jb25jYXQoaXRlbXMpO1xuICB9XG5cbiAgaWYgKCFrZXkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udHJpZSxcbiAgICAgICcnOiBhZGQodHJpZVsnJ10sICcnLCBpdGVtcylcbiAgICB9O1xuICB9XG5cbiAgZm9yIChjb25zdCBrIGluIHRyaWUpIHtcbiAgICBpZiAoayAmJiB0cmllLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICBjb25zdCBwID0gcHJlZml4KGssIGtleSk7XG5cbiAgICAgIGlmIChwID09PSBrKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4udHJpZSxcbiAgICAgICAgICBbIHAgXTogYWRkKHRyaWVba10sIGtleS5zdWJzdHIocC5sZW5ndGgpLCBpdGVtcylcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHApIHtcbiAgICAgICAgcmV0dXJuIHJtcHJvcChrLCB7XG4gICAgICAgICAgLi4udHJpZSxcbiAgICAgICAgICBbIHAgXToge1xuICAgICAgICAgICAgWyBrLnN1YnN0cihwLmxlbmd0aCkgXTogdHJpZVtrXSxcbiAgICAgICAgICAgIFsga2V5LnN1YnN0cihwLmxlbmd0aCkgXTogaXRlbXNcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLi4udHJpZSxcbiAgICBbIGtleSBdOiBpdGVtc1xuICB9O1xufVxuXG4vKipcbiAqIFJldHVybiBhIG1hcCBvZiBhbGwgaXRlbXMgd2hvc2Uga2V5cyBhcmUgcHJlZml4ZXMgb2YgdGhlIGdpdmVuIGtleS5cbiAqIFBsYWNlIG1hdGNoaW5nIGl0ZW1zIGluIGEgbWFwLCB3aGVyZSB0aGUga2V5IGlzIHRoZSBzdWZmaXggb2YgdGhlIGdpdmVuXG4gKiBrZXkgdGhhdCBleGNlZWRzIHRoZSBwcmVmaXguXG4gKiBGb3IgZXhhbXBsZSwgd2hlbiBmaWx0ZXJpbmcgd2l0aCAnL3VzZXJzLzEyMycsIHdpdGggYW4gaXRlbSAnL3VzZXJzLydcbiAqIGFuZCBhbiBpdGVtICcvdXNlcnMvMTIzJyBwcmVzZW50LCB0aGUgcmVzdWx0IHdpbGwgYmUgYSBtYXAgY29udGFpbmluZyB0aGVcbiAqIGtleSAnMTIzJyBwb2ludGluZyB0byB0aGUgdmFsdWUgc3RvcmVkIGF0ICcvdXNlcnMnIGFuZCB0aGUga2V5ICcnIHBvaW50aW5nXG4gKiB0byB0aGUgdmFsdWUgc3RvcmVkIGF0ICcvdXNlcnMvMTIzJy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hdGNoKHRyaWUsIGtleSwgb3V0cHV0ID0ge30pIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkodHJpZSkpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvdXRwdXQpKSB7XG4gICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShvdXRwdXQsIHRyaWUpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIG91dHB1dFsga2V5IF0gPSB0cmllO1xuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBPYmplY3Qua2V5cyh0cmllKVxuICAgICAgLmZpbHRlcihrID0+IChrZXkuc3Vic3RyKDAsIGsubGVuZ3RoKSA9PT0gaykpXG4gICAgICAuZm9yRWFjaChrID0+IG1hdGNoKHRyaWVba10sIGtleS5zdWJzdHIoay5sZW5ndGgpLCBvdXRwdXQpKTtcbiAgfVxuICByZXR1cm4gb3V0cHV0O1xufVxuXG4vKipcbiAqIFJldHVybiBhIG1hcCBvZiBhbGwgc3RvcmVkIGtleXMgYW5kIHZhbHVlcyBhcyBhIHBsYWluIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW4odHJpZSwga2V5ID0gJycsIG91dHB1dCA9IHt9KSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHRyaWUpKSB7XG4gICAgb3V0cHV0WyBrZXkgXSA9IHRyaWU7XG4gIH1cbiAgZWxzZSB7XG4gICAgT2JqZWN0LmtleXModHJpZSlcbiAgICAgIC5mb3JFYWNoKGsgPT4gZmxhdHRlbih0cmllW2tdLCBrZXkgKyBrLCBvdXRwdXQpKTtcbiAgfVxuICByZXR1cm4gb3V0cHV0O1xufVxuXG4vKipcbiAqIFJlbW92ZSB0aGUgZ2l2ZW4gcHJvcGVydHkgZnJvbSB0aGUgb2JqZWN0IGFuZCByZXR1cm4gdGhlIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gcm1wcm9wKHByb3AsIG9iaikge1xuICBkZWxldGUgb2JqW3Byb3BdO1xuICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgY29tbW9uIHByZWZpeCBvZiBzdHJpbmdzIGEgYW5kIGIuXG4gKi9cbmZ1bmN0aW9uIHByZWZpeChhLCBiKSB7XG4gIGxldCBpO1xuICBmb3IgKGkgPSAwOyBhW2ldID09PSBiW2ldICYmIGkgPCBhLmxlbmd0aDsgaSsrKTtcbiAgcmV0dXJuIGEuc3Vic3RyKDAsIGkpO1xufVxuIl19