New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

swagger-router

Package Overview
Dependencies
Maintainers
3
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

swagger-router - npm Package Compare versions

Comparing version 0.5.1 to 0.5.2

.eslintrc.yml

259

lib/node.js
"use strict";
var P = require('bluebird');
const P = require('bluebird');
// Work around recursive structure in ** terminal nodes
function printableValue(value) {
const res = {};
if (!value || !(value instanceof Object)) {
return value;
}
Object.keys(value).forEach((key) => {
const val = value[key];
if (key === 'methods') {
const newMethods = {};
Object.keys(val).forEach((method) => {
newMethods[method] = `<${val[method].name}>`;
});
res.methods = newMethods;
} else if (key !== 'specRoot') {
// Omit the specRoot, as it tends to be huge & contains reference
// circles.
res[key] = val;
}
});
return res;
}
const _keyPrefix = '/';
const _keyPrefixRegExp = /^\//;
/*

@@ -10,41 +36,37 @@ * A node in the lookup graph.

*/
function Node(value) {
// The value for a path ending on this node. Public property.
this.value = value || null;
class Node {
constructor(value) {
// The value for a path ending on this node. Public property.
this.value = value || null;
// Internal properties.
this._children = {};
this._paramName = null;
this._parent = null;
}
// Internal properties.
this._children = {};
this._paramName = null;
this._parent = null;
}
Node.prototype._keyPrefix = '/';
Node.prototype._keyPrefixRegExp = /^\//;
Node.prototype.setChild = function(key, child) {
var self = this;
if (key.constructor === String) {
this._children[this._keyPrefix + key] = child;
} else if (key.name && key.pattern
&& key.modifier !== '+'
&& key.pattern.constructor === String) {
// A named but plain key.
child._paramName = key.name;
this._children[this._keyPrefix + key.pattern] = child;
} else if (key.modifier === '+') {
child._paramName = key.name;
this._children['**'] = child;
} else {
// Setting up a wildcard match
child._paramName = key.name;
this._children['*'] = child;
setChild(key, child) {
if (key.constructor === String) {
this._children[_keyPrefix + key] = child;
} else if (key.name && key.pattern
&& key.modifier !== '+'
&& key.pattern.constructor === String) {
// A named but plain key.
child._paramName = key.name;
this._children[_keyPrefix + key.pattern] = child;
} else if (key.modifier === '+') {
child._paramName = key.name;
this._children['**'] = child;
} else {
// Setting up a wildcard match
child._paramName = key.name;
this._children['*'] = child;
}
}
};
Node.prototype.getChild = function(segment, params) {
if (segment.constructor === String) {
// Fast path
var res = this._children[this._keyPrefix + segment];
if (!res) {
if (segment !== '') {
getChild(segment, params) {
if (segment.constructor === String) {
// Fast path
let res = this._children[_keyPrefix + segment];
if (!res && segment !== '') {
// Fall back to the wildcard match, but only if the segment is

@@ -57,3 +79,3 @@ // non-empty.

if (params[res._paramName]) {
params[res._paramName] += '/' + encodeURIComponent(segment);
params[res._paramName] += `/${encodeURIComponent(segment)}`;
} else {

@@ -66,67 +88,62 @@ params[res._paramName] = encodeURIComponent(segment);

}
}
if (res) {
if (res._paramName) {
params[res._paramName] = segment;
if (res) {
if (res._paramName) {
params[res._paramName] = segment;
}
return res;
} else {
return null;
}
return res;
} else {
return null;
// Fall-back cases for internal use during tree construction. These cases
// are never used for actual routing.
} else if (segment.pattern) {
// Unwrap the pattern
return this.getChild(segment.pattern, params);
} else if (this._children['*']
&& this._children['*']._paramName === segment.name) {
// XXX: also compare modifier!
return this._children['*'] || null;
}
}
// Fall-back cases for internal use during tree construction. These cases
// are never used for actual routing.
} else if (segment.pattern) {
// Unwrap the pattern
return this.getChild(segment.pattern, params);
} else if (this._children['*']
&& this._children['*']._paramName === segment.name) {
// XXX: also compare modifier!
return this._children['*'] || null;
hasChildren() {
return Object.keys(this._children).length || this._children['*'];
}
};
Node.prototype.hasChildren = function() {
return Object.keys(this._children).length || this._children['*'];
};
keys() {
if (this._children['*'] || this._children['**']) {
return [];
} else {
const res = [];
Object.keys(this._children).forEach((key) => {
// Only list '' if there are children (for paths like
// /double//slash)
if (key !== _keyPrefix || this._children[key].hasChildren()) {
res.push(key.replace(_keyPrefixRegExp, ''));
}
});
return res.sort();
}
}
Node.prototype.keys = function() {
var self = this;
if (this._children['*'] || this._children['**']) {
return [];
} else {
var res = [];
Object.keys(this._children).forEach(function(key) {
// Only list '' if there are children (for paths like
// /double//slash)
if (key !== self._keyPrefix || self._children[key].hasChildren()) {
res.push(key.replace(self._keyPrefixRegExp, ''));
}
});
return res.sort();
// Shallow clone, allows sharing of subtrees in DAG
clone() {
const c = new Node();
c._children = this._children;
c._paramName = this._paramName;
return c;
}
};
// Shallow clone, allows sharing of subtrees in DAG
Node.prototype.clone = function() {
var c = new Node();
c._children = this._children;
c._paramName = this._paramName;
return c;
};
// Call promise-returning fn for each node value, with the path to the value
Node.prototype.visitAsync = function(fn, path) {
path = path || [];
var self = this;
// First value, then each of the children (one by one)
return fn(self.value, path)
.then(function() {
return P.resolve(Object.keys(self._children))
.each(function(childKey) {
var segment = childKey.replace(/^\//, '');
var child = self._children[childKey];
if (child === self) {
// Call promise-returning fn for each node value, with the path to the value
visitAsync(fn, path) {
path = path || [];
// First value, then each of the children (one by one)
return fn(this.value, path)
.then(() => P.resolve(Object.keys(this._children))
.each((childKey) => {
const segment = childKey.replace(/^\//, '');
const child = this._children[childKey];
if (child === this) {
// Don't enter an infinite loop on **

@@ -137,46 +154,22 @@ return;

}
});
});
};
}));
}
// Work around recursive structure in ** terminal nodes
function printableValue(value) {
var res = {};
if (!value || !(value instanceof Object)) {
return value;
toJSON() {
if (this._children['**'] === this) {
return {
value: printableValue(this.value),
_children: '<recursive>',
_paramName: this._paramName
};
} else {
return {
value: printableValue(this.value),
_children: this._children,
_paramName: this._paramName
};
}
}
Object.keys(value).forEach(function(key) {
var val = value[key];
if (key === 'methods') {
var newMethods = {};
Object.keys(val).forEach(function(method) {
newMethods[method] = '<' + val[method].name + '>';
});
res.methods = newMethods;
} else if (key !== 'specRoot') {
// Omit the specRoot, as it tends to be huge & contains reference
// circles.
res[key] = val;
}
});
return res;
}
Node.prototype.toJSON = function() {
if (this._children['**'] === this) {
return {
value: printableValue(this.value),
_children: '<recursive>',
_paramName: this._paramName
};
} else {
return {
value: printableValue(this.value),
_children: this._children,
_paramName: this._paramName
};
}
};
module.exports = Node;
"use strict";
var URI = require('./uri');
var url = require('url');
var TAssembly = require('tassembly');
var expressionCompiler = require('template-expression-compiler');
var utils = require('./utils');
const URI = require('./uri');
const TAssembly = require('tassembly');
const expressionCompiler = require('template-expression-compiler');
const utils = require('./utils');
var compilerOptions = {
const compilerOptions = {
ctxMap: {

@@ -27,11 +26,11 @@ $: 'rm',

expression = expression.replace(/\n/g, ' ').trim();
compilerOptions.modelPrefix = (part && 'rm.request.' + part) || 'm';
compilerOptions.modelPrefix = (part && `rm.request.${part}`) || 'm';
return expressionCompiler.parse(expression, compilerOptions);
}
var globalMethods = {
default: function(val, defVal) {
const globalMethods = {
default(val, defVal) {
return val || defVal;
},
merge: function(destination, source) {
merge(destination, source) {
destination = destination || {};

@@ -45,4 +44,4 @@ source = source || {};

var result = Object.assign({}, destination);
Object.keys(source).forEach(function(keyName) {
const result = Object.assign({}, destination);
Object.keys(source).forEach((keyName) => {
if (result[keyName] === undefined) {

@@ -54,3 +53,3 @@ result[keyName] = source[keyName];

},
strip: function(object, properties) {
strip(object, properties) {
if (typeof object !== 'object') {

@@ -64,3 +63,3 @@ throw new Error('Illegal argument. ' +

} else if (Array.isArray(properties)) {
properties.forEach(function(prop) {
properties.forEach((prop) => {
delete object[prop];

@@ -75,3 +74,3 @@ });

filter: function(object, pred) {
filter(object, pred) {
if (typeof object !== 'object') {

@@ -82,4 +81,4 @@ throw new Error('Illegal argument. ' +

if (Array.isArray(pred)) {
var res = {};
pred.forEach(function(key) {
const res = {};
pred.forEach((key) => {
res[key] = object[key];

@@ -97,7 +96,5 @@ });

requestTemplate: function(spec, options) {
var tpl = new Template(spec, options);
return function(model) {
return tpl.expand(model);
};
requestTemplate(spec, options) {
const tpl = new Template(spec, options);
return (model) => tpl.expand(model);
},

@@ -111,3 +108,3 @@

*/
date: function(date, format) {
date(date, format) {

@@ -124,3 +121,3 @@ function isValidDate(d) {

if (!isValidDate(date)) {
var origDate = date;
const origDate = date;

@@ -136,6 +133,7 @@ if (typeof date === 'string' && /^\d+$/.test(date)) {

if (!isValidDate(date)) {
throw new Error('Invalid date: ' + origDate);
throw new Error(`Invalid date: ${origDate}`);
}
}
/* eslint-disable indent */
switch (format) {

@@ -147,10 +145,11 @@ case 'rfc822':

default:
throw new Error('Unsupported date format: ' + format);
throw new Error(`Unsupported date format: ${format}`);
}
/* eslint-enable indent */
},
// Private helpers
_optionalPath: function(element) {
_optionalPath(element) {
if (element !== undefined) {
return '/' + encodeURIComponent(element);
return `/${encodeURIComponent(element)}`;
} else {

@@ -160,3 +159,3 @@ return '';

},
_encodeURIComponent: function(s) {
_encodeURIComponent(s) {
s = (s === undefined || s === null) ? '' : s;

@@ -173,8 +172,9 @@ if (/[^\w_-]/.test(s)) {

options = options || {};
var result = [];
var templateNest = 0;
var startIndex = 0;
var currentTemplate;
var inDoubleBrace = false;
for (var index = 0; index < templateSpec.length; index++) {
const result = [];
let templateNest = 0;
let startIndex = 0;
let currentTemplate;
let inDoubleBrace = false;
let index;
for (index = 0; index < templateSpec.length; index++) {
if (templateSpec[index] === '{') {

@@ -202,5 +202,5 @@ if (templateNest === 0) { // We are either entering a new template

} else if (/^\//.test(currentTemplate)) {
currentTemplate = '_optionalPath(' + currentTemplate.substring(1) + ')';
currentTemplate = `_optionalPath(${currentTemplate.substring(1)})`;
} else {
currentTemplate = '_encodeURIComponent(' + currentTemplate + ')';
currentTemplate = `_encodeURIComponent(${currentTemplate})`;
}

@@ -214,3 +214,3 @@ }

var compiledExpression = compileExpression(currentTemplate, options.part);
const compiledExpression = compileExpression(currentTemplate, options.part);
result.push(['raw', compiledExpression]);

@@ -232,10 +232,11 @@ startIndex = index + 1;

function compileTAssembly(template, reqPart, globals) {
var res = '';
var stringCb = function(bit) {
let resolveTemplate;
let res = '';
const stringCb = (bit) => {
if (bit !== undefined && bit !== null) {
res += '' + bit;
res += `${bit}`;
}
};
var options = {
const options = {
nestedTemplate: true,

@@ -246,4 +247,5 @@ errorHandler: null,

};
try {
var resolveTemplate = TAssembly.compile(template, options);
resolveTemplate = TAssembly.compile(template, options);
} catch (e) {

@@ -255,4 +257,4 @@ e.template = template;

return function(context) {
var childContext = {
return (context) => {
const childContext = {
rc: context.rc,

@@ -268,3 +270,3 @@ rm: context.rm,

resolveTemplate(childContext);
var value = res;
const value = res;
res = ''; // Prepare for the next request.

@@ -278,3 +280,3 @@ return value;

// a static string & a variable substitution.
var simpleTemplate = new RegExp('^(?:\\/(?:[a-zA-Z_\\.-]+|'
const simpleTemplate = new RegExp('^(?:\\/(?:[a-zA-Z_\\.-]+|'
// Sequence of plain path segments (above) or simple templated

@@ -296,14 +298,10 @@ // segments (below).

if (simpleTemplate.test(uri) && uri.indexOf('{') >= 0) {
var pathTemplate = new URI(uri, {}, true);
return function(context) {
return pathTemplate.expand(context.rm.request.params);
};
const pathTemplate = new URI(uri, {}, true);
return (context) => pathTemplate.expand(context.rm.request.params);
} else if (/\{/.test(uri)) {
var tassemblyTemplate = splitAndPrepareTAssemblyTemplate(uri);
const tassemblyTemplate = splitAndPrepareTAssemblyTemplate(uri);
// console.log('tass', spec.uri, tassemblyTemplate);
return compileTAssembly(tassemblyTemplate, 'params', globals);
} else {
return function(context) {
return uri;
};
return () => uri;
}

@@ -319,4 +317,4 @@ }

if (subSpec && subSpec.constructor === Object) {
var res = {};
Object.keys(subSpec).forEach(function(key) {
const res = {};
Object.keys(subSpec).forEach((key) => {
res[key] = replaceComplexTemplates(part, subSpec[key], globals);

@@ -326,9 +324,7 @@ });

} else if (Array.isArray(subSpec)) {
return subSpec.map(function(elem) {
return replaceComplexTemplates(part, elem, globals);
});
return subSpec.map((elem) => replaceComplexTemplates(part, elem, globals));
} else if (subSpec && subSpec.constructor === String || subSpec === '') {
if (/\{[^\}]+\}/.test(subSpec)) {
// There is a template, now we need to check it for special stuff we replace
var tAssemblyTemplates = splitAndPrepareTAssemblyTemplate(subSpec, { part: part });
const tAssemblyTemplates = splitAndPrepareTAssemblyTemplate(subSpec, { part });
if (tAssemblyTemplates.length === 1

@@ -342,16 +338,14 @@ && tAssemblyTemplates[0].length === 2

// Compile a function
var resolver = compileTAssembly(tAssemblyTemplates, part, globals);
const resolver = compileTAssembly(tAssemblyTemplates, part, globals);
// Replace the complex template with a function call
var fnName = 'fn_' + globals._i++;
const fnName = `fn_${globals._i++}`;
globals[fnName] = resolver;
return 'rc.g.' + fnName + '(c)';
return `rc.g.${fnName}(c)`;
}
} else {
// If it's not templated - wrap it into braces to let tassembly add it
return "'" + subSpec + "'";
return `'${subSpec}'`;
}
} else {
// Other literals: Number, booleans
return subSpec;
}
// Other literals: Number, booleans
return subSpec;

@@ -378,71 +372,72 @@ }

*/
function Template(origSpec, globalsInit) {
var self = this;
var globals = Object.assign({}, globalMethods, globalsInit);
var spec = _cloneSpec(origSpec);
globals._i = 0;
class Template {
constructor(origSpec, globalsInit) {
const globals = Object.assign({}, globalMethods, globalsInit);
let spec = _cloneSpec(origSpec);
globals._i = 0;
if (typeof spec === 'string') {
spec = replaceComplexTemplates(undefined, spec, globals);
} else {
Object.keys(spec).forEach(function(part) {
if (part === 'uri') {
globals._uri = createURIResolver(spec.uri, globals);
spec.uri = 'rc.g._uri(c)';
} else {
spec[part] = replaceComplexTemplates(part, spec[part], globals);
}
});
}
var completeTAssemblyTemplate = expressionCompiler.stringify(spec);
// console.log(origSpec, completeTAssemblyTemplate);
var res = null;
var objectCb = function(bit) {
if (res === null) {
res = bit;
if (typeof spec === 'string') {
spec = replaceComplexTemplates(undefined, spec, globals);
} else {
Object.keys(spec).forEach((part) => {
if (part === 'uri') {
globals._uri = createURIResolver(spec.uri, globals);
spec.uri = 'rc.g._uri(c)';
} else {
spec[part] = replaceComplexTemplates(part, spec[part], globals);
}
});
}
};
var resolver;
try {
resolver = TAssembly.compile([['raw', completeTAssemblyTemplate]], {
nestedTemplate: true,
globals: globals,
cb: objectCb,
errorHandler: null,
});
} catch (e) {
e.spec = origSpec;
e.tassembly = completeTAssemblyTemplate;
throw e;
}
const completeTAssemblyTemplate = expressionCompiler.stringify(spec);
// console.log(origSpec, completeTAssemblyTemplate);
let res = null;
const objectCb = (bit) => {
if (res === null) {
res = bit;
}
};
var c = {
rc: null,
rm: null,
g: globals,
cb: objectCb,
m: null,
};
c.rc = c;
self.expand = function(m) {
c.rm = m;
c.m = m;
let resolver;
try {
resolver(c);
resolver = TAssembly.compile([['raw', completeTAssemblyTemplate]], {
nestedTemplate: true,
globals,
cb: objectCb,
errorHandler: null,
});
} catch (e) {
e.expression_tassembly = completeTAssemblyTemplate;
e.expression_spec = origSpec;
res = null;
e.spec = origSpec;
e.tassembly = completeTAssemblyTemplate;
throw e;
}
var ret = res;
res = null;
// ensure a reasonable fallback for ret.method
if (ret && ret.hasOwnProperty('method')) {
ret.method = ret.method || 'get';
}
return ret;
};
const c = {
rc: null,
rm: null,
g: globals,
cb: objectCb,
m: null,
};
c.rc = c;
this.expand = (m) => {
c.rm = m;
c.m = m;
try {
resolver(c);
} catch (e) {
e.expression_tassembly = completeTAssemblyTemplate;
e.expression_spec = origSpec;
res = null;
throw e;
}
const ret = res;
res = null;
// ensure a reasonable fallback for ret.method
if (ret && {}.hasOwnProperty.call(ret, 'method')) {
ret.method = ret.method || 'get';
}
return ret;
};
}
}

@@ -449,0 +444,0 @@

"use strict";
var URI = require('./uri');
var Node = require('./node');
var utils = require('./utils');
const URI = require('./uri');
const Node = require('./node');
const utils = require('./utils');
/*
* The main router object
*/
function Router(options) {
// Options:
// - specHandler(spec) -> spec'
// - pathHandler(pathSpec) -> pathSpec'
this._options = options || {};
this._root = new Node();
}
class Router {
constructor(options) {
// Options:
// - specHandler(spec) -> spec'
// - pathHandler(pathSpec) -> pathSpec'
this._options = options || {};
this._root = new Node();
}
// XXX modules: variant that builds a prefix tree from a path array, but pass
// in a spec instead of a value
Router.prototype._buildTree = function(path, value) {
var node = new Node();
if (path.length) {
var segment = path[0];
if (segment.modifier === '+') {
// Set up a recursive match and end the traversal
var recursionNode = new Node();
recursionNode.value = value;
recursionNode.setChild(segment, recursionNode);
node.setChild(segment, recursionNode);
// XXX modules: variant that builds a prefix tree from a path array, but pass
// in a spec instead of a value
_buildTree(path, value) {
const node = new Node();
if (path.length) {
const segment = path[0];
if (segment.modifier === '+') {
// Set up a recursive match and end the traversal
const recursionNode = new Node();
recursionNode.value = value;
recursionNode.setChild(segment, recursionNode);
node.setChild(segment, recursionNode);
} else {
const subTree = this._buildTree(path.slice(1), value);
node.setChild(segment, subTree);
if (segment.modifier === '/') {
// Set the value for each optional path segment ({/foo})
node.value = value;
subTree.value = value;
}
}
} else {
var subTree = this._buildTree(path.slice(1), value);
node.setChild(segment, subTree);
if (segment.modifier === '/') {
// Set the value for each optional path segment ({/foo})
node.value = value;
subTree.value = value;
}
node.value = value;
}
} else {
node.value = value;
return node;
}
return node;
};
specToTree(spec) {
const root = new Node();
Object.keys(spec.paths).forEach((pathPattern) => {
const path = utils.parsePath(pathPattern, true);
this._extend(path, root, spec.paths[pathPattern]);
});
return root;
}
Router.prototype.specToTree = function(spec) {
var root = new Node();
var self = this;
Object.keys(spec.paths).forEach(function(pathPattern) {
var path = utils.parsePath(pathPattern, true);
self._extend(path, root, spec.paths[pathPattern]);
});
return root;
};
setTree(tree) {
this._root = tree;
}
Router.prototype.setTree = function(tree) {
this._root = tree;
};
delSpec() {
// Possible implementation:
// - Perform a *recursive* lookup for each leaf node.
// - Walk up the tree and remove nodes as long as `.hasChildren()` is
// false.
// This will work okay in a tree, but would clash with subtree sharing in
// a graph. We should perform some benchmarks to see if subtree sharing is
// worth it. Until then we probably don't need spec deletion anyway, as we
// can always re-build the entire router from scratch.
throw new Error("Not implemented");
}
Router.prototype.delSpec = function delSpec(spec, prefix) {
// Possible implementation:
// - Perform a *recursive* lookup for each leaf node.
// - Walk up the tree and remove nodes as long as `.hasChildren()` is
// false.
// This will work okay in a tree, but would clash with subtree sharing in
// a graph. We should perform some benchmarks to see if subtree sharing is
// worth it. Until then we probably don't need spec deletion anyway, as we
// can always re-build the entire router from scratch.
throw new Error("Not implemented");
};
// Extend an existing route tree with a new path by walking the existing tree
// and inserting new subtrees at the desired location.
Router.prototype._extend = function route(path, node, value) {
var params = {};
for (var i = 0; i < path.length; i++) {
var nextNode = node.getChild(path[i], params);
if (!nextNode || !nextNode.getChild) {
// Found our extension point
node.setChild(path[i], this._buildTree(path.slice(i + 1), value));
return;
} else {
node = nextNode;
// Extend an existing route tree with a new path by walking the existing tree
// and inserting new subtrees at the desired location.
_extend(path, node, value) {
const params = {};
for (let i = 0; i < path.length; i++) {
const nextNode = node.getChild(path[i], params);
if (!nextNode || !nextNode.getChild) {
// Found our extension point
node.setChild(path[i], this._buildTree(path.slice(i + 1), value));
return;
} else {
node = nextNode;
}
}
if (value !== undefined) {
node.value = value;
}
}
if (value !== undefined) {
node.value = value;
}
};
// Lookup worker.
Router.prototype._lookup = function route(path, node) {
var params = {};
var prevNode;
var permissions = [];
var filters = [];
for (var i = 0; i < path.length; i++) {
if (!node || !node.getChild) {
return null;
// Lookup worker.
_lookup(path, node) {
const params = {};
let prevNode;
let permissions = [];
let filters = [];
for (let i = 0; i < path.length; i++) {
if (!node || !node.getChild) {
return null;
}
prevNode = node;
if (node.value) {
if (node.value.security) {
permissions = permissions.concat(node.value.security);
}
if (node.value.filters) {
filters = filters.concat(node.value.filters);
}
}
node = node.getChild(path[i], params);
}
prevNode = node;
if (node.value) {
if (node && node.value) {
if (node.value.security) {

@@ -109,65 +120,55 @@ permissions = permissions.concat(node.value.security);

}
node = node.getChild(path[i], params);
}
if (node && node.value) {
if (node.value.security) {
permissions = permissions.concat(node.value.security);
if (node || prevNode && path[path.length - 1] === '') {
if (path[path.length - 1] === '') {
// Pass in a listing
params._ls = prevNode.keys();
}
return {
params,
value: (node && node.value || null),
permissions,
filters
};
} else {
return null;
}
if (node.value.filters) {
filters = filters.concat(node.value.filters);
}
}
if (node || prevNode && path[path.length - 1] === '') {
if (path[path.length - 1] === '') {
// Pass in a listing
params._ls = prevNode.keys();
/*
* Look up a path in the router, and return either null or the configured
* object.
*
* @param {string|array} path
* @return {null|object} with object being
* {
* params: {
* someParam: 'pathcomponent'
* },
* value: theValue,
* permissions: [somePermission]
* }
*/
lookup(path) {
if (!path) {
throw new Error('Path expected!');
} else if (path.constructor === String) {
path = utils.parsePath(path);
} else if (path.constructor === URI) {
path = path.path;
}
return {
params: params,
value: (node && node.value || null),
permissions: permissions,
filters: filters
};
} else {
return null;
const res = this._lookup(path, this._root);
if (res) {
return {
params: res.params,
value: res.value,
permissions: res.permissions,
filters: res.filters
};
} else {
return res;
}
}
};
}
/*
* Look up a path in the router, and return either null or the configured
* object.
*
* @param {string|array} path
* @return {null|object} with object being
* {
* params: {
* someParam: 'pathcomponent'
* },
* value: theValue,
* permissions: [somePermission]
* }
*/
Router.prototype.lookup = function route(path) {
if (!path) {
throw new Error('Path expected!');
} else if (path.constructor === String) {
path = utils.parsePath(path);
} else if (path.constructor === URI) {
path = path.path;
}
var res = this._lookup(path, this._root);
if (res) {
return {
params: res.params,
value: res.value,
permissions: res.permissions,
filters: res.filters
};
} else {
return res;
}
};
module.exports = Router;
module.exports = Router;
"use strict";
var utils = require('./utils');
const utils = require('./utils');
/**

@@ -15,206 +16,205 @@ * Represents a URI object which can optionally contain and

*/
function URI(uri, params, asPattern) {
// Initialise all fields to make an object monomorphic
this.params = params || {};
this.protoHost = null;
this.path = null;
this._pathMetadata = {};
class URI {
constructor(uri, params, asPattern) {
// Initialise all fields to make an object monomorphic
this.params = params || {};
this.protoHost = null;
this.path = null;
this._pathMetadata = {};
if (typeof uri === 'string') {
var protoHostMatch = /^[^\/]+:(?:\/\/)?[^\/]+/.exec(uri);
if (protoHostMatch) {
this.protoHost = protoHostMatch[0];
uri = uri.substring(this.protoHost.length);
}
this.path = utils.parsePath(uri, asPattern);
} else if (Array.isArray(uri)) {
if (!asPattern) {
// Ensure that all path segments are strings
for (var i = 0; i < uri.length; i++) {
uri[i] = '' + uri[i];
if (typeof uri === 'string') {
const protoHostMatch = /^[^\/]+:(?:\/\/)?[^\/]+/.exec(uri);
if (protoHostMatch) {
this.protoHost = protoHostMatch[0];
uri = uri.substring(this.protoHost.length);
}
this.path = utils.parsePath(uri, asPattern);
} else if (Array.isArray(uri)) {
if (!asPattern) {
// Ensure that all path segments are strings
for (let i = 0; i < uri.length; i++) {
uri[i] = `${uri[i]}`;
}
}
this.path = uri;
} else if (uri && uri.constructor === URI) {
this.protoHost = uri.protoHost;
// this.path is considered immutable, so can be shared with other URI
// instances
this.path = uri.path;
} else if (uri !== '') {
throw new Error(`Invalid path passed into URI constructor: ${uri}`);
}
this.path = uri;
} else if (uri && uri.constructor === URI) {
this.protoHost = uri.protoHost;
// this.path is considered immutable, so can be shared with other URI
// instances
this.path = uri.path;
} else if (uri !== '') {
throw new Error('Invalid path passed into URI constructor: ' + uri);
}
}
/**
* Builds and returns the full, bounded string path for this URI object
*
* @return {String} the complete path of this URI object
* @param {object} options {
* format {string} Either 'simplePattern' or 'fullPattern'. [optional]
* params {object} parameters to use during serialization
* }
* @return {string} URI path
*/
URI.prototype.toString = function(options) {
// b/c
if (!options || options.constructor === String) {
options = { format: options };
}
var params = options.params || this.params;
var uriStr = this.protoHost || '';
for (var i = 0; i < this.path.length; i++) {
var segment = this.path[i];
if (segment && segment.constructor === Object) {
var segmentValue = params[segment.name];
if (segmentValue === undefined) {
segmentValue = segment.pattern;
}
/**
* Builds and returns the full, bounded string path for this URI object
*
* @return {String} the complete path of this URI object
* @param {object} options {
* format {string} Either 'simplePattern' or 'fullPattern'. [optional]
* params {object} parameters to use during serialization
* }
* @return {string} URI path
*/
toString(options) {
// b/c
if (!options || options.constructor === String) {
options = { format: options };
}
const params = options.params || this.params;
let uriStr = this.protoHost || '';
for (let i = 0; i < this.path.length; i++) {
const segment = this.path[i];
if (segment && segment.constructor === Object) {
let segmentValue = params[segment.name];
if (segmentValue === undefined) {
segmentValue = segment.pattern;
}
if (segmentValue !== undefined) {
if (!options.format || options.format === 'simplePattern' || !segment.name) {
if (segment.modifier === '+') {
uriStr += '/' + segmentValue;
if (segmentValue !== undefined) {
if (!options.format || options.format === 'simplePattern' || !segment.name) {
if (segment.modifier === '+') {
uriStr += `/${segmentValue}`;
} else {
// Normal mode
uriStr += `/${encodeURIComponent(segmentValue)}`;
}
} else {
// Normal mode
uriStr += '/' + encodeURIComponent(segmentValue);
uriStr += `/{${segment.modifier || ''}`
+ `${encodeURIComponent(segment.name)}:`
+ `${encodeURIComponent(segmentValue)}}`;
}
} else if (options.format && !segment.modifier) {
uriStr += `/{${encodeURIComponent(segment.name)}}`;
} else if (options.format) {
uriStr += `{${segment.modifier || ''}${encodeURIComponent(segment.name)}}`;
} else {
uriStr += '/{' + (segment.modifier || '')
+ encodeURIComponent(segment.name) + ':'
+ encodeURIComponent(segmentValue) + '}';
if (segment.modifier === '+') {
// Add trailing slash
uriStr += '/';
}
// Omit optional segment & return
return uriStr;
}
} else if (options.format && !segment.modifier) {
uriStr += '/{' + encodeURIComponent(segment.name) + '}';
} else if (options.format) {
uriStr += '{' + (segment.modifier || '')
+ encodeURIComponent(segment.name) + '}';
} else if (this._pathMetadata
&& this._pathMetadata[i]
&& this._pathMetadata[i] === '+') {
uriStr += `/${utils.encodeReserved(segment)}`;
} else {
if (segment.modifier === '+') {
// Add trailing slash
uriStr += '/';
}
// Omit optional segment & return
return uriStr;
uriStr += `/${encodeURIComponent(segment)}`;
}
} else if (this._pathMetadata
&& this._pathMetadata[i]
&& this._pathMetadata[i] === '+') {
uriStr += '/' + utils.encodeReserved(segment);
} else {
uriStr += '/' + encodeURIComponent(segment);
}
return uriStr;
}
return uriStr;
};
/**
* Expand all parameters in the URI and return a new URI.
* @param {object} params (optional) Parameters to use for expansion. Uses
* URI-assigned parameters if not supplied.
* @return {URI}
*/
URI.prototype.expand = function(params) {
if (!params) {
params = this.params;
}
var res = [];
var pathMetadata = {};
var uri;
for (var i = 0; i < this.path.length; i++) {
var segment = this.path[i];
if (segment && segment.constructor === Object) {
var segmentValue = params[segment.name];
if (segmentValue === undefined) {
segmentValue = segment.pattern;
/**
* Expand all parameters in the URI and return a new URI.
* @param {object} params (optional) Parameters to use for expansion. Uses
* URI-assigned parameters if not supplied.
* @return {URI}
*/
expand(params) {
if (!params) {
params = this.params;
}
let res = [];
const pathMetadata = {};
for (let i = 0; i < this.path.length; i++) {
const segment = this.path[i];
if (segment && segment.constructor === Object) {
let segmentValue = params[segment.name];
if (segmentValue === undefined) {
if (segment.modifier) {
// Skip over this optional segment.
continue;
} else {
segmentValue = '';
segmentValue = segment.pattern;
if (segmentValue === undefined) {
if (segment.modifier) {
// Skip over this optional segment.
continue;
} else {
segmentValue = '';
}
}
}
}
if (segment.modifier === '+') {
// Res will become a path array, so we must split path elements
var oldResLen = res.length;
res = res.concat(('' + segmentValue).split('/'));
// Set up metadata for all path elements under {+} template
for (var j = oldResLen; j < res.length; j++) {
pathMetadata[j] = '+';
if (segment.modifier === '+') {
// Res will become a path array, so we must split path elements
const oldResLen = res.length;
res = res.concat((`${segmentValue}`).split('/'));
// Set up metadata for all path elements under {+} template
for (let j = oldResLen; j < res.length; j++) {
pathMetadata[j] = '+';
}
} else {
res.push(`${segmentValue}`);
}
} else {
res.push('' + segmentValue);
res.push(segment);
}
} else {
res.push(segment);
}
const uri = new URI(res);
uri.protoHost = this.protoHost;
// FIXME: handle this in the constructor!
uri._pathMetadata = pathMetadata;
return uri;
}
uri = new URI(res);
uri.protoHost = this.protoHost;
// FIXME: handle this in the constructor!
uri._pathMetadata = pathMetadata;
return uri;
};
/**
* Checks if the URI starts with the given path prefix
*
* @param {String|URI} pathOrURI the prefix path to check for
* @return {Boolean} whether this URI starts with the given prefix path
*/
URI.prototype.startsWith = function(pathOrURI) {
var uri;
if (!pathOrURI) {
return true;
}
if (pathOrURI.constructor === URI) {
uri = pathOrURI;
} else {
uri = new URI(pathOrURI);
}
// if our URI is shorter than the one we are
// comparing to, it doesn't start with that prefix
if (this.path.length < uri.path.length) {
return false;
}
// check each component
for (var idx = 0; idx < uri.path.length; idx++) {
var mySeg = this.path[idx];
var otherSeg = uri.path[idx];
if (mySeg.constructor === Object && otherSeg.constructor === Object) {
// both path are named variables
// nothing to do
continue;
} else if (mySeg.constructor === Object) {
// we have a named variable, but there is a string
// given in the prefix
if (mySeg.pattern && mySeg.pattern !== otherSeg) {
// they differ
/**
* Checks if the URI starts with the given path prefix
*
* @param {String|URI} pathOrURI the prefix path to check for
* @return {Boolean} whether this URI starts with the given prefix path
*/
startsWith(pathOrURI) {
let uri;
if (!pathOrURI) {
return true;
}
if (pathOrURI.constructor === URI) {
uri = pathOrURI;
} else {
uri = new URI(pathOrURI);
}
// if our URI is shorter than the one we are
// comparing to, it doesn't start with that prefix
if (this.path.length < uri.path.length) {
return false;
}
// check each component
for (let idx = 0; idx < uri.path.length; idx++) {
const mySeg = this.path[idx];
const otherSeg = uri.path[idx];
if (mySeg.constructor === Object && otherSeg.constructor === Object) {
// both path are named variables
// nothing to do
continue;
} else if (mySeg.constructor === Object) {
// we have a named variable, but there is a string
// given in the prefix
if (mySeg.pattern && mySeg.pattern !== otherSeg) {
// they differ
return false;
}
} else if (otherSeg.constructor === Object) {
// we have a fixed string, but a variable has been
// given in the prefix - nothing to do
continue;
} else if (mySeg !== otherSeg) {
// both are strings, but they differ
return false;
}
} else if (otherSeg.constructor === Object) {
// we have a fixed string, but a variable has been
// given in the prefix - nothing to do
continue;
} else if (mySeg !== otherSeg) {
// both are strings, but they differ
return false;
}
// ok, no differences found
return true;
}
// ok, no differences found
return true;
};
// For util.inspect, console.log & co
inspect() {
// Quote the string
return JSON.stringify(this.toString());
}
}
// For JSON.stringify
URI.prototype.toJSON = URI.prototype.toString;
// For util.inspect, console.log & co
URI.prototype.inspect = function() {
// Quote the string
return JSON.stringify(this.toString());
};
module.exports = URI;
"use strict";
var url = require('url');
const utils = {};
var utils = {};
function robustDecodeURIComponent(uri) {

@@ -14,6 +12,6 @@ if (!/%/.test(uri)) {

} catch (e) {
return uri.replace(/(%[0-9a-fA-F][0-9a-fA-F])+/g, function(m) {
return uri.replace(/(%[0-9a-fA-F][0-9a-fA-F])+/g, (m) => {
try {
return decodeURIComponent(m);
} catch (e) {
} catch (error) {
return m;

@@ -27,8 +25,10 @@ }

// jscs:disable
var splitRe = /(\/)(?:\{([\+])?([^:\}\/]+)(?::([^}]+))?\}|([^\/\{]*))|(?:{([\/\+]))([^:\}\/]+)(?::([^}]+))?\}/g;
/* eslint-disable max-len */
const splitRe = /(\/)(?:\{([\+])?([^:\}\/]+)(?::([^}]+))?\}|([^\/\{]*))|(?:{([\/\+]))([^:\}\/]+)(?::([^}]+))?\}/g;
/* eslint-enable max-len */
// jscs:enable
function parsePattern(pattern) {
var res = [];
const res = [];
splitRe.lastIndex = 0;
var m;
let m;
do {

@@ -67,3 +67,3 @@ m = splitRe.exec(pattern);

// Parse a path or pattern
utils.parsePath = function(path, isPattern) {
utils.parsePath = (path, isPattern) => {
if (Array.isArray(path)) {

@@ -75,5 +75,5 @@ return path;

}
var bits = path.split('/');
const bits = path.split('/');
if (/%/.test(path)) {
for (var i = 0; i < bits.length; i++) {
for (let i = 0; i < bits.length; i++) {
if (/%/.test(bits[i])) {

@@ -90,3 +90,3 @@ bits[i] = robustDecodeURIComponent(bits[i]);

var unescapes = {
const unescapes = {
'%5B': '[',

@@ -105,4 +105,4 @@ '%5D': ']',

*/
utils.encodeReserved = function(string) {
var res = encodeURI(string);
utils.encodeReserved = (string) => {
const res = encodeURI(string);
if (!/[\[\]%]/.test(string)) {

@@ -113,29 +113,23 @@ return res;

// double percent escapes.
return res.replace(/%5B|%5D|%25/gi, function(m) {
return unescapes[m];
});
return res.replace(/%5B|%5D|%25/gi, (m) => unescapes[m]);
}
};
utils.toRFC822Date = function(date) {
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
utils.toRFC822Date = (date) => {
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
function numpad(x, digits) {
var result = Math.floor(x).toString();
let result = Math.floor(x).toString();
while (result.length < digits) {
result = '0' + result;
result = `0${result}`;
}
return result;
}
return days[date.getUTCDay()] + ", "
+ numpad(date.getUTCDate(), 2) + " "
+ months[date.getUTCMonth()] + " "
+ date.getUTCFullYear() + " "
+ numpad(date.getUTCHours(), 2) + ":"
+ numpad(date.getUTCMinutes(), 2) + ":"
+ numpad(date.getUTCSeconds(), 2) + " +0000";
return `${days[date.getUTCDay()]}, ${numpad(date.getUTCDate(), 2)} `
+ `${months[date.getUTCMonth()]} ${date.getUTCFullYear()} ${numpad(date.getUTCHours(), 2)}`
+ `:${numpad(date.getUTCMinutes(), 2)}:${numpad(date.getUTCSeconds(), 2)} +0000`;
};
module.exports = utils;
module.exports = utils;
{
"name": "swagger-router",
"version": "0.5.1",
"version": "0.5.2",
"description": "An efficient swagger 2 based router with support for multiple APIs. For use in RESTBase.",

@@ -39,9 +39,11 @@ "main": "index.js",

"devDependencies": {
"mocha": "^2.5.3",
"mocha": "^3.1.0",
"mocha-jshint": "^2.3.1",
"istanbul": "^0.4.3",
"istanbul": "^0.4.5",
"mocha-lcov-reporter": "^1.2.0",
"coveralls": "^2.11.9",
"mocha-jscs": "^5.0.0"
"coveralls": "^2.11.14",
"mocha-jscs": "^5.0.1",
"mocha-eslint":"^3.0.1",
"eslint-config-node-services": "^1.0.4"
}
}

@@ -7,1 +7,3 @@ 'use strict';

require('mocha-jscs')();
// Run eslint as part of normal testing
require('mocha-eslint')([ './lib', './index.js' ]);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc