Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

connect-rest

Package Overview
Dependencies
Maintainers
1
Versions
190
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

connect-rest - npm Package Compare versions

Comparing version 0.0.15 to 0.0.16

89

lib/connect-rest.js

@@ -6,3 +6,3 @@ /*

*/
var VERSION = '0.0.15';
var VERSION = '0.0.16';

@@ -44,11 +44,11 @@ var connect = require('connect');

function addPath(key, path, action, prototypeObject, validator){
mapping[ key ].push( new Route( path, prototypeObject, validator,
function addPath(key, path, action, prototypeObject, options){
mapping[ key ].push( new Route( path, prototypeObject, options,
function(request, content, callback){
if(action.length == 3) {
action(request, content, function(err, result){
callback(err, result);
callback(err, { contentType: options.contentType || 'application/json', result : result } );
});
} else {
callback(null, action(request, content));
callback(null, { contentType: options.contentType || 'application/json', result : action(request, content) } );
}

@@ -65,7 +65,7 @@ }, _

var routes = _.filter(
mapping[ method ], function(route){ return route.matches(
var routes = _.filter(
mapping[ method ], function(route){ return route.matches(
null, pathname, CONTEXT, version, _, semver, false
); }
);
);

@@ -95,4 +95,4 @@ return routes.length > 0 ? _.first( _.map( routes, function(route){ return route.prototypeObject; } ) ) : 'No matching service';

var callChain = _.map( matching, function(func){
return async.apply( func, {headers: req.headers, parameters: req.query}, bodyObj );
var callChain = _.map( matching, function(func){
return async.apply( func, {headers: req.headers, parameters: req.query}, bodyObj );
} );

@@ -108,28 +108,29 @@

res.statusCode = err.statusCode || 500;
res.end( 'Error occurred: ' + err );
res.end( 'Error occurred: ' + err );
}
else{
res.writeHead(200, {'Content-Type': 'application/json'});
var result = _.find(results, function(returnValue){ return returnValue; });
if( result )
res.end( JSON.stringify( result ) );
var result = _.find(results, function(returnValue){ return returnValue && returnValue.result; }) || {};
console.log( '%j', result );
res.writeHead(200, {'Content-Type': result.contentType || 'application/json'});
res.end( result && result.result ? ((result.contentType == 'application/json') ? JSON.stringify( result.result ) : result.result) : '' );
}
}
);
);
}
exports.head = function headRest(path, functionRef, validator){
addPath("HEAD", path, functionRef, null, validator);
exports.head = function headRest(path, functionRef, options){
addPath("HEAD", path, functionRef, null, options || {} );
};
exports.get = function getRest(path, functionRef, validator){
addPath("GET", path, functionRef, null, validator);
exports.get = function getRest(path, functionRef, options){
addPath("GET", path, functionRef, null, options || {} );
};
exports.post = function postRest(path, functionRef, prototypeObject, validator){
addPath("POST", path, functionRef, prototypeObject, validator);
exports.post = function postRest(path, functionRef, prototypeObject, options){
addPath("POST", path, functionRef, prototypeObject, options || {} );
};
exports.put = function putRest(path, functionRef, prototypeObject, validator){
addPath("PUT", path, functionRef, prototypeObject, validator);
exports.put = function putRest(path, functionRef, prototypeObject, options){
addPath("PUT", path, functionRef, prototypeObject, options || {} );
};
exports.delete = function deleteRest(path, functionRef, prototypeObject, validator){
addPath("DELETE", path, functionRef, prototypeObject, validator);
exports.delete = function deleteRest(path, functionRef, prototypeObject, options){
addPath("DELETE", path, functionRef, prototypeObject, options || {} );
};

@@ -156,5 +157,5 @@

if( options.discoverPath )
addPath('GET', options.discoverPath + '/:version', discover );
addPath('GET', options.discoverPath + '/:version', discover );
if( options.protoPath )
addPath('GET', options.protoPath + '/*path', protoPather );
addPath('GET', options.protoPath + '/*path', protoPather );
API_KEYS = options.apiKeys;

@@ -197,3 +198,3 @@

res.statusCode = 401;
res.end( 'API_KEY is required.' );
res.end( 'API_KEY is required.' );
return;

@@ -206,7 +207,7 @@ }

var routes = _.filter(
mapping[ req.method ], function(route){ return route.matches(
var routes = _.filter(
mapping[ req.method ], function(route){ return route.matches(
req, pathname, CONTEXT, req.headers['accept-version'] || req.headers['x-api-version'] || '*', _, semver, true
) && (!route.validator || route.validator(req, res) ); }
);
) && (!route.options.validator || route.options.validator(req, res) ); }
);
var matching = _.map( routes, function(route){ return route.action; } );

@@ -225,11 +226,11 @@

} else{
var body = '';
req.on('data', function(chunk) {
body += chunk;
if (body.length > LOAD_SIZE_LIMIT) {
req.connection.destroy();
}
});
var body = '';
req.on('data', function(chunk) {
body += chunk;
if (body.length > LOAD_SIZE_LIMIT) {
req.connection.destroy();
}
});
req.on('end', function() {
req.on('end', function() {
logger.debug('Body payload: ', body );

@@ -240,5 +241,5 @@

process(req, res, matching, bodyObj);
} );
}
};
} );
}
};
};

@@ -245,0 +246,0 @@

@@ -26,3 +26,3 @@ var PARAMETER_M_DELIMETER = ':';

else if( this.isString ){
if (this.path == '*')
if (this.path == '*')
return true;

@@ -33,4 +33,5 @@

if( _( _.last( ptokens ) ).startsWith( PARAMETER_O_DELIMETER ) && utokens.length == ptokens.length-1 )
utokens.push('');
for (var i=0;i<ptokens.length;i++)
if( _( ptokens[i] ).startsWith( PARAMETER_O_DELIMETER ) && utokens.length <= i )
utokens.push('');

@@ -48,13 +49,13 @@ if( _( _.last( ptokens ) ).startsWith( PARAMETER_G_DELIMETER ) ){

var parameterReplacements = {};
for (var i=0;i<utokens.length;i++){
if( _( ptokens[i] ).startsWith( PARAMETER_M_DELIMETER ) )
parameterReplacements[ ptokens[i].substring( PARAMETER_M_DELIMETER.length ) ] = utokens[i];
else if( _( ptokens[i] ).startsWith( PARAMETER_G_DELIMETER ) )
parameterReplacements[ ptokens[i].substring( PARAMETER_G_DELIMETER.length ) ] = utokens[i];
else if( _( ptokens[i] ).startsWith( PARAMETER_O_DELIMETER ) ){
if( utokens[i].length>0 )
parameterReplacements[ ptokens[i].substring( PARAMETER_O_DELIMETER.length ) ] = utokens[i];
for (var t=0; t<utokens.length; t++){
if( _( ptokens[t] ).startsWith( PARAMETER_M_DELIMETER ) )
parameterReplacements[ ptokens[t].substring( PARAMETER_M_DELIMETER.length ) ] = utokens[t];
else if( _( ptokens[t] ).startsWith( PARAMETER_G_DELIMETER ) )
parameterReplacements[ ptokens[t].substring( PARAMETER_G_DELIMETER.length ) ] = utokens[t];
else if( _( ptokens[t] ).startsWith( PARAMETER_O_DELIMETER ) ){
if( utokens[t].length>0 )
parameterReplacements[ ptokens[t].substring( PARAMETER_O_DELIMETER.length ) ] = utokens[t];
}
else {
if( ptokens[i].toUpperCase() != utokens[i].toUpperCase() )
if( ptokens[t].toUpperCase() != utokens[t].toUpperCase() )
return false;

@@ -65,3 +66,3 @@ }

_.each(parameterReplacements, function(value, key, list){
req.query[ key ] = value;
req.query[ key ] = value;
});

@@ -72,4 +73,3 @@

else if( this.isObject ){
return (this.isSubReged ? this.path.path.test( pathname ) : this.path.path == '*' || (this.path.path.toUpperCase()==pathname.toUpperCase()) ) &&
matchesVersion( semver, version, this.path.version );
return (this.isSubReged ? this.path.path.test( pathname ) : this.path.path == '*' || (this.path.path.toUpperCase()==pathname.toUpperCase()) ) && matchesVersion( semver, version, this.path.version );
}

@@ -76,0 +76,0 @@ return false;

var Path = require('./path');
function Route(path, prototypeObject, validator, action, _){
this.action = action;
this.prototypeObject = prototypeObject;
this.validator = validator;
this.paths = [];
function Route(path, prototypeObject, options, action, _){
this.action = action;
this.prototypeObject = prototypeObject;
this.options = options || {};
this.paths = [];
if( !path || !action || !_.isFunction( action ) )
throw new Error('You need to give proper parameters.');
if( !path || !action || !_.isFunction( action ) )
throw new Error('You need to give proper parameters.');
if( _.isArray( path ) ){
this.paths = _.map( path, function(element){ return new Path( element, _ ); } );
} else{
this.paths.push( new Path( path, _ ) );
}
if( _.isArray( path ) ){
this.paths = _.map( path, function(element){ return new Path( element, _ ); } );
} else{
this.paths.push( new Path( path, _ ) );
}
}

@@ -31,11 +31,11 @@

Route.prototype.matchings = function( version, _, semver ){
var found = _.map(
_.filter( this.paths, function( path ){ return path.matchings( version, _, semver); } ), function(path){
return path.path;
}
);
var found = _.map(
_.filter( this.paths, function( path ){ return path.matchings( version, _, semver); } ), function(path){
return path.path;
}
);
return found;
return found;
};
module.exports = Route;
{
"name": "connect-rest",
"version": "0.0.15",
"version": "0.0.16",
"description": "RESTful web services middleware for Connect.",

@@ -49,4 +49,4 @@ "keywords": [

"readme": "README.md",
"_id": "connect-rest@0.0.15",
"_from": "connect-rest@>=0.0.15"
"_id": "connect-rest@0.0.16",
"_from": "connect-rest@>=0.0.16"
}

@@ -28,3 +28,3 @@ [connect-rest](https://github.com/imrefazekas/connect-rest) is a middleware for [connect](http://www.senchalabs.org/connect/) for building REST APIs providing service discovery and path-based parameter mapping and "reflective" publishing and node domains as well.

- [Domain support](#domain-support)
- [Validation](#validation)
- [Customization: Validation and Response mime-types](#customization)

@@ -288,9 +288,18 @@ ## Assign

## Validation
## Customization
When assigning routes with rest API you can pass a validation function as well, which can be used to determine if the REST function can be called in a given circumstances or should be ignored. This could mean authorization or ip address validation or other security concern.
When assigning routes with rest API you can pass an object too. This object looks like this:
{
contentType: ''
validator: ...
}
The contentType defines what the given REST service will retrieve. If not given, 'application/json' will be used.
The validator is a function, which can be used to determine if the REST function can be called in a given circumstances or should be ignored. This could mean authorization or ip address validation or other security concern.
rest.post( [ { path: '/shake', version: '>=2.0.0' }, { path: '/twist', version: '>=2.1.1' } ], function( request, content ){
return JSON.stringify(content);
}, null, function(req, res){ return _.contains(req.user.roles, "superuser"); } );
}, null, { contentType:'application/xml', validator: function(req, res){ return _.contains(req.user.roles, "superuser"); } } );

@@ -358,2 +367,5 @@

- 0.0.16:
- better optional parameter handling allowing to use optional parameter chain like: /set/?depoartment/?room
- rewritten assing services. instead of passing a single validator, one has to pass on optional object: { contentType: '', validator: ...} which allows one to define validator and answer return content mime-type as well.
- 0.0.15 : Great changes from Joel Grenon, thank you! Standard callbacks introduced, better optional parameter handling and respecting error status code if exists

@@ -360,0 +372,0 @@ - 0.0.14 : Adding grunt project files

@@ -92,3 +92,3 @@ var opt = {

var voptions = _.clone( opt );
voptions.path = '/api/make';
voptions.path = '/api/make?api_key=849b7648-14b8-4154-9ef2-8d1dc4c2b7e9';
voptions.method = 'POST';

@@ -124,2 +124,24 @@ voptions.headers['accept-version'] = '1.1';

function testCall8a(http, _, callback){
var voptions = _.clone( opt );
voptions.method = 'GET';
voptions.path = '/api/set?api_key=849b7648-14b8-4154-9ef2-8d1dc4c2b7e9';
generalCall( http, voptions, callback );
}
function testCall8b(http, _, callback){
var voptions = _.clone( opt );
voptions.method = 'GET';
voptions.path = '/api/set/abraka?api_key=849b7648-14b8-4154-9ef2-8d1dc4c2b7e9';
generalCall( http, voptions, callback );
}
function testCall8c(http, _, callback){
var voptions = _.clone( opt );
voptions.method = 'GET';
voptions.path = '/api/set/abraka/dabra?api_key=849b7648-14b8-4154-9ef2-8d1dc4c2b7e9';
generalCall( http, voptions, callback );
}
exports.testCall1 = testCall1;

@@ -133,1 +155,5 @@ exports.testCall2 = testCall2;

exports.testCall7 = testCall7;
exports.testCall8a = testCall8a;
exports.testCall8b = testCall8b;
exports.testCall8c = testCall8c;

@@ -14,20 +14,23 @@ function buildUpRestAPI( rest, _ ){

console.log( 'Received:' + JSON.stringify( request ) + ' ' + JSON.stringify(content) );
callback(null, 'ok');
return callback(null, 'ok');
});
rest.get('/inquire/*book', function( request, content, callback ){
console.log( 'Received:' + JSON.stringify( request ) + ' ' + JSON.stringify(content) );
callback(null, 'ok');
return callback(null, 'ok');
});
rest.get( '/set/?rid/?facet', function( request, content, callback ){
console.log( 'Received:' + JSON.stringify( request ) + ' ' + JSON.stringify(content) );
return callback(null, 'ok');
});
rest.post( { path: '/make', version: '>=1.0.0' }, function( request, content, callback ){
console.log( 'Received:' + JSON.stringify( request ) + ' ' + JSON.stringify(content) );
callback(null, 'ok');
return callback(null, 'ok');
});
rest.post( [ '/act', '/do' ], function( request, content, callback ){
console.log( 'Received:' + JSON.stringify( request ) + ' ' + JSON.stringify(content) );
callback( null, 'ok' );
return callback( null, 'ok' );
});
rest.post( [ { path: '/shake', version: '>=2.0.0' }, { path: '/twist', version: '>=2.1.1' } ], function( request, content, callback ){
console.log( 'Received:' + JSON.stringify( request ) + ' ' + JSON.stringify(content) );
//throw new Error('Shake error...');
callback(null, 'ok');
return callback(null, 'ok');
}, {'title': 'Alice in Wonderland'} );

@@ -34,0 +37,0 @@ }

@@ -60,10 +60,13 @@ var rest = require('../lib/connect-rest');

async.parallel([
async.apply( caller.testCall1, http, _ ),
async.apply( caller.testCall2, http, _ ),
async.apply( caller.testCall3a, http, _ ),
async.apply( caller.testCall3b, http, _ ),
async.apply( caller.testCall4, http, _ ),
async.apply( caller.testCall5, http, _ ),
async.apply( caller.testCall6, http, _ ),
async.apply( caller.testCall7, http, _ )
// async.apply( caller.testCall1, http, _ ),
// async.apply( caller.testCall2, http, _ ),
// async.apply( caller.testCall3a, http, _ ),
// async.apply( caller.testCall3b, http, _ ),
// async.apply( caller.testCall4, http, _ ),
// async.apply( caller.testCall5, http, _ ),
// async.apply( caller.testCall6, http, _ ),
// async.apply( caller.testCall7, http, _ ),
async.apply( caller.testCall8a, http, _ ),
async.apply( caller.testCall8b, http, _ ),
async.apply( caller.testCall8c, http, _ )
], function(err, results){

@@ -70,0 +73,0 @@ console.log('Tests finished.');

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