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

google-spreadsheet

Package Overview
Dependencies
Maintainers
1
Versions
55
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

google-spreadsheet - npm Package Compare versions

Comparing version 0.2.5 to 0.2.6

README.md

455

index.js

@@ -12,153 +12,181 @@ var request = require("request");

module.exports = function( ss_key, auth_id ){
var google_auth;
var self = this;
var self = this;
var google_auth;
var xml_parser = new xml2js.Parser({
// options carried over from older version of xml2js -- might want to update how the code works, but for now this is fine
explicitArray: false,
explicitRoot: false,
});
var xml_parser = new xml2js.Parser({
// options carried over from older version of xml2js -- might want to update how the code works, but for now this is fine
explicitArray: false,
explicitRoot: false,
});
if ( !ss_key ) {
throw new Error("Spreadsheet key not provided.");
}
if ( auth_id ){
google_auth = auth_id;
}
if ( !ss_key ) {
throw new Error("Spreadsheet key not provided.");
}
if ( auth_id ){
google_auth = auth_id;
}
this.setAuth = function( username, password, cb ){
var new_auth = new GoogleClientLogin({
email: username,
password: password,
service: 'spreadsheets',
accountType: GoogleClientLogin.accountTypes.google
})
new_auth.on(GoogleClientLogin.events.login, function(){
google_auth = new_auth.getAuthId();
cb( null, new_auth );
})
new_auth.on(GoogleClientLogin.events.error, function(err){
cb( err );
})
new_auth.login();
}
this.setAuth = function( username, password, cb ){
var new_auth = new GoogleClientLogin({
email: username,
password: password,
service: 'spreadsheets',
accountType: GoogleClientLogin.accountTypes.google
})
new_auth.on(GoogleClientLogin.events.login, function(){
google_auth = new_auth.getAuthId();
cb( null, new_auth );
})
new_auth.on(GoogleClientLogin.events.error, function(err){
cb( err );
})
new_auth.login();
}
this.getInfo = function( cb ){
self.makeFeedRequest( ["worksheets", ss_key], 'GET', null, function(err, data, xml) {
if ( err ) return cb( err );
var ss_data = {
title: data.title["_"],
updated: data.updated,
author: data.author,
worksheets: []
}
var worksheets = forceArray(data.entry);
worksheets.forEach( function( ws_data ) {
ss_data.worksheets.push( new SpreadsheetWorksheet( self, ws_data ) );
})
cb( null, ss_data );
});
}
this.getRows = function( worksheet_id, opts, query, cb ){
// the first row is used as titles/keys and is not included
this.getInfo = function( cb ){
self.makeFeedRequest( ["worksheets", ss_key], 'GET', null, function(err, data, xml) {
if ( err ) return cb( err );
var ss_data = {
title: data.title["_"],
updated: data.updated,
author: data.author,
worksheets: []
}
var worksheets = forceArray(data.entry);
worksheets.forEach( function( ws_data ) {
ss_data.worksheets.push( new SpreadsheetWorksheet( self, ws_data ) );
})
cb( null, ss_data );
});
}
this.getRows = function( worksheet_id, opts, query, cb ){
// the first row is used as titles/keys and is not included
// opts is optional
if ( typeof( opts ) == 'function' ){
cb = opts;
opts = {};
query = null;
// so is query
} else if ( typeof( query ) == 'function' ){
cb = query;
query = null;
}
// opts is optional
if ( typeof( opts ) == 'function' ){
cb = opts;
opts = {};
query = null;
// so is query
} else if ( typeof( query ) == 'function' ){
cb = query;
query = null;
}
if ( opts.start ) query["start-index"] = opts.start;
if ( opts.num ) query["max-results"] = opts.num;
if ( opts.orderby ) query["orderby"] = opts.orderby;
if ( opts.reverse ) query["reverse"] = opts.reverse;
if ( opts.start ) query["start-index"] = opts.start;
if ( opts.num ) query["max-results"] = opts.num;
if ( opts.orderby ) query["orderby"] = opts.orderby;
if ( opts.reverse ) query["reverse"] = opts.reverse;
self.makeFeedRequest( ["list", ss_key, worksheet_id], 'GET', query, function(err, data, xml) {
if ( err ) return cb( err );
self.makeFeedRequest( ["list", ss_key, worksheet_id], 'GET', query, function(err, data, xml) {
if ( err ) return cb( err );
// gets the raw xml for each entry -- this is passed to the row object so we can do updates on it later
// gets the raw xml for each entry -- this is passed to the row object so we can do updates on it later
var entries_xml = xml.match(/<entry[^>]*>([\s\S]*?)<\/entry>/g);
var rows = [];
var entries = forceArray( data.entry );
var i=0;
entries.forEach( function( row_data ) {
rows.push( new SpreadsheetRow( self, row_data, entries_xml[ i++ ] ) );
});
cb(null, rows);
});
var rows = [];
var entries = forceArray( data.entry );
var i=0;
entries.forEach( function( row_data ) {
rows.push( new SpreadsheetRow( self, row_data, entries_xml[ i++ ] ) );
});
cb(null, rows);
});
}
this.addRow = function( worksheet_id, data, cb ){
if( !worksheet_id ) throw new Error("Worksheet not specified.");
}
var data_xml = '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">' + "\n";
Object.keys(data).forEach(function(key) {
if (key != 'id' && key != 'title' && key != 'content' && key != '_links'){
data_xml += '<gsx:'+ xmlSafeColumnName(key) + '>' + xmlSafeValue(data[key]) + '</gsx:'+ xmlSafeColumnName(key) + '>' + "\n"
}
});
data_xml += '</entry>';
self.makeFeedRequest( ["list", ss_key, worksheet_id], 'POST', data_xml, cb );
}
this.getCells = function (worksheet_id, opts, cb) {
// opts is optional
if (typeof( opts ) == 'function') {
cb = opts;
opts = {};
}
this.addRow = function( worksheet_id, data, cb ){
if( !worksheet_id ) throw new Error("Worksheet not specified.");
var query = {};
if (opts.minRow) query["min-row"] = opts.minRow;
if (opts.maxRow) query["max-row"] = opts.maxRow;
if (opts.minCol) query["min-col"] = opts.minCol;
if (opts.maxCol) query["max-col"] = opts.maxCol;
var data_xml = '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">' + "\n";
Object.keys(data).forEach(function(key) {
if (key != 'id' && key != 'title' && key != 'content' && key != '_links'){
data_xml += '<gsx:'+ xmlSafeColumnName(key) + '>' + xmlSafeValue(data[key]) + '</gsx:'+ xmlSafeColumnName(key) + '>' + "\n"
}
});
data_xml += '</entry>';
self.makeFeedRequest( ["list", ss_key, worksheet_id], 'POST', data_xml, cb );
}
self.makeFeedRequest(["cells", ss_key, worksheet_id], 'GET', query, function (err, data, xml) {
if (err) return cb(err);
this.makeFeedRequest = function( url_params, method, query_or_data, cb ){
var url;
var headers = {};
if (!cb ) cb = function(){};
if ( typeof(url_params) == 'string' ) {
// used for edit / delete requests
url = url_params;
} else if ( Array.isArray( url_params )){
//used for get and post requets
var visibility = google_auth ? 'private' : 'public';
var projection = google_auth ? 'full' : 'values';
url_params.push( visibility, projection );
url = GOOGLE_FEED_URL + url_params.join("/");
}
var cells = [];
var entries = forceArray(data['entry']);
var i = 0;
entries.forEach(function( cell_data ){
cells.push( new SpreadsheetCell( self, worksheet_id, cell_data ) );
});
if ( google_auth ) {
headers.Authorization = "GoogleLogin auth=" + google_auth;
}
cb( null, cells );
});
}
if ( method == 'POST' || method == 'PUT' ){
headers['content-type'] = 'application/atom+xml';
}
this.makeFeedRequest = function( url_params, method, query_or_data, cb ){
var url;
var headers = {};
if (!cb ) cb = function(){};
if ( typeof(url_params) == 'string' ) {
// used for edit / delete requests
url = url_params;
} else if ( Array.isArray( url_params )){
//used for get and post requets
var visibility = google_auth ? 'private' : 'public';
var projection = google_auth ? 'full' : 'values';
url_params.push( visibility, projection );
url = GOOGLE_FEED_URL + url_params.join("/");
}
if ( method == 'GET' && query_or_data ) {
url += "?" + querystring.stringify( query_or_data );
}
if ( google_auth ) {
if (google_auth.type === 'Bearer') {
headers['Authorization'] = 'Bearer ' + google_auth.value;
} else {
headers['Authorization'] = "GoogleLogin auth=" + google_auth;
}
}
request( {
url: url,
method: method,
headers: headers,
body: method == 'POST' || method == 'PUT' ? query_or_data : null,
}, function(err, response, body){
if (err) {
return cb( err );
} else if( response.statusCode === 401 ) {
return cb( new Error("Invalid authorization key."));
} else if ( response.statusCode >= 400 ) {
return cb( new Error("HTTP error " + response.statusCode + ": " + http.STATUS_CODES[response.statusCode]));
}
if ( method == 'POST' || method == 'PUT' ){
headers['content-type'] = 'application/atom+xml';
}
if ( body ){
xml_parser.parseString(body, function(err, result){
if ( err ) return cb( err );
cb( null, result, body );
});
} else {
if ( err ) cb( err );
else cb( null, true );
}
if ( method == 'GET' && query_or_data ) {
url += "?" + querystring.stringify( query_or_data );
}
})
}
request( {
url: url,
method: method,
headers: headers,
body: method == 'POST' || method == 'PUT' ? query_or_data : null
}, function(err, response, body){
if (err) {
return cb( err );
} else if( response.statusCode === 401 ) {
return cb( new Error("Invalid authorization key."));
} else if ( response.statusCode >= 400 ) {
console.log( body );
return cb( new Error("HTTP error " + response.statusCode + ": " + http.STATUS_CODES[response.statusCode]));
}
if ( body ){
xml_parser.parseString(body, function(err, result){
if ( err ) return cb( err );
cb( null, result, body );
});
} else {
if ( err ) cb( err );
else cb( null, true );
}
})
}
};

@@ -168,72 +196,115 @@

var SpreadsheetWorksheet = function( spreadsheet, data ){
var self = this;
self.id = data.id.substring( data.id.lastIndexOf("/") + 1 );
self.title = data.title["_"];
self.rowCount = data['gs:rowCount'];
self.colCount = data['gs:colCount'];
var self = this;
self.id = data.id.substring( data.id.lastIndexOf("/") + 1 );
self.title = data.title["_"];
self.rowCount = data['gs:rowCount'];
self.colCount = data['gs:colCount'];
this.getRows = function( opts, query, cb ){
spreadsheet.getRows( self.id, opts, query, cb );
}
this.addRow = function( data, cb ){
spreadsheet.addRow( self.id, data, cb );
}
this.getRows = function( opts, query, cb ){
spreadsheet.getRows( self.id, opts, query, cb );
}
this.getCells = function (opts, cb) {
spreadsheet.getCells( self.id, opts, cb );
}
this.addRow = function( data, cb ){
spreadsheet.addRow( self.id, data, cb );
}
}
var SpreadsheetRow = function( spreadsheet, data, xml ){
var self = this;
self['_xml'] = xml;
Object.keys(data).forEach(function(key) {
var val = data[key];
if(key.substring(0, 4) === "gsx:") {
if(typeof val === 'object' && Object.keys(val).length === 0) {
val = null;
}
if (key == "gsx:") {
self[key.substring(0, 3)] = val;
} else {
self[key.substring(4)] = val;
}
} else {
if (key == "id") {
self[key] = val;
} else if (val['_']) {
self[key] = val['_'];
} else if ( key == 'link' ){
self['_links'] = [];
val = forceArray( val );
val.forEach( function( link ){
self['_links'][ link['$']['rel'] ] = link['$']['href'];
});
}
}
}, this);
var self = this;
self['_xml'] = xml;
Object.keys(data).forEach(function(key) {
var val = data[key];
if(key.substring(0, 4) === "gsx:") {
if(typeof val === 'object' && Object.keys(val).length === 0) {
val = null;
}
if (key == "gsx:") {
self[key.substring(0, 3)] = val;
} else {
self[key.substring(4)] = val;
}
} else {
if (key == "id") {
self[key] = val;
} else if (val['_']) {
self[key] = val['_'];
} else if ( key == 'link' ){
self['_links'] = [];
val = forceArray( val );
val.forEach( function( link ){
self['_links'][ link['$']['rel'] ] = link['$']['href'];
});
}
}
}, this);
self.save = function( cb ){
/*
API for edits is very strict with the XML it accepts
So we just do a find replace on the original XML.
It's dumb, but I couldnt get any JSON->XML conversion to work
*/
self.save = function( cb ){
/*
API for edits is very strict with the XML it accepts
So we just do a find replace on the original XML.
It's dumb, but I couldnt get any JSON->XML conversion to work reliably
*/
var data_xml = self['_xml'];
// probably should make this part more robust?
data_xml = data_xml.replace('<entry>', "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gsx='http://schemas.google.com/spreadsheets/2006/extended'>");
Object.keys( self ).forEach( function(key) {
if (key.substr(0,1) != '_' && typeof( self[key] == 'string') ){
data_xml = data_xml.replace( new RegExp('<gsx:'+xmlSafeColumnName(key)+">([\\s\\S]*?)</gsx:"+xmlSafeColumnName(key)+'>'), '<gsx:'+xmlSafeColumnName(key)+'>'+ xmlSafeValue(self[key]) +'</gsx:'+xmlSafeColumnName(key)+'>');
}
});
spreadsheet.makeFeedRequest( self['_links']['edit'], 'PUT', data_xml, cb );
}
self.del = function( cb ){
spreadsheet.makeFeedRequest( self['_links']['edit'], 'DELETE', null, cb );
}
var data_xml = self['_xml'];
// probably should make this part more robust?
data_xml = data_xml.replace('<entry>', "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gsx='http://schemas.google.com/spreadsheets/2006/extended'>");
Object.keys( self ).forEach( function(key) {
if (key.substr(0,1) != '_' && typeof( self[key] == 'string') ){
data_xml = data_xml.replace( new RegExp('<gsx:'+xmlSafeColumnName(key)+">([\\s\\S]*?)</gsx:"+xmlSafeColumnName(key)+'>'), '<gsx:'+xmlSafeColumnName(key)+'>'+ xmlSafeValue(self[key]) +'</gsx:'+xmlSafeColumnName(key)+'>');
}
});
spreadsheet.makeFeedRequest( self['_links']['edit'], 'PUT', data_xml, cb );
}
self.del = function( cb ){
spreadsheet.makeFeedRequest( self['_links']['edit'], 'DELETE', null, cb );
}
}
var SpreadsheetCell = function( spreadsheet, worksheet_id, data ){
var self = this;
self.id = data['id'];
self.row = parseInt(data['gs:cell']['$']['row']);
self.col = parseInt(data['gs:cell']['$']['col']);
self.value = data['gs:cell']['_'];
self['_links'] = [];
links = forceArray( data.link );
links.forEach( function( link ){
self['_links'][ link['$']['rel'] ] = link['$']['href'];
});
self.setValue = function(new_value, cb) {
self.value = new_value;
self.save(cb);
};
self.save = function(cb) {
new_value = xmlSafeValue(self.value);
var edit_id = 'https://spreadsheets.google.com/feeds/cells/key/worksheetId/private/full/R'+self.row+'C'+self.col;
var data_xml =
'<entry><id>'+edit_id+'</id>'+
'<link rel="edit" type="application/atom+xml" href="'+edit_id+'"/>'+
'<gs:cell row="'+self.row+'" col="'+self.col+'" inputValue="'+new_value+'"/></entry>'
data_xml = data_xml.replace('<entry>', "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gs='http://schemas.google.com/spreadsheets/2006'>");
console.log(self['_links']['edit']);
console.log(data_xml);
spreadsheet.makeFeedRequest( self['_links']['edit'], 'PUT', data_xml, cb );
}
self.del = function(cb) {
self.setValue('');
}
}
//utils
var forceArray = function(val) {
if ( Array.isArray( val ) ) return val;
if ( !val ) return [];
return [ val ];
if ( Array.isArray( val ) ) return val;
if ( !val ) return [];
return [ val ];
}

@@ -240,0 +311,0 @@ var xmlSafeValue = function(val){

{
"author": "Theo Ephraim <theozero@gmail.com> (http://theoephraim.com)",
"name": "google-spreadsheet",
"description": "Google Spreadsheet Data API for Node.js -- can read, write, edit, and delete rows",
"version": "0.2.5",
"description": "Google Spreadsheet Data API -- simple interface to read and write rows and cells",
"version": "0.2.6",
"keywords": [

@@ -20,11 +20,11 @@ "google",

"engines": {
"node": "~0.4.0"
"node": ">=0.8.0"
},
"dependencies": {
"request": "~2.0.2",
"xml2js": "~0.2.8",
"request": "~2.29.0",
"xml2js": "~0.4.0",
"googleclientlogin": "0.2.x"
},
"devDependencies": {
"nodeunit": "~0.8.1",
"nodeunit": "~0.8.2",
"async": "~0.2.9"

@@ -31,0 +31,0 @@ },

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