Comparing version 0.5.0 to 0.6.0
@@ -20,2 +20,6 @@ #! /usr/bin/env node | ||
.options({ | ||
'encoding': { | ||
describe: 'Overwrite detected input encoding', | ||
type: 'string', | ||
}, | ||
'in-place': { | ||
@@ -26,2 +30,7 @@ default: false, | ||
}, | ||
'skip-start': { | ||
default: 0, | ||
describe: 'Skip lines at the start of the input', | ||
type: 'number', | ||
}, | ||
}) | ||
@@ -45,3 +54,6 @@ .example('csvnorm input.csv > normalized.csv', 'Normalize a CSV file') | ||
index_1.default({ | ||
encoding: options.encoding, | ||
readableStream: stdin, | ||
// skipLinesEnd: options['skip-end'], | ||
skipLinesStart: options['skip-start'], | ||
writableStream: stdout, | ||
@@ -56,4 +68,7 @@ }); | ||
index_1.default({ | ||
encoding: options.encoding, | ||
filePath: path.resolve(csvFilePath), | ||
inPlace: options['in-place'], | ||
// skipLinesEnd: options['skip-end'], | ||
skipLinesStart: options['skip-start'], | ||
}); | ||
@@ -60,0 +75,0 @@ } |
@@ -1,2 +0,2 @@ | ||
declare const _default: (value: string) => string | undefined; | ||
declare const _default: (value: string) => string; | ||
export default _default; |
@@ -22,2 +22,5 @@ "use strict"; | ||
} | ||
else { | ||
return value; | ||
} | ||
}; |
@@ -1,2 +0,2 @@ | ||
declare const _default: (value: string) => string | null | undefined; | ||
declare const _default: (value: string) => string | undefined; | ||
export default _default; |
@@ -5,3 +5,3 @@ "use strict"; | ||
if (typeof value !== 'string') { | ||
return null; | ||
return undefined; | ||
} | ||
@@ -20,2 +20,3 @@ const mmddyyyy = /^([01][0-9])\/([0-3][0-9])\/([0-9]{4})$/; | ||
} | ||
return undefined; | ||
}; |
@@ -1,2 +0,1 @@ | ||
declare const _default: (value: string) => number | null | undefined; | ||
export default _default; | ||
export default function (value: string): number | undefined; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = (value) => { | ||
function default_1(value) { | ||
if (typeof value !== 'string') { | ||
return null; | ||
return undefined; | ||
} | ||
const containsANumber = /^[0-9+-.,]+$/.test(value); | ||
if (!containsANumber) { | ||
return null; | ||
return undefined; | ||
} | ||
@@ -33,2 +33,4 @@ const containsASeparator = /[.,]/.test(value); | ||
} | ||
}; | ||
return undefined; | ||
} | ||
exports.default = default_1; |
@@ -8,4 +8,4 @@ /// <reference types="node" /> | ||
constructor(opts: FormatterOptions); | ||
_transform(row: string[], chunkEncoding: string, chunkIsProcessedCb: () => void): void; | ||
_transform(row: string[], _1: string, chunkIsProcessedCb: () => void): void; | ||
} | ||
export {}; |
@@ -12,3 +12,3 @@ "use strict"; | ||
} | ||
_transform(row, chunkEncoding, chunkIsProcessedCb) { | ||
_transform(row, _1, chunkIsProcessedCb) { | ||
const formattedRow = row | ||
@@ -15,0 +15,0 @@ .map((cell) => { |
/// <reference types="node" /> | ||
import * as stream from 'stream'; | ||
interface MainOptions { | ||
encoding?: string; | ||
filePath?: string; | ||
inPlace?: boolean; | ||
readableStream?: stream; | ||
skipLinesStart?: number; | ||
writableStream?: stream; | ||
@@ -8,0 +10,0 @@ } |
@@ -13,6 +13,9 @@ "use strict"; | ||
function printCsv(options) { | ||
const { configGenerator, inputFilePath, writableStream, } = options; | ||
const { configGenerator, encoding, skipLinesStart = 0, | ||
// skipLinesEnd = 0, | ||
inputFilePath, writableStream, } = options; | ||
const formatter = new Formatter_1.default({}); | ||
const parser = csvParse({ | ||
delimiter: configGenerator.mostFrequentDelimter, | ||
from_line: skipLinesStart + 1, | ||
}); | ||
@@ -24,3 +27,3 @@ parser.on('error', console.error); | ||
.createReadStream(inputFilePath) | ||
.pipe(toUtf8()) | ||
.pipe(toUtf8({ encoding })) | ||
.pipe(parser) | ||
@@ -30,35 +33,37 @@ .pipe(formatter) | ||
.pipe(writableStream || process.stdout); | ||
// .pipe(process.stdout) | ||
} | ||
exports.default = (options) => { | ||
const { filePath, inPlace, readableStream, } = options; | ||
let { writableStream } = options; | ||
class ConfigGenerator extends stream.Writable { | ||
constructor(opts) { | ||
super(opts); | ||
this.delimiterHistogram = { | ||
'\t': 0, | ||
',': 0, | ||
';': 0, | ||
'|': 0, | ||
}; | ||
this.mostFrequentDelimter = ','; | ||
} | ||
_write(chunk, chunkEncoding, chunkIsProcessedCb) { | ||
for (let charIndex = 0; charIndex < chunk.length; charIndex++) { | ||
const char = chunk.toString()[charIndex]; | ||
if (this.delimiterHistogram.hasOwnProperty(char)) { | ||
this.delimiterHistogram[char]++; | ||
} | ||
class ConfigGenerator extends stream.Writable { | ||
constructor(opts) { | ||
super(opts); | ||
this.delimiterHistogram = { | ||
'\t': 0, | ||
',': 0, | ||
';': 0, | ||
'|': 0, | ||
}; | ||
this.mostFrequentDelimter = ','; | ||
} | ||
_write(chunk, _1, chunkIsProcessedCb) { | ||
for (const char of chunk.toString()) { | ||
if (this.delimiterHistogram.hasOwnProperty(char)) { | ||
this.delimiterHistogram[char]++; | ||
} | ||
chunkIsProcessedCb(); | ||
} | ||
_final(done) { | ||
const pairs = Array | ||
.from(Object.entries(this.delimiterHistogram)) | ||
.sort((itemA, itemB) => itemB[1] - itemA[1]); | ||
// [first entry of delimiter list][key of entry] | ||
this.mostFrequentDelimter = pairs[0][0]; | ||
done(); | ||
} | ||
chunkIsProcessedCb(); | ||
} | ||
_final(done) { | ||
const pairs = Array | ||
.from(Object.entries(this.delimiterHistogram)) | ||
.sort((itemA, itemB) => itemB[1] - itemA[1]); | ||
// [first entry of delimiter list][key of entry] | ||
this.mostFrequentDelimter = pairs[0][0]; | ||
done(); | ||
} | ||
} | ||
exports.default = (options) => { | ||
const { encoding, filePath, inPlace, readableStream, | ||
// skipLinesEnd = 0, | ||
skipLinesStart = 0, } = options; | ||
let { writableStream } = options; | ||
const configGenerator = new ConfigGenerator({}); | ||
@@ -80,3 +85,6 @@ if (filePath) { | ||
configGenerator, | ||
encoding, | ||
inputFilePath: filePath, | ||
// skipLinesEnd, | ||
skipLinesStart, | ||
writableStream, | ||
@@ -97,3 +105,6 @@ }); | ||
configGenerator, | ||
encoding, | ||
inputFilePath: temporaryFilePath, | ||
// skipLinesEnd, | ||
skipLinesStart, | ||
writableStream, | ||
@@ -100,0 +111,0 @@ }); |
@@ -18,4 +18,5 @@ "use strict"; | ||
assert.equal(tempContent, expectedOutput); | ||
await fse.remove(tempPathAbsolute); | ||
console.info(' ✔︎'); | ||
} | ||
main(); |
{ | ||
"name": "csvnorm", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"description": "Command line tool to normalize CSV and *SV files.", | ||
@@ -10,5 +10,6 @@ "main": "binary/source/index.js", | ||
"scripts": { | ||
"clean": "rm -rf binary", | ||
"lint": "yarn tslint '{source,tests,types}/**/*.ts'", | ||
"build": "yarn tsc && chmod 755 binary/source/cli.js", | ||
"unit-test": "yarn build && for file in binary/tests/{require,empty-lines,main,input-stream,in-place}.js; do node $file; done", | ||
"unit-test": "yarn build && for file in binary/tests/*.js; do node $file; done", | ||
"test": "yarn lint && yarn unit-test" | ||
@@ -15,0 +16,0 @@ }, |
@@ -30,17 +30,20 @@ # Csvnorm | ||
```sh | ||
csvnorm data.csv | ||
``` | ||
```txt | ||
Usage: | ||
csvnorm [Options] INFILE [> OUTFILE] | ||
csvnorm [Options] < INFILE [> OUTFILE] | ||
```sh | ||
cat data.csv | csvnorm | ||
Options: | ||
--encoding Overwrite detected input encoding [string] | ||
--in-place Normalize CSV file in place [boolean] [default: false] | ||
--skip-start Skip lines at the start of the input [number] [default: 0] | ||
--version Show version number [boolean] | ||
--help Show help [boolean] | ||
Examples: | ||
csvnorm input.csv > normalized.csv Normalize a CSV file | ||
cat input.csv | csvnorm > normalized.csv Pipe and normalize a CSV file | ||
``` | ||
### TODO | ||
- [ ] Print debugging info in TTY mode | ||
## Node Module | ||
@@ -83,1 +86,9 @@ | ||
``` | ||
### TODO | ||
- [ ] Print debugging info in TTY mode | ||
- [ ] Improve encoding detection | ||
(e.g. fork and update https://github.com/finnp/to-utf-8) | ||
- [ ] Implement `skipLinesEnd` |
{ | ||
"compilerOptions": { | ||
"target": "es2017", | ||
"alwaysStrict": true, | ||
"declaration": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"module": "commonjs", | ||
"declaration": true, | ||
"noFallthroughCasesInSwitch": true, | ||
"noImplicitAny": true, | ||
"noImplicitReturns": true, | ||
"noImplicitThis": true, | ||
"noUnusedLocals": true, | ||
"noUnusedParameters": true, | ||
"outDir": "./binary", | ||
"strict": true | ||
"strict": true, | ||
"strictBindCallApply": true, | ||
"strictFunctionTypes": true, | ||
"strictPropertyInitialization": true, | ||
"strictNullChecks" : true, | ||
"target": "es2017" | ||
}, | ||
@@ -9,0 +21,0 @@ "include": ["source", "tests", "types"], |
Sorry, the diff of this file is not supported yet
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
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
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
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
60404
35
514
93
2
7