UNPKG

ravendb

Version:
133 lines 4.84 kB
import { EventEmitter } from "node:events"; import { ObjectKeyCaseTransformStream } from "../Mapping/Json/Streams/ObjectKeyCaseTransformStream.js"; import { pipelineAsync } from "../Utility/StreamUtil.js"; import { Transform, pipeline } from "node:stream"; import { CollectResultStream, } from "../Mapping/Json/Streams/CollectResultStream.js"; import { throwError, getError } from "../Exceptions/index.js"; import { TypeUtil } from "../Utility/TypeUtil.js"; import { StringBuilder } from "../Utility/StringBuilder.js"; import { Buffer } from "node:buffer"; import { JsonlParser } from "../ext/stream-json/jsonl/Parser.js"; export class RavenCommandResponsePipeline extends EventEmitter { _opts; _body = new StringBuilder(); constructor() { super(); this._opts = {}; } static create() { return new RavenCommandResponsePipeline(); } parseJsonSync() { this._opts.jsonSync = true; return this; } /** * @param type Type of object to extract from objects stream - use Raw to skip extraction. * @param options */ parseJsonlAsync(valueExtractor, options = {}) { const transforms = options?.transforms ?? []; const extractItemTransform = new Transform({ objectMode: true, transform(chunk, encoding, callback) { const value = valueExtractor(chunk["value"]); if (!value) { return callback(); } callback(null, { ...chunk, value }); } }); transforms.unshift(extractItemTransform); this._opts.jsonlAsync = { transforms }; return this; } collectBody(callback) { this._opts.collectBody = callback || true; return this; } objectKeysTransform(optsOrTransform) { this._opts.streamKeyCaseTransform = !optsOrTransform || typeof optsOrTransform === "function" ? { defaultTransform: optsOrTransform } : optsOrTransform; return this; } stream(src, dst, callback) { const streams = this._buildUp(src); if (dst) { streams.push(dst); } return pipeline(...streams, TypeUtil.NOOP); } _appendBody(s) { this._body.append(s.toString()); } _buildUp(src) { if (!src) { throwError("MappingError", "Body stream cannot be null."); } const opts = this._opts; const streams = [src]; if (opts.collectBody) { src.on("data", (chunk) => this._appendBody(chunk)); } if (opts.jsonlAsync) { streams.push(new JsonlParser()); if (opts.jsonlAsync.transforms) { streams.push(...opts.jsonlAsync.transforms); } } else if (opts.jsonSync) { const bytesChunks = []; const parseJsonSyncTransform = new Transform({ readableObjectMode: true, transform(chunk, enc, callback) { bytesChunks.push(chunk); callback(); }, flush(callback) { let str = null; try { str = Buffer.concat(bytesChunks).toString("utf8"); } catch (err) { callback(getError("InvalidDataException", `Failed to concat / decode server response`, err)); return; } try { callback(null, JSON.parse(str)); } catch (err) { callback(getError("InvalidOperationException", `Error parsing response: '${str}'.`, err)); } } }); streams.push(parseJsonSyncTransform); } if (opts.streamKeyCaseTransform) { const keyCaseOpts = Object.assign({}, opts.streamKeyCaseTransform, { handlePath: false }); streams.push(new ObjectKeyCaseTransformStream(keyCaseOpts)); } return streams; } async process(src) { const streams = this._buildUp(src); const opts = this._opts; const collectResult = new CollectResultStream(); streams.push(collectResult); const resultPromise = collectResult.promise; await pipelineAsync(...streams); const result = await resultPromise; if (opts.collectBody) { const body = this._body.toString(); this.emit("body", body); if (typeof opts.collectBody === "function") { opts.collectBody(body); } } return result; } } //# sourceMappingURL=RavenCommandResponsePipeline.js.map