Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

sv

Package Overview
Dependencies
Maintainers
1
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sv - npm Package Compare versions

Comparing version 0.2.0 to 0.2.2

.travis.yml

100

index.js
#!/usr/bin/env node
'use strict'; /*jslint node: true, es5: true, indent: 2 */
var os = require('os');
var util = require('util');
var stream = require('stream');
var Parser = exports.Parser = require('./parser');

@@ -15,2 +18,46 @@ var Stringifier = exports.Stringifier = require('./stringifier');

var JSONStringifier = function(opts) {
stream.Transform.call(this, {objectMode: true});
this._readableState.objectMode = false;
};
util.inherits(JSONStringifier, stream.Transform);
JSONStringifier.prototype._transform = function(chunk, encoding, callback) {
this.push(JSON.stringify(chunk) + os.EOL, encoding);
callback();
};
var ObjectFilter = function(fields) {
// objects in, objects out
stream.Transform.call(this, {objectMode: true});
this.fields = {};
for (var i = 0, l = fields.length; i < l; i++) {
this.fields[fields[i]] = 1;
}
};
util.inherits(ObjectFilter, stream.Transform);
ObjectFilter.prototype._transform = function(chunk, encoding, callback) {
var filtered = {};
for (var field in this.fields)
filtered[field] = chunk[field];
this.push(filtered, encoding);
callback();
};
var ObjectOmitter = function(fields) {
// objects in, objects out
stream.Transform.call(this, {objectMode: true});
this.fields = {};
for (var i = 0, l = fields.length; i < l; i++) {
this.fields[fields[i]] = 1;
}
};
util.inherits(ObjectOmitter, stream.Transform);
ObjectOmitter.prototype._transform = function(chunk, encoding, callback) {
for (var field in this.fields)
delete chunk[field];
this.push(chunk, encoding);
callback();
};
if (require.main === module) {

@@ -21,19 +68,52 @@ var optimist = require('optimist')

'',
' argv will be passed directly to the Stringifier constructor.',
' process.stdin will be set to utf8',
'Usage: <sprints.txt sv [options] > sprints.csv',
'',
' cat data.tsv | sv > data.csv'
].join('\n'));
'Options:',
' -p, --peek 10 infer columns from first ten lines of input',
' -d, --delimiter , field separator',
' -q, --quotechar " mark beginning and end of fields containing delimiter',
' -e, --escapechar \\ escape quotechars when quoted',
' -j, --json write one JSON object per row',
' --filter a,b keep only fields a and b in the results',
' --omit c,d leave out fields x and y from the results',
' (do not use filter and omit together)',
'',
'Only STDIN is supported, and it is coerced to utf8',
].join('\n'))
.string('delimiter')
.boolean(['json',])
.alias({
p: 'peek',
d: 'delimiter',
q: 'quotechar',
e: 'escapechar',
j: 'json',
});
var argv = optimist.argv;
var parser = new Parser();
var stringifier = new Stringifier(optimist.argv);
if (process.stdin.isTTY) {
if (argv.help) {
optimist.showHelp();
console.error("You must supply data via STDIN");
console.log('ARGV: ' + process.argv.join(' '));
}
else if (process.stdin.isTTY) {
optimist.showHelp();
console.error('You must supply data via STDIN');
}
else {
var stringifier = argv.json ? new JSONStringifier() : new Stringifier(argv);
process.stdin.setEncoding('utf8');
process.stdin.pipe(parser).pipe(stringifier).pipe(process.stdout);
var parser = process.stdin.pipe(new Parser());
var filtered = null;
if (argv.filter) {
filtered = parser.pipe(new ObjectFilter(argv.filter.split(/,/g)));
}
else if (argv.omit) {
filtered = parser.pipe(new ObjectOmitter(argv.omit.split(/,/g)));
}
else {
filtered = parser;
}
filtered.pipe(stringifier).pipe(process.stdout);
}
}

6

package.json
{
"name": "sv",
"version": "0.2.0",
"version": "0.2.2",
"description": "Any separated values.",

@@ -25,6 +25,6 @@ "keywords": [

"dependencies": {
"optimist": "*"
"optimist": "0.5.2"
},
"devDependencies": {
"tap": "*"
"tap": "0.4.x"
},

@@ -31,0 +31,0 @@ "scripts": {

@@ -82,5 +82,10 @@ 'use strict'; /*jslint node: true, es5: true, indent: 2 */

for (var i = 0; i < end; i++) {
// if we are on an escape char, simply skip over it (++) and the (default)
if (buffer[i] === this.escapechar) {
i++;
// excel is bizarre. An escape before a quotechar doesn't count.
if (buffer[i+1] !== this.quotechar) {
i++;
}
}
// if we are outside quoting and on a "
else if (!inside && buffer[i] === this.quotechar) {

@@ -90,10 +95,23 @@ inside = true;

}
// if we are inside quoting and on a "
else if (inside && buffer[i] === this.quotechar) {
inside = false;
cells.push(buffer.toString(this.encoding, start, i));
// assume that an end quotechar is always followed by a delimiter
// advance so that buffer[i] == '\t'
// handle excel dialect: double quotechar => single literal quotechar
if (buffer[i+1] === this.quotechar) {
// double quotechar
// `inside` remains true
// we need to collapse out the current index. this might be optimized somehow
// buffer.copy(targetBuffer, [targetStart], [sourceStart], [sourceEnd])#
buffer.copy(buffer, i, i+1);
end--;
}
else {
// otherwise, assume that an end quotechar is always followed by a delimiter.
// advance so that buffer[i] == '\t'
inside = false;
cells.push(buffer.toString(this.encoding, start, i));
start = i + 2;
}
i++;
start = i + 1;
}
// otherwise we just wait for the delimiter
else if (!inside && buffer[i] === this.delimiter) {

@@ -106,3 +124,3 @@ cells.push(buffer.toString(this.encoding, start, i));

// we may have consumed the last field, already, if it was quoted.
cells.push(buffer.toString(this.encoding, start));
cells.push(buffer.toString(this.encoding, start, end));
}

@@ -120,3 +138,2 @@

Parser.prototype._flush = function(callback) {
// console.log('_flush');
// if there was a trailing newline, this._buffer.length = 0

@@ -123,0 +140,0 @@ if (this._buffer && this._buffer.length)

@@ -12,7 +12,9 @@ 'use strict'; /*jslint node: true, es5: true, indent: 2 */

if (typeof(obj) !== 'string' && !util.isArray(obj)) {
var keys = Object.keys(obj);
for (var key, k = 0; (key = keys[k]); k++) {
if (!(key in seen)) {
columns.push(key);
seen[key] = 1;
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
// maybe should also check that obj[key] != null
if (!(key in seen)) {
columns.push(key);
seen[key] = 1;
}
}

@@ -19,0 +21,0 @@ }

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

'use strict'; /*jslint node: true, es5: true, indent: 2, multistr: true */
'use strict'; /*jslint node: true, es5: true, indent: 2 */
var fs = require('fs');

@@ -62,1 +62,20 @@ var test = require('tap').test;

});
test('excel parser', function (t) {
var input = [
'index name time',
'1 "chris ""breezy"" brown" 1:18',
'2 "stephen" 1:16',
].join('\n');
var rows = [];
var parser = new sv.Parser();
parser.on('data', function(obj) {
rows.push(obj);
});
parser.end(input, function() {
t.equal(rows.length, 2, 'There should be two rows.');
t.equal(rows[0].name, 'chris "breezy" brown', 'The paired double quotes should be interpreted as just one double quote.');
t.end();
});
});
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