UNPKG

@sergdudko/objectstream

Version:

Creates a stream to convert json from string or convert json to string.

178 lines (177 loc) 5.24 kB
import { Transform } from "stream"; import { validator } from "../utils/global.js"; /** * @class Stringifer * * Сreates an instance of Stringifer (Json to String conversion stream) */ export class Stringifer extends Transform { /** * * @param start - first separator * @param middle - middle separator * @param end - end separator */ constructor(start, middle, end) { super({ highWaterMark: 64 * 1024, objectMode: true }); if (typeof start !== "undefined" && (typeof start !== "string" || Buffer.byteLength(start) > 1 || start.match(/["{}]/))) throw new Error("Argument start require one byte String!"); if (typeof middle !== "undefined" && (typeof middle !== "string" || Buffer.byteLength(middle) > 1 || middle.match(/["{}]/))) throw new Error("Argument separator require one byte String!"); if (typeof end !== "undefined" && (typeof end !== "string" || Buffer.byteLength(end) > 1 || end.match(/["{}]/))) throw new Error("Argument end require one byte String!"); this.__separators = { start: Buffer.from(start ? start : "", "utf8"), middle: Buffer.from(middle ? middle : "", "utf8"), end: Buffer.from(end ? end : "", "utf8"), }; this.__isString = false; this.__bytesWrite = 0; this.__encoding = "utf8"; this.setDefaultEncoding(this.__encoding); } /** * separators * * @private */ __separators; /** * pass string data to the stream * * @private */ __isString; /** * stream byte counter * * @private */ __bytesWrite; /** * stream encoding * * @private */ __encoding; /** * Data event handler * * @private * @param object - object data * @param encoding - stream encoding * @param callback - callback function */ _transform(object, // eslint-disable-next-line encoding = this.__encoding, callback = () => { return; }) { if (typeof object === "undefined") { callback(); return; } if (object === null) { this._final(() => { callback(); }); return; } switch (typeof object) { case "object": try { if (validator(object, false) !== true) { callback([ new Error("Validation failed, incoming data type is not pure Object!"), ]); return; } let _buffer = Buffer.from(JSON.stringify(object), "utf8"); if (this.__bytesWrite === 0) { _buffer = Buffer.concat([this.__separators.start, _buffer]); } else { _buffer = Buffer.concat([this.__separators.middle, _buffer]); } if (this.__isString) this.push(_buffer.toString(this.__encoding)); else this.push(_buffer, this.__encoding); this.__bytesWrite += Buffer.byteLength(_buffer); callback(); return; } catch (err) { callback([err]); return; } case "undefined": callback(); return; default: callback([ new Error("Incoming data type is " + typeof object + ", require data type is pure Object!"), ]); return; } } /** * Flush event handler * * @private * @param callback - callback function */ _flush(callback = () => { return; }) { callback(); } /** * End event handler * * @private * @param callback - callback function */ _final(callback = () => { return; }) { if (this.__bytesWrite === 0) { const _buffer = Buffer.concat([ this.__separators.start, this.__separators.end, ]); if (this.__isString) this.push(_buffer.toString(this.__encoding)); else this.push(_buffer, this.__encoding); } else { if (this.__isString) this.push(this.__separators.end.toString(this.__encoding)); else this.push(this.__separators.end, this.__encoding); } this.__bytesWrite += Buffer.byteLength(this.__separators.end); callback(); } /** * set stream encoding */ setEncoding(encoding) { this.__encoding = encoding; this.setDefaultEncoding(this.__encoding); this.__isString = true; return this; } }