-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
72 lines (64 loc) · 1.88 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
const { Transform } = require('stream');
/**
* The ReadlineTransform is reading String or Buffer content from a Readable stream
* and writing each line which ends without line break as object
*
* @param {RegExp} opts.breakMatcher - line break matcher for str.split() (default: /\r?\n/)
* @param {Boolean} opts.ignoreEndOfBreak - if content ends with line break, ignore last empty line (default: true)
* @param {Boolean} opts.skipEmpty - if line is empty string, skip it (default: false)
*/
class ReadlineTransform extends Transform {
constructor(options) {
const opts = options || {};
opts.objectMode = true;
super(opts);
this._brRe = opts.breakMatcher || /\r?\n/;
this._ignoreEndOfBreak = 'ignoreEndOfBreak' in opts ? Boolean(opts.ignoreEndOfBreak) : true;
this._skipEmpty = Boolean(opts.skipEmpty);
this._buf = null;
}
_transform(chunk, encoding, cb) {
let str;
if (Buffer.isBuffer(chunk) || encoding === 'buffer') {
str = chunk.toString('utf8');
} else {
str = chunk;
}
try {
if (this._buf !== null) {
this._buf += str;
} else {
this._buf = str;
}
const lines = this._buf.split(this._brRe);
const lastIndex = lines.length - 1;
for (let i = 0; i < lastIndex; i++) {
this._writeItem(lines[i]);
}
const lastLine = lines[lastIndex];
if (lastLine.length) {
this._buf = lastLine;
} else if (!this._ignoreEndOfBreak) {
this._buf = '';
} else {
this._buf = null;
}
cb();
} catch(err) {
cb(err); // invalid data type;
}
}
_flush(cb) {
if (this._buf !== null) {
this._writeItem(this._buf);
this._buf = null;
}
cb();
}
_writeItem(line) {
if (line.length > 0 || !this._skipEmpty) {
this.push(line);
}
}
}
module.exports = exports.default = ReadlineTransform;