<|start_filename|>example/cred-loader.js<|end_filename|>
//load example credential file
//in production, use enviroment variables instead
try {
  module.exports = require("./oauth2-creds.json");
} catch (err) {
  console.log(
    'Please make a "oauth2-creds.json" file in this folder to use these examples.'
  );
  console.log(
    '{ "client_id": "...", "client_secret": "...", "refresh_token": "..." }'
  );
  console.log("To retrieve this token, see ../get_oauth2_permissions.js");
  process.exit(1);
}


<|start_filename|>example/edit-autosize.js<|end_filename|>
var Spreadsheet = require("../");

Spreadsheet.load(
  {
    debug: true,
    oauth2: require("./cred-loader"),
    spreadsheetName: "edit-spreadsheet-example",
    worksheetName: "Sheet1"
  },
  function run(err, spreadsheet) {
    if (err) throw err;
    spreadsheet.add({300: {50: "hello!"}});
    spreadsheet.send({autoSize: true}, function(err) {
      if (err) throw err;
      console.log(
        "Resized then updated Cell at row 300, column 50 to 'hello!'"
      );
    });
  }
);


<|start_filename|>lib/util.js<|end_filename|>

//parse number
exports.num = function(obj) {
  if (obj === undefined) return 0;
  if (typeof obj === "number" || typeof obj === "boolean") return obj;
  if (typeof obj === "string") {
    //ensure that the string is *only* a number
    if (!/^\-?\d+(\.\d+)?$/.test(obj)) return obj;
    var res = parseFloat(obj, 10);
    if (isNaN(res)) return obj;
    return res;
  }
  throw "Invalid number: " + JSON.stringify(obj);
};

exports.int2cell = function(r, c) {
  return String.fromCharCode(64 + c) + r;
};

exports.gcell2cell = function(cell, getValue, useTextValues) {
  //get formula AND has a formula?
  if (!getValue && /^=/.test(cell.inputValue)) {
    //must convert '=RC[-2]+R[3]C[-1]' to '=B5+C8'
    return cell.inputValue.replace(
      /(R(\[(-?\d+)\])?)(C(\[(-?\d+)\])?)/g,
      function() {
        return exports.int2cell(
          exports.num(cell.row) + exports.num(arguments[3] || 0),
          exports.num(cell.col) + exports.num(arguments[6] || 0)
        );
      }
    );
  }
  //get value
  return useTextValues ? exports.num(cell.$t) : exports.num(cell.inputValue);
};

exports.promisify = function(fn) {
  return function wrapped() {
    //store promise on callback
    var resolve, reject;
    var promise = new Promise(function(res, rej) {
      resolve = res;
      reject = rej;
    });
    //
    var args = Array.from(arguments);
    var callback = args[args.length - 1];
    var hasCallback = typeof callback === "function";
    //resolve/reject promise
    var fullfilled = function(err, data) {
      if (err) {
        reject(err);
      } else {
        var datas = Array.prototype.slice.call(arguments, 1);
        if (datas.length >= 2) {
          resolve(datas);
        } else {
          resolve(data);
        }
      }
      if (hasCallback) {
        callback.apply(this, arguments);
      }
    };
    //replace/add callback
    if (hasCallback) {
      args[args.length - 1] = fullfilled;
    } else {
      args.push(fullfilled);
    }
    //call underlying function
    var returned = fn.apply(this, args);
    if (typeof returned !== "undefined") {
      console.log("promisify warning: discarded return value");
    }
    //return promise!
    return promise;
  };
};


<|start_filename|>lib/auth.js<|end_filename|>
var GoogleOAuthJWT = require("google-oauth-jwt");
var GoogleAuth = require("google-auth-library");
var googleAuth = new GoogleAuth();

//client auth helper
module.exports = function(opts, callback) {
  if (opts.username && opts.password) callback("Client login not supported");
  else if (opts.oauth) oAuth1Login(opts.oauth, opts.useHTTPS, callback);
  else if (opts.oauth2) oAuth2Login(opts.oauth2, callback);
  else if (opts.accessToken) accessTokenLogin(opts.accessToken, callback);
};

function oAuth1Login(oauth, useHTTPS, callback) {
  if (!oauth.scopes) {
    oauth.scopes = ["http" + useHTTPS + "://spreadsheets.google.com/feeds"];
  }
  GoogleOAuthJWT.authenticate(oauth, function(err, token) {
    if (err) callback("Google OAuth Error: " + err);
    else callback(null, {type: "Bearer", token: token});
  });
}

function oAuth2Login(oauth2, callback) {
  var oAuth2Client = new googleAuth.OAuth2(
    oauth2.client_id,
    oauth2.client_secret,
    "urn:ietf:wg:oauth:2.0:oob"
  );

  oAuth2Client.setCredentials({
    access_token: "<PASSWORD>",
    expiry_date: 1,
    refresh_token: oauth2.refresh_token,
    token_type: "Bearer"
  });
  oAuth2Client.getAccessToken(function(err, token) {
    if (err) callback("Google OAuth2 Error: " + err);
    else callback(null, {type: "Bearer", token: token});
  });
}

function accessTokenLogin(accessToken, callback) {
  function gotToken(err, t) {
    if (err) return callback(err);
    if (!t.type || !t.token)
      return callback("Missing token or token type information");
    //got token
    callback(null, {type: t.type, token: t.token});
  }
  //
  if (typeof accessToken === "function") accessToken(gotToken);
  else if (typeof accessToken === "object") gotToken(null, accessToken);
  else callback("Invalid access token");
}


<|start_filename|>example/read-basic.js<|end_filename|>
var Spreadsheet = require("../");
var creds = require("./cred-loader");

Spreadsheet.load(
  {
    debug: true,
    oauth2: require("./cred-loader"),
    spreadsheetName: "node-edit-spreadsheet",
    worksheetName: "Sheet1"
  },
  function run(err, spreadsheet) {
    if (err) return console.log(err);
    //receive all cells
    spreadsheet.receive({getValues: false}, function(err, rows, info) {
      if (err) return console.log(err);
      console.log("Found rows:", rows);
      console.log("With info:", info);
    });
  }
);


<|start_filename|>example/read-basic-async-await.js<|end_filename|>
const Spreadsheet = require("../");
const creds = require("./cred-loader");

(async () => {
  try {
    let spreadsheet = await Spreadsheet.load({
      debug: true,
      oauth2: creds,
      spreadsheetName: "node-spreadsheet-example",
      worksheetName: "Sheet1"
    });
    //receive all cells
    let [rows, info] = await spreadsheet.receive({getValues: false});
    console.log("Found rows:", rows);
    console.log("With info:", info);
  } catch (err) {
    console.error("EROR", err);
  }
})();


<|start_filename|>example/edit-basic-async-await.js<|end_filename|>
const Spreadsheet = require("../");
const creds = require("./cred-loader");

(async () => {
  try {
    let spreadsheet = await Spreadsheet.load({
      debug: true,
      oauth2: creds,
      spreadsheetName: "node-spreadsheet-example",
      worksheetName: "Sheet1"
    });
    //insert 'Zip zop' at E3
    spreadsheet.add({3: {5: "Zip zop"}});
    await spreadsheet.send();
    console.log("Updated Cell E3");
  } catch (err) {
    console.error("EROR", err);
  }
})();


<|start_filename|>example/edit-cell-names.js<|end_filename|>
var Spreadsheet = require("../");

Spreadsheet.load(
  {
    debug: true,
    oauth2: require("./cred-loader"),
    spreadsheetName: "edit-spreadsheet-example",
    worksheetName: "Sheet1"
  },
  function run(err, spreadsheet) {
    if (err) throw err;
    spreadsheet.add({
      3: {
        4: {name: "a", val: 42}, //'42' though tagged as "a"
        5: {name: "b", val: 21}, //'21' though tagged as "b"
        6: "={{ a }}+{{ b }}" //forumla adding row3,col4 with row3,col5 => '=D3+E3'
      }
    });
    spreadsheet.send(function(err) {
      if (err) throw err;
      console.log("Cells updated");
    });
  }
);
