UNPKG

jsforce

Version:

Salesforce API Library for JavaScript

181 lines (165 loc) 4.14 kB
var _ = require('underscore'), SfDate = require('./date'); /** * @private */ function toCSV(records, headers, options) { options = options || {}; if (!headers) { headers = extractHeaders(records, options); } var rows = _.map(records, function(record){ return recordToCSV(record, headers, options); }); return arrayToCSV(headers) + "\n" + rows.join("\n"); } /** * @private */ function extractHeaders(records, options) { options = options || {}; var headers = {}; _.forEach(records, function(record) { for (var key in record) { var value = record[key]; if (record.hasOwnProperty(key) && (value === null || typeof value !== 'object')) { headers[key] = true; } } }); return _.keys(headers); } /** * @private */ function recordToCSV(record, headers, options) { options = options || {}; var row = []; _.forEach(headers, function(header) { var value = record[header]; if (value === null && typeof options.nullValue !== 'undefined') { value = options.nullValue; } if (typeof value === 'undefined') { value = null; } row.push(value); }); return arrayToCSV(row); } /** * @private */ function arrayToCSV(arr) { return _.map(arr, escapeCSV).join(','); } /** * @private */ function escapeCSV(str) { if (str === null || typeof str === 'undefined') { str = ''; } str = String(str); if (str.indexOf('"') >= 0 || str.indexOf(',') >= 0 || /[\n\r]/.test(str)) { str = '"' + str.replace(/"/g, '""') + '"'; } return str; } /** * @private * @class * @constructor * @param {String} text - CSV string */ var CSVParser = function(text) { this.text = text; this.cursor = 0; }; CSVParser.prototype = { nextToken : function() { var cell; var dquoted = false; var firstChar = this.text.charAt(this.cursor); if (firstChar === '' || firstChar === '\r' || firstChar === '\n') { return null; } if (firstChar === '"') { dquoted = true; } if (dquoted) { var dq = this.cursor; while(true) { dq++; dq = this.text.indexOf('"', dq); if (dq<0 || this.text.charAt(dq+1) !== '"') { break; } else { dq++; } } if (dq>=0) { var delim = this.text.charAt(dq+1); cell = this.text.substring(this.cursor, dq+1); this.cursor = dq + (delim === ',' ? 2 : 1); } else { cell = this.text.substring(this.cursor); this.cursor = this.text.length; } return cell.replace(/""/g,'"').replace(/^"/,'').replace(/"$/,''); } else { var comma = this.text.indexOf(',', this.cursor); var cr = this.text.indexOf('\r', this.cursor); var lf = this.text.indexOf('\n', this.cursor); comma = comma<0 ? this.text.length+1 : comma; cr = cr<0 ? this.text.length+1 : cr; lf = lf<0 ? this.text.length+1 : lf; var pivot = Math.min(comma, cr, lf, this.text.length); cell = this.text.substring(this.cursor, pivot); this.cursor = pivot; if (comma === pivot) { this.cursor++; } return cell; } }, nextLine : function() { for (var c = this.text.charAt(this.cursor); c === '\r' || c === '\n'; c = this.text.charAt(++this.cursor)) {} return this.cursor !== this.text.length; } }; /** * @private */ function parseCSV(str) { var parser = new CSVParser(str); var headers = []; var token; if (parser.nextLine()) { token = parser.nextToken(); while (!_.isUndefined(token) && !_.isNull(token)) { headers.push(token); token = parser.nextToken(); } } var rows = []; while (parser.nextLine()) { var row = {}; token = parser.nextToken(); var i = 0; while (!_.isUndefined(token) && !_.isNull(token)) { var header = headers[i++]; row[header] = token; token = parser.nextToken(); } rows.push(row); } return rows; } /** * @protected */ module.exports = { toCSV : toCSV, extractHeaders : extractHeaders, recordToCSV : recordToCSV, arrayToCSV : arrayToCSV, parseCSV : parseCSV };