@coolgk/utils
Version:
javascript, typescript utility and wrapper functions and classes: array, string, base64, ampq, bcrypt, cache, captcha, csv, email, jwt, number, pdf, tmp, token, unit conversion, url params, session, form data, google sign in, facebook sign in
98 lines (96 loc) • 4.04 kB
JavaScript
/*!
* @package @coolgk/utils
* @version 3.1.4
* @link https://github.com/coolgk/node-utils
* @license MIT
* @author Daniel Gong <daniel.k.gong@gmail.com>
*
* Copyright (c) 2017 Daniel Gong <daniel.k.gong@gmail.com>. All rights reserved.
* Licensed under the MIT License.
*/
;
/*!
* Copyright (c) 2017 Daniel Gong <daniel.k.gong@gmail.com>. All rights reserved.
* Licensed under the MIT License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const csvParse = require("csv-parse");
const csvStringify = require("csv-stringify");
const queue_1 = require("@coolgk/queue");
const tmp_1 = require("@coolgk/tmp");
const fs_1 = require("fs");
class Csv {
constructor(options = {}) {
this._csvStringify = options.csvStringify || csvStringify;
this._csvParse = options.csvParse || csvParse;
this._generateFile = options.generateFile || tmp_1.generateFile;
this._tmpConfig = options.tmpConfig || {};
}
parse(value, options = {}) {
return new Promise((resolve, reject) => this._csvParse(value, options, (error, output) => (error ? reject(error) : resolve(output))));
}
readFile(file, options = {}) {
const fileStream = fs_1.createReadStream(file);
const readline = require('readline').createInterface({
input: fileStream
});
return {
forEach: (callback, endCallback) => {
let index = 0;
readline.on('line', (line) => {
if (!options.limit || index < options.limit) {
((callbackIndex) => {
queue_1.queue(() => this.parse(line, options).then(([row]) => callback(row, callbackIndex)));
})(index++);
}
else {
readline.close();
fileStream.destroy();
}
});
readline.on('close', () => endCallback && endCallback(index));
}
};
}
createFile(data, options = {}) {
return (options.filepath
? Promise.resolve({ path: options.filepath })
: this._generateFile(Object.assign({}, this._tmpConfig, { keep: true, postfix: '.csv' }))).then(({ path }) => {
const fileStream = fs_1.createWriteStream(path);
const fileStreamPromise = new Promise((resolve, reject) => {
fileStream.on('error', (error) => {
reject(error);
});
fileStream.on('finish', () => {
resolve();
});
});
return (options.columns
? this._writeCsvStream(fileStream, options.columns, options, true)
: Promise.resolve())
.then(() => new Promise((resolve, reject) => {
if (data instanceof Array) {
resolve(Promise.all(data.map((row) => this._writeCsvStream(fileStream, row, options))));
}
else {
const promises = [];
data.forEach((row) => promises.push(this._writeCsvStream(fileStream, row, options)), () => resolve(Promise.all(promises)));
}
}))
.then(() => new Promise((resolve, reject) => {
fileStream.end(() => resolve(fileStreamPromise));
}))
.then(() => path);
});
}
_writeCsvStream(writableStream, rowData, options, isHeader = false) {
return queue_1.queue(() => new Promise((resolve, reject) => Promise.resolve(rowData).then((data) => this._csvStringify([options.formatter && !isHeader ? options.formatter(data) : data], options, (error, csvRow) => error
? reject(error)
:
writableStream.write(csvRow)
? resolve()
: writableStream.once('drain', resolve)))));
}
}
exports.Csv = Csv;
exports.default = Csv;