Socket
Socket
Sign inDemoInstall

nano

Package Overview
Dependencies
Maintainers
2
Versions
155
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nano - npm Package Compare versions

Comparing version 1.3.0 to 1.3.1

22

error.js

@@ -0,1 +1,2 @@

var EventEmitter = require('events').EventEmitter;
var STATUS_CODES = { '100': 'Continue'

@@ -100,4 +101,23 @@ , '101': 'Switching Protocols'

}
function request_err(error, code, request, callback) {
if(typeof request === 'function') {
callback = request;
request = {};
}
error = gen_err('request', error, code, request);
if(callback) {
callback(error);
return request;
} else {
var em = new EventEmitter();
process.nextTick(function() { em.emit('error', error); });
return em;
}
}
exports.uncaught = function (e,c,r,s) { return gen_err('uncaught',e,c,r,s); };
exports.request = function (e,c,r,s) { return gen_err('request',e,c,r,s); };
exports.couch = function (e,c,r,s) { return gen_err('couch',e,c,r,s); };
exports.couch = function (e,c,r,s) { return gen_err('couch',e,c,r,s); };
exports.init = function (e,c,r,s) { return gen_err('init',e,c,r,s); };
exports.request_err = request_err;

57

logging.js
// Simple event+strategy-based logging for NanoCouch
// written by: Derek Perez
var verbose = (process.env.NANO_ENV==='testing');
var _ = require('underscore');
// snippet by Marak Squires.
// Generates a pesuedo-random identifier for a log event.
function randomString(len, charSet) {
charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var randomString = '';
var str = '';
for (var i = 0; i < len; i++) {
var randomPoz = Math.floor(Math.random() * charSet.length);
randomString += charSet.substring(randomPoz,randomPoz+1);
str += charSet.substring(randomPoz,randomPoz+1);
}
return randomString;
return str;
}
// logging generator, expects a strategy function
// to be provided on require of the module.
// a logging strategy should support two arguments,
// the first an `eventId` used to identify a group of
// log events that would be considered related. the second
// is an array of values that nano may pass to the logStrategy.
module.exports = function(logStrategy) {
module.exports = function logging(cfg) {
var logStrategy = cfg ? cfg.log : undefined;
this.cfg = cfg;
if (typeof logStrategy !== 'function') {
if(verbose) {
logStrategy = function consoleLog(eventId, args) {
console.log(eventId, args);
};
}
else logStrategy = function noop(){};
}
// if we've been provided no strategy
// for our logs, and verbose mode is active,
// simply pipe to console.log.
if (!logStrategy && verbose)
logStrategy = function(eventId, args) { console.log(eventId, args) };
// by default, if we have no logging
// strategy provided, we'll simply return
// an empty function, no output.
else if (!logStrategy)
logStrategy = function(){};
// the export returns the `logEvent` root function.
// calling this function returns a curried `log` function
// which will allow the user to associate all log hits with
// a unique log eventId. Providing a prefix is optional, simply
// prepends a string to the random string generator, for extra
// debugging goodness.
return function logEvent(prefix) {
var eventId = (prefix ? prefix+'-' : '') + randomString(10);
var eventId = (prefix ? prefix + '-' : '') + randomString(10);
return function log() {
logStrategy.call(this, eventId, _.toArray(arguments));
}
}
}
logStrategy.call(this, eventId,
[].slice.call(arguments,0)); // convert arguments into array
};
};
};

@@ -20,12 +20,16 @@ /* minimal couch in node

, qs = require('querystring')
, _ = require('underscore')
, u = require('url')
, error = require('./error')
, default_url = "http://localhost:5984"
, nano
;
function isEmpty(object) {
for(var property in object) {
if(object.hasOwnProperty(property)) return false; }
return true;
}
/*
* nano is a library that helps you building requests to couchdb
* that is built on top of mikeals/request
* that is built on top of mikeal/request
*

@@ -38,32 +42,11 @@ * no more, no less

module.exports = exports = nano = function database_module(cfg) {
var public_functions = {}, path, db;
if(typeof cfg === "string") {
if(/^https?:/.test(cfg)) { cfg = {url: cfg}; } // url
else {
try { cfg = require(cfg); } // file path
catch(e) { console.error("bad cfg: couldn't load file"); }
}
}
if(!cfg) {
console.error("bad cfg: you passed undefined");
cfg = {};
}
if(cfg.proxy || !cfg.jar) {
var opts = {};
if(cfg.proxy) opts.proxy = cfg.proxy;
if(!cfg.jar) opts.jar = false;
request = require('request').defaults(opts);
}
if(!cfg.url) {
console.error("bad cfg: using default=" + default_url);
cfg = {url: default_url}; // if everything else fails, use default
}
var public_functions = {}
, request_opts = {}
, logging
, path
, path_array
, db
, auth
;
// configure logging strategy for this
// instance of nano
var logging = require('./logging')(cfg.log);
logging("cfg")(cfg);
path = u.parse(cfg.url);
/****************************************************************************

@@ -102,58 +85,78 @@ * relax *

var log = logging();
try {
var headers = { "content-type": "application/json"
, "accept": "application/json"
}
, req = { method: (opts.method || "GET"), headers: headers
, uri: cfg.url + "/" + opts.db }
, params = opts.params
, status_code
, parsed
, rh;
var headers = { "content-type": "application/json"
, "accept" : "application/json"
}
, req = { method : (opts.method || "GET")
, headers: headers
, uri : cfg.url + "/" + opts.db }
, params = opts.params
, status_code
, parsed
, rh
;
if (opts.jar) {
req.jar = opts.jar;
}
if (opts.jar) { req.jar = opts.jar; }
if(opts.path) {
req.uri += "/" + opts.path;
if(opts.path) { req.uri += "/" + opts.path; }
else if(opts.doc) {
if(!/^_design/.test(opts.doc)) {
try { req.uri += "/" + encodeURIComponent(opts.doc); }
catch (ex1) {
ex1.message = 'couldnt encode: ' + opts.doc + ' as an uri';
return error.request_err(ex, 'encodeuri', {});
}
}
else if(opts.doc) {
if(!/^_design/.test(opts.doc)) {
// add the document to the url
req.uri += "/" + encodeURIComponent(opts.doc);
else {
req.uri += "/" + opts.doc;
}
if(opts.att) { req.uri += "/" + opts.att; }
}
if(opts.encoding && callback) {
req.encoding = opts.encoding;
delete req.headers["content-type"];
delete req.headers.accept;
}
if(opts.content_type) {
req.headers["content-type"] = opts.content_type;
delete req.headers.accept; // undo headers set
}
if(!isEmpty(params)) {
['startkey', 'endkey', 'key', 'keys'].forEach(function (key) {
if (key in params) {
try { params[key] = JSON.stringify(params[key]); }
catch (ex2) {
ex2.message = 'bad params: ' + key + ' = ' + params[key];
return error.request_err(ex, 'jsonstringify', {});
}
}
else {
req.uri += "/" + opts.doc;
}
// add the attachment to the url
if(opts.att) { req.uri += "/" + opts.att; }
});
try { req.uri += "?" + qs.stringify(params); }
catch (ex3) {
ex3.message = 'invalid params: ' + params.toString();
return error.request_err(ex3, 'qsstringify', {});
}
if(opts.encoding && callback) {
req.encoding = opts.encoding;
delete req.headers["content-type"];
delete req.headers.accept;
}
if(!callback) { // void callback, stream
try {
return request(req);
} catch (ex4) {
return error.request_err(ex4, 'streamthrow', {});
}
if(opts.content_type) {
req.headers["content-type"] = opts.content_type;
delete req.headers.accept; // undo headers set
}
if(opts.body) {
if (Buffer.isBuffer(opts.body)) {
req.body = opts.body; // raw data
}
//if(cfg.cookie){
// req.headers.cookie = cfg.cookie;
//}
if(!_.isEmpty(params)) {
['startkey', 'endkey', 'key', 'keys'].forEach(function (key) {
if (key in params) { params[key] = JSON.stringify(params[key]); }
});
req.uri += "?" + qs.stringify(params);
}
if(!callback) { return request(req); } // void callback, pipe
if(opts.body) {
if (Buffer.isBuffer(opts.body)) {
req.body = opts.body; // raw data
else {
try {
req.body = JSON.stringify(opts.body);
} catch (ex5) {
ex5.message = "couldn't json.stringify the body you provided";
return error.request_err(ex5, 'jsonstringify', {}, callback);
}
else { req.body = JSON.stringify(opts.body); } // json data
}
log(req);
request(req, function(e,h,b){
} // json data
}
log(req);
try {
var stream = request(req, function(e,h,b){
rh = (h && h.headers || {});

@@ -164,30 +167,24 @@ rh['status-code'] = status_code = (h && h.statusCode || 500);

log({err: 'socket', body: b, headers: rh });
return callback(error.request(e,"socket",req,status_code),b,rh);
callback(error.request(e,"socket",req,status_code),b,rh);
return stream;
}
// prevent security vunerabilities related to couchdb
delete rh.server;
// prevent problems with trims and stalled responses
delete rh['content-length'];
// did we get json or binary?
try { parsed = JSON.parse(b); } catch (err) { parsed = b; }
if (status_code >= 200 && status_code < 300) {
//if (rh['set-cookie']){
// cfg.cookie = rh['set-cookie']; //get auth cookie
//}
log({err: null, body: parsed, headers: rh});
callback(null,parsed,rh);
return stream;
}
else { // proxy the error directly from couchdb
log({err: 'couch', body: parsed, headers: rh});
if (!parsed) { parsed = {}; } // if HEAD request, body will be undefined
if (!parsed) { parsed = {}; }
callback(error.couch(parsed.reason,parsed.error,req,status_code),
parsed, rh);
return stream;
}
});
} catch(exc) {
if (callback) {
log({err: 'uncaught', body: exc});
callback(error.uncaught(exc));
}
else { console.error({err: 'uncaught', body: exc}); }
return stream;
} catch(ex6) {
return error.request_err(ex6, 'callbackthrow', {});
}

@@ -327,32 +324,2 @@ }

/****************************************************************************
* session *
***************************************************************************/
/*
* creates session
*
* e.g. nano.session.create(user, password)
*
* @param {user:string} user name
* @param {pass:string} password
*
* @see relax
*/
//function create_session(user, password, callback) {
// var body = new Buffer("name=" + user + "&" + "password=" + password);
// return relax({db: "_session", body:body, method: "POST", content_type: "application/x-www-form-urlencodeddata"}, callback);
//}
/*
* destroy session
*
* e.g. nano.session.destroy()
*
* @see relax
*/
//function destroy_session(callback) {
// cfg.cookie = null; //make sure cookie gets destroyed also if error
// return relax({db: "_session", method: "DELETE"}, callback);
//}
/****************************************************************************
* doc *

@@ -437,2 +404,21 @@ ***************************************************************************/

/*
* bulk fetch functionality
* [1]: http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API
*
* @param {doc_names:object} document keys as per the couchdb api[1]
* @param {params:object} additions to the querystring, note that include_docs is always set to true
*
* @see get_doc
* @see relax
*/
function fetch_docs(doc_names,params,callback) {
if(typeof params === "function") {
callback = params;
params = {};
}
params.include_docs = true;
return relax({db: db_name, path: "_all_docs", method: "POST", params: params, body: doc_names},callback);
}
/*
* calls a view

@@ -473,13 +459,17 @@ *

*/
function update_with_handler_doc(design_name, update_name, doc_name, params, callback) {
function update_with_handler_doc(design_name, update_name,
doc_name, params, callback) {
if(typeof params === "function") {
callback = params;
params = {};
params = {};
}
var update_path = '_design/' + design_name + '/_update/' + update_name + '/' + doc_name;
return relax({db: db_name, path: update_path, method: "PUT", params: params}, callback);
var update_path = '_design/' + design_name + '/_update/' +
update_name + '/' + doc_name;
return relax(
{ db: db_name, path: update_path, method: "PUT"
, params: params }, callback);
}
/*
* bulk fetch/update/delete/insert functionality
* bulk update/delete/insert functionality
* [1]: http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API

@@ -498,3 +488,5 @@ *

}
return relax({db: db_name, path: "_bulk_docs", body: docs, method: "POST", params: params}, callback);
return relax(
{ db: db_name, path: "_bulk_docs", body: docs
, method: "POST", params: params}, callback);
}

@@ -532,4 +524,6 @@

}
return relax({ db: db_name, att: att_name, method: "PUT", content_type: content_type
, doc: doc_name, params: params, body: att},callback);
return relax(
{ db: db_name, att: att_name, method: "PUT"
, content_type: content_type, doc: doc_name, params: params
, body: att}, callback);
}

@@ -577,3 +571,5 @@

}
, compact: function(cb) { return compact_db(db_name,cb); }
, compact: function(cb) {
return compact_db(db_name,cb);
}
, changes: function(params,cb) {

@@ -587,2 +583,3 @@ return changes_db(db_name,params,cb);

, list: list_docs
, fetch: fetch_docs
, config: {url: cfg.url, db: db_name}

@@ -597,3 +594,3 @@ , attachment: { insert: insert_att

public_functions.view.compact = function(design_name,cb) {
return compact_db(db_name,design_name,cb);
return compact_db(db_name,design_name,cb);
};

@@ -613,9 +610,5 @@ return public_functions;

}
//, session: { create: create_session
// , destroy: destroy_session
// }
, use: document_module
, scope: document_module // alias
, request: relax
, config: cfg
, relax: relax // alias

@@ -625,6 +618,43 @@ , dinosaur: relax // alias

// does the user want a database, or nano?
if(path.pathname && !_.isEmpty(path.pathname.split('/')[1])) {
var auth = path.auth ? path.auth + '@' : '';
db = path.pathname.split('/')[1];
if(typeof cfg === "string") {
if(/^https?:/.test(cfg)) { cfg = {url: cfg}; } // url
else {
try { cfg = require(cfg); } // file path
catch(e) {
e.message = "couldn't read config file " +
(cfg ? cfg.toString() : '');
throw error.init(e, "badfile");
}
}
}
if(!(cfg && cfg.url))
throw error.init("no configuration with a valid url was given", "badurl");
public_functions.config = cfg;
if(cfg.proxy || cfg.jar) {
if(cfg.proxy)
request_opts.proxy = cfg.proxy;
request_opts.jar = !!cfg.jar;
request = require('request').defaults(request_opts);
}
// assuming a cfg.log inside cfg
logging = require('./logging')(cfg);
try {
path = u.parse(cfg.url);
path_array = path.pathname.split('/').filter(function(e) { return e; });
}
catch (e2) {
e2.message = "your url is invalid: " + cfg.url;
throw error.init(e2, "invalidurl");
}
// nano('http://couch.nodejitsu.com/db1') should return a database
// nano('http://couch.nodejitsu.com') should return a nano object
if(path.pathname && path_array.length > 0) {
auth = path.auth ? path.auth + '@' : '';
db = path_array[0];
cfg.url = path.protocol + '//' + auth + path.hostname; // reset url

@@ -634,2 +664,3 @@ return document_module(db);

else { return public_functions; }
};

@@ -636,0 +667,0 @@

@@ -5,3 +5,3 @@ { "name" : "nano"

, "repository" : "git://github.com/dscape/nano"
, "version" : "1.3.0"
, "version" : "1.3.1"
, "author" : "Nuno Job <nunojobpinto@gmail.com> (http://nunojob.com)"

@@ -16,2 +16,3 @@ , "contributors" :

, "Dale Harvey <dale@arandomurl.com> (http://arandomurl.com)"
, "Jan Lehnardt <jan@apache.org> (http://jan.prima.de/plok/)"
, "InTheFiveByFive"

@@ -21,3 +22,3 @@ ]

["couchdb", "data", "request", "json", "nosql", "micro", "nano", "database"]
, "dependencies" : {"request": "2.9.3", "underscore": "1.2.3"}
, "dependencies" : {"request": "2.9.x"}
, "devDependencies" :

@@ -27,2 +28,3 @@ { "async": "0.1.15", "ensure": "0.4.6", "nock": "0.5.5"

, "inherits": "1.0.0", "yamlish": "0.0.2", "slide": "1.1.3"
, "underscore": "1.3.1"
}

@@ -29,0 +31,0 @@ , "scripts" : { "test": "./node_modules/ensure/bin/tap.js tests/*/*.js" }

@@ -47,2 +47,3 @@ var ensure = require('ensure')

tests.att_des = function (callback) {
console.log(require('../../nano'))
nano.db.create(db_name("a"), function () {

@@ -49,0 +50,0 @@ db("a").attachment.insert("new", "att", "Hello World!", "text/plain",

@@ -72,14 +72,5 @@ var ensure = require('ensure')

tests.bad_file = function (callback) { callback(null,nano('notafile')); };
tests.bad_file_ok = function (_,e) { this.t.equal(e.config.url,"http://localhost:5984"); };
tests.obj_cfg = function (callback) { callback(null,nano(cfg)); };
tests.obj_cfg_ok = function (_,n) { this.t.equal(n.config.url, cfg.url); };
tests.not_string_or_object = function (callback) { callback(null,nano(false)); };
tests.not_string_or_object_ok = function (_,e) { this.t.equal(e.config.url,"http://localhost:5984"); };
tests.nano_undefined = function (callback) { callback(null,nano()); };
tests.nano_undefined_ok = function (_,e) { this.t.equal(e.config.url,"http://localhost:5984"); };
ensure(__filename,tests,module,process.argv[2]);
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