Comparing version 0.0.2 to 0.0.3
var cartodb = require('../'); | ||
var CartoDB = require('../'); | ||
var secret = require('./secret.js'); | ||
var client = new cartodb.CartoDBClientApiKey(secret.USER, secret.API_KEY); | ||
// please, fill secret.js using secret.js.example before launch the demo | ||
var client = new CartoDB({user:secret.USER, api_key:secret.API_KEY}); | ||
@@ -12,8 +13,6 @@ client.on('connect', function() { | ||
// this is not required for ApiKey client, see below | ||
client.connect(); | ||
client.on('data', function(data) { | ||
var results = JSON.parse(data); | ||
console.log(results.rows); | ||
console.log(data.rows); | ||
}); | ||
@@ -25,11 +24,5 @@ | ||
// request two queries | ||
client.sql("select * from tracker limit 5"); | ||
client.sql("select * from tracker limit 5 offset 5"); | ||
// request two queries, put here your tables | ||
client.query("select * from {table} limit 5", {table: 'tracker'}); | ||
client.query("select * from tracker limit 5 offset 5"); | ||
// the process do not finish here, client connection is persistent | ||
// so you have to finish the process manually | ||
// if you dont call client.connect the connection will not be persistent | ||
// so the process will finish after the two request finish | ||
@@ -1,184 +0,219 @@ | ||
// OAuth supports 3 legged and 2 legged (aka XAuth) authentication. | ||
// This app demonstrates how to use 2 legged authentication with CartoDB | ||
/* | ||
* Module dependencies | ||
*/ | ||
var sys = require('sys') | ||
, querystring = require('querystring') | ||
, OAuth = require('oauth').OAuth | ||
, EventEmitter = require('events').EventEmitter | ||
, util = require('util') | ||
, https = require('https'); | ||
var qs = require('querystring') | ||
, OAuth = require('oauth').OAuth | ||
, EventEmitter = require('events').EventEmitter | ||
, util = require('util') | ||
, request = require('superagent') | ||
, resources = require('./resources.json'); | ||
/* | ||
* Alias | ||
*/ | ||
var debug = util.debug | ||
var log = util.log | ||
, log = util.log; | ||
function CartoDBClient(user, password, consumer_key, consumer_secret) { | ||
this.user = user; | ||
var cartodb_request_url = 'https://' + user + '.cartodb.com/oauth/request_token' | ||
this.cartodb_access_url = 'https://' + user + '.cartodb.com/oauth/access_token' | ||
this.cartodb_api_url = 'https://' + user + '.cartodb.com/api/v1/sql'; | ||
this.password = password; | ||
this.oa = new OAuth(cartodb_request_url, this.cartodb_access_url, consumer_key, consumer_secret, "1.0", null, "HMAC-SHA1"); | ||
} | ||
/* | ||
* Constructor | ||
* | ||
* @param {Object} Connection params | ||
* | ||
* @api public | ||
*/ | ||
CartoDBClient.prototype = new EventEmitter(); | ||
function CartoDB(params) { | ||
CartoDBClient.prototype.connect = function() { | ||
var self = this; | ||
debug('connecting'); | ||
self.oa.getOAuthRequestToken(function(error, request_key, request_secret, results){ | ||
if(error) log('error :' + error); | ||
else { | ||
debug('\n== Request Tokens =='); | ||
debug('request key :' + request_key); | ||
debug('request secret :' + request_secret); | ||
for(var i in params){ | ||
this[i] = params[i]; | ||
} | ||
// Configure XAuth request | ||
var xauth = {x_auth_mode:"client_auth", x_auth_username: self.user , x_auth_password: self.password }; | ||
this.api_url = resources.api_url.replace(':user', this.user); | ||
// Request access key and secret tokens via XAuth | ||
// ** NOTE: Do NOT post the request_secret in argument 3 ** | ||
debug("\nRequesting access tokens via XAuth..."); | ||
self.oa.post(self.cartodb_access_url, request_key, null, xauth, null, function(error, data) { | ||
if(error) { | ||
debug(require('sys').inspect(error)); | ||
throw new Error("...XAuth failed. Please check your password and username."); | ||
} else { | ||
debug("...XAuth successful!"); | ||
if(this.consumer_key && this.consumer_secret){ | ||
this.request_url = resources.request_url.replace(':user', this.user); | ||
this.access_url = resources.access_url.replace(':user', this.user); | ||
// Parse access tokens from returned query string | ||
var access_tokens = querystring.parse(data); | ||
self.access_key = access_tokens['oauth_token']; | ||
self.access_secret = access_tokens['oauth_token_secret']; | ||
self.emit('connect'); | ||
} | ||
}); | ||
} | ||
}); | ||
this.connect = this.connectOAuth; | ||
this.query = this.queryOAuth; | ||
} | ||
this.oa = new OAuth( | ||
this.request_url | ||
, this.access_url | ||
, this.consumer_key | ||
, this.consumer_secret | ||
, "1.0" | ||
, null | ||
, "HMAC-SHA1" | ||
); | ||
} | ||
/** | ||
* renders a template | ||
* tmpl("Hi {name}", {name: 'rambo'}) renders "Hi rambo" | ||
/* | ||
* Inheritance | ||
*/ | ||
function tmpl(s,d){ | ||
for(var p in d) | ||
s=s.replace(new RegExp('{'+p+'}','g'), d[p]); | ||
return s; | ||
} | ||
/** | ||
* executes a sql sentence in cartodb. When request is complete 'data' event is emitted, if something went wroing 'error' | ||
* is emitted | ||
util.inherits(CartoDB, EventEmitter); | ||
/* | ||
* Connect to CartoDB | ||
* | ||
* @api public | ||
*/ | ||
CartoDBClient.prototype.sql = function(_sql, args) { | ||
var sql = tmpl(_sql, args); | ||
debug("sending", sql) | ||
var self = this; | ||
function _response(error, data, response) { | ||
if(error) { | ||
self.emit('error', error); | ||
} else { | ||
self.emit('data', data, response); | ||
CartoDB.prototype.connectOAuth = function() { | ||
var self = this; | ||
self.oa.getOAuthRequestToken(function(error, request_key, request_secret, results){ | ||
if(error) throw error; | ||
else { | ||
// Configure XAuth request | ||
var xauth = { | ||
x_auth_mode: "client_auth" | ||
, x_auth_username: self.user | ||
, x_auth_password: self.password | ||
}; | ||
// Request access key and secret tokens via XAuth | ||
// ** NOTE: Do NOT post the request_secret in argument 3 ** | ||
self.oa.post(self.access_url, request_key, null, xauth, null, function(error, data) { | ||
if(error) throw error; | ||
else { | ||
// Parse access tokens from returned query string | ||
var access_tokens = qs.parse(data); | ||
self.access_key = access_tokens['oauth_token']; | ||
self.access_secret = access_tokens['oauth_token_secret']; | ||
self.emit('connect'); | ||
} | ||
}); | ||
} | ||
if(sql.length > 2048) { | ||
var protected_request = this.cartodb_api_url + "?q=" + querystring.escape(sql); | ||
this.oa.get(protected_request, this.access_key, this.access_secret, _response); | ||
} else { | ||
var protected_request = this.cartodb_api_url; | ||
var body = {q: sql} | ||
this.oa.post(protected_request, this.access_key, this.access_secret, body, null, _response) | ||
} | ||
} | ||
}); | ||
}; | ||
/** | ||
* executes a sql query in cartodb. | ||
* When request is complete 'data' event is emitted, | ||
* if something went wrong 'error' | ||
* is emitted | ||
* | ||
* @param {String} sql query | ||
* @param {Object} arguments | ||
* @api public | ||
*/ | ||
function CartoDBClientApiKey(user, api_key) { | ||
this.opt = {} | ||
this.user = user; | ||
this.api_key = api_key; | ||
this.cartodb_host = user + '.cartodb.com'; | ||
this.cartodb_api_path = '/api/v1/sql'; | ||
} | ||
CartoDB.prototype.queryOAuth = function(_sql, args) { | ||
CartoDBClientApiKey.prototype = new EventEmitter(); | ||
var self = this; | ||
CartoDBClientApiKey.prototype.connect = function(callback) { | ||
this.opt.keep_alive = true; | ||
this.emit('connect'); | ||
var sql = tmpl(_sql, args); | ||
function _response(error, data, response) { | ||
if(error) self.emit('error', error); | ||
else self.emit('data', JSON.parse(data), response); | ||
} | ||
if(sql.length > 2048) | ||
this.oa.get( | ||
this.api_url + "?q=" + qs.escape(sql) | ||
, this.access_key | ||
, this.access_secret | ||
, _response | ||
); | ||
else | ||
this.oa.post( | ||
this.api_url | ||
, this.access_key | ||
, this.access_secret | ||
, {q: sql} | ||
, null | ||
, _response | ||
); | ||
}; | ||
CartoDBClientApiKey.prototype.is_write_query = function(_sql) { | ||
var sql_lower = _sql.toLowerCase(); | ||
var isWrite = sql_lower.indexOf('insert') !== -1 || | ||
sql_lower.indexOf('delete') !== -1 || | ||
sql_lower.indexOf('update') !== -1; | ||
return isWrite; | ||
} | ||
/* | ||
* Connect with the server | ||
* | ||
* @api public | ||
*/ | ||
CartoDBClientApiKey.prototype.close = function() { | ||
//do nothing yet, leave nodejs manage the connection pool | ||
CartoDB.prototype.connect = function() { | ||
this.emit('connect'); | ||
}; | ||
CartoDBClientApiKey.prototype.sql = function(_sql, args) { | ||
var self = this; | ||
var sql = tmpl(_sql, args); | ||
debug("SQL: " + sql); | ||
/* | ||
* Close the connection | ||
* | ||
* @api public | ||
*/ | ||
var options = { | ||
host: this.cartodb_host, | ||
port: 443, | ||
headers: {}// {'Connection': 'keep-alive'} // stay connected | ||
}; | ||
CartoDB.prototype.close = function() { | ||
//do nothing yet, leave nodejs manage the connection pool | ||
}; | ||
if(this.opt.keep_alive) { | ||
options.headers['Connection'] = 'keep-alive'; | ||
} | ||
/* | ||
* Query the database | ||
* | ||
* @param {String} sql statemente | ||
* @param {Object} arguments | ||
*/ | ||
var params = "q=" + querystring.escape(sql) + "&api_key="+ this.api_key; | ||
if(sql.length > 2048 || this.is_write_query(sql)) { | ||
options.method = "POST"; | ||
options.headers['Content-type'] = 'application/x-www-form-urlencoded'; | ||
options.headers['Content-length'] = params.length; | ||
options.path = this.cartodb_api_path; | ||
} else { | ||
options.method = "GET"; | ||
options.path = this.cartodb_api_path + "?" + params; | ||
CartoDB.prototype.query = function(_sql, args) { | ||
var self = this; | ||
var sql = tmpl(_sql, args); | ||
if(sql.length > 2048 || isWriteQuery(sql)) | ||
request | ||
.post(self.api_url) | ||
.type('form') | ||
.send({q: sql, api_key: self.api_key}) | ||
.set('port', 443) | ||
.end(function(res){ | ||
if(res.ok) self.emit('data', res.body); | ||
else self.emit('error', res); | ||
}); | ||
else | ||
request | ||
.get(self.api_url) | ||
.query({q: sql, api_key: self.api_key}) | ||
.set('port', 443) | ||
.end(function(res){ | ||
if(res.ok) self.emit('data', res.body); | ||
else self.emit('error', res.text); | ||
}); | ||
}; | ||
} | ||
/* | ||
* Utilities | ||
*/ | ||
var req = https.request(options, function(res) { | ||
var data = ''; | ||
res.on('data', function(d) { | ||
res.setEncoding('utf8'); | ||
data += d; | ||
}); | ||
/** | ||
* renders a template | ||
* tmpl("Hi {name}", {name: 'rambo'}) renders "Hi rambo" | ||
*/ | ||
res.on('end', function() { | ||
if(res.statusCode === 200) { | ||
self.emit('data', data); | ||
} else { | ||
self.emit('error', { statusCode: res.statusCode, data: data}); | ||
} | ||
}); | ||
function tmpl(s,d){ | ||
for(var p in d) s = s.replace('{'+p+'}', d[p]); | ||
return s; | ||
} | ||
}); | ||
/* | ||
* check if the user wants to write to the db | ||
*/ | ||
if(options.method === "POST") { | ||
req.write(params); | ||
} | ||
req.end(); | ||
req.on('error', function(d) { | ||
self.emit('error', d); | ||
}); | ||
var isWriteQuery = CartoDB.prototype.isWriteQuery = function(sql) { | ||
return /insert|delete|update/gi.test(sql); | ||
}; | ||
module.exports = { | ||
CartoDBClient: CartoDBClient, | ||
CartoDBClientApiKey: CartoDBClientApiKey | ||
} | ||
/* | ||
* Exports the constructor | ||
*/ | ||
module.exports = CartoDB; | ||
@@ -5,3 +5,3 @@ { | ||
"private": false, | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"main": "index", | ||
@@ -19,9 +19,17 @@ "url": "https://github.com/Vizzuality/cartodb-nodejs", | ||
}, | ||
"contributors": [ | ||
"Dan Zajdband <dan.zajdband@gmail.com>", | ||
"Javi Santana <jsantana@vizzuality.com>" | ||
], | ||
"dependencies": { | ||
"underscore" : "1.1.x", | ||
"oauth": "0.9.5" | ||
"oauth": "0.9.5", | ||
"superagent": "0.4.x" | ||
}, | ||
"devDependencies": { | ||
"mocha": "*" | ||
}, | ||
"scripts": { | ||
"test": "make test" | ||
} | ||
} |
@@ -17,17 +17,18 @@ CartoDB client for node.js | ||
The library provides two clents, oauth client and api key client. Two clients basically have the same funcionallity and you should choose one of them depending on you requirements. | ||
The library provides two auth ways, oauth client and api key client. Both have the same funcionallity and you should choose one of them depending on you requirements. | ||
```javascript | ||
var cartodb = require('cartodb'); | ||
var CartoDB = require('cartodb'); | ||
var secret = require('./secret.js'); | ||
/* you could change this by CartoDBClient if you want to use oath | ||
client = new cartodb.CartoDBClient( | ||
secret.USER, | ||
secret.password, | ||
secret.CONSUMER_KEY, | ||
secret.CONSUMER_SECRET); | ||
/* you could change this providing an api_key instead of consumer key / secret if you want to use oath | ||
client = new CartoDB({ | ||
user: secret.USER, | ||
password: secret.password, | ||
consumer_key: secret.CONSUMER_KEY, | ||
consumer_secret: secret.CONSUMER_SECRET | ||
}); | ||
*/ | ||
var client = new cartodb.CartoDBClientApiKey(secret.USER, secret.API_KEY); | ||
var client = new CartoDB({user: secret.USER,api_key: secret.API_KEY}); | ||
@@ -39,9 +40,4 @@ | ||
// this is not required for ApiKey client | ||
// if you dont call client.connect the connection will not be persistent | ||
// so the process will finish after the two request finish | ||
client.connect(); | ||
// Data if automatically parsed | ||
client.on('data', function(data) { | ||
var results = JSON.parse(data); | ||
console.log(results.rows); | ||
@@ -55,6 +51,5 @@ }); | ||
// request two queries | ||
client.sql("select * from tracker limit 5"); | ||
client.sql("select * from tracker limit 5 offset 5"); | ||
client.query("select * from {table} limit 5", {table: 'tracker'}); // template can be used | ||
client.query("select * from tracker limit 5 offset 5"); | ||
// the process will not finish here if client connection is persistent | ||
``` | ||
@@ -66,6 +61,5 @@ | ||
------------ | ||
* nodejs >0.4.10 | ||
* nodejs >0.5.0 | ||
* npm | ||
* CartoDB account | ||
be careful with nodejs version you are using, there are some problems with https module in 0.4.8 version https://github.com/joyent/node/issues/728 |
var assert = require('assert'); | ||
var cartodb = require('../'); | ||
var CartoDB = require('../'); | ||
var secret = require('./secret'); | ||
@@ -9,8 +9,9 @@ var shouldBehaveLikeASQLCLient = require('./client.oauth').shouldBehaveLikeASQLCLient; | ||
beforeEach(function(done){ | ||
this.client = new cartodb.CartoDBClientApiKey( | ||
secret.USER, | ||
secret.API_KEY); | ||
this.client = new CartoDB({ | ||
user : secret.USER, | ||
api_key : secret.API_KEY}); | ||
this.client.on('connect', function() { | ||
done(); | ||
}); | ||
this.client.connect(); | ||
@@ -21,15 +22,15 @@ }); | ||
it("should return true for insert", function() { | ||
this.client.is_write_query("InSerT into table (bla) values ('meh')"); | ||
this.client.isWriteQuery("InSerT into table (bla) values ('meh')"); | ||
}); | ||
it("should return true for udpate", function() { | ||
this.client.is_write_query("UpDaTe table set bla=1"); | ||
this.client.isWriteQuery("UpDaTe table set bla=1"); | ||
}); | ||
it("should return true for delete", function() { | ||
this.client.is_write_query("DeLeTe from table"); | ||
this.client.isWriteQuery("DeLeTe from table"); | ||
}); | ||
it("should return false for select ", function() { | ||
this.client.is_write_query("select * from table"); | ||
this.client.isWriteQuery("select * from table"); | ||
}); | ||
@@ -36,0 +37,0 @@ }); |
var assert = require('assert'); | ||
var cartodb = require('../'); | ||
var CartoDB = require('../'); | ||
var secret = require('./secret'); | ||
@@ -14,6 +14,5 @@ | ||
console.log(secret.EXISTING_TABLE); | ||
this.client.sql(sql, {table: secret.EXISTING_TABLE}); | ||
this.client.query(sql, {table: secret.EXISTING_TABLE}); | ||
this.client.on('data', function(data) { | ||
var response = JSON.parse(data); | ||
assert.equal(1, response.total_rows); | ||
assert.equal(1, data.total_rows); | ||
done(); | ||
@@ -25,6 +24,6 @@ }); | ||
var sql = "select * from {table} limit 1"; | ||
this.client.sql(sql, {table: 'ASDASDASDASDASDassaDDS'}); | ||
this.client.on('error', function(data) { | ||
assert.ok(data.statusCode !== undefined); | ||
assert.ok(JSON.parse(data.data).error !== undefined); | ||
this.client.query(sql, {table: 'ASDASDASDASDASDassaDDS'}); | ||
this.client.on('error', function(error) { | ||
assert.ok(typeof error !== undefined); | ||
assert.ok(typeof error.statusCode !== undefined); | ||
done(); | ||
@@ -36,3 +35,3 @@ }); | ||
var sql = "insert into {table} (name) values ('test')"; | ||
this.client.sql(sql, {table: secret.EXISTING_TABLE}); | ||
this.client.query(sql, {table: secret.EXISTING_TABLE}); | ||
this.client.on('data', function(data) { | ||
@@ -48,8 +47,9 @@ done(); | ||
beforeEach(function(done){ | ||
this.client = new cartodb.CartoDBClient( | ||
secret.USER, | ||
secret.password, | ||
secret.CONSUMER_KEY, | ||
secret.CONSUMER_SECRET); | ||
this.client = new CartoDB({ | ||
user : secret.USER, | ||
password : secret.password, | ||
consumer_key : secret.CONSUMER_KEY, | ||
consumer_secret : secret.CONSUMER_SECRET}); | ||
this.client.connect(); | ||
console.log('connecting'); | ||
this.client.on('connect', function() { | ||
@@ -56,0 +56,0 @@ done(); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
13
281
12395
3
62
+ Addedsuperagent@0.4.x
+ Addedemitter-component@0.0.1(transitive)
+ Addedformidable@1.0.9(transitive)
+ Addedmime@1.2.5(transitive)
+ Addedqs@0.4.2(transitive)
+ Addedsuperagent@0.4.3(transitive)