UNPKG

1.49 kBPlain TextView Raw
1import { Transform } from 'stream'
2import { Reviver } from '@naturalcycles/js-lib'
3import { TransformTyped } from '../stream.model'
4
5export interface TransformJsonParseOptions {
6 /**
7 * If true - will throw an error on JSON.parse / stringify error
8 *
9 * @default true
10 */
11 strict?: boolean
12
13 reviver?: Reviver
14}
15
16/**
17 * Transforms chunks of JSON strings/Buffers (objectMode=false) into parsed objects (readableObjectMode=true).
18 *
19 * if strict - will throw an error on JSON.parse / stringify error
20 *
21 * Usage:
22 *
23 * await _pipeline([
24 * readable,
25 * binarySplit(),
26 * transformJsonParse(),
27 * consumeYourStream...
28 * [)
29 */
30export function transformJsonParse<OUT = any>(
31 opt: TransformJsonParseOptions = {},
32): TransformTyped<string | Buffer, OUT> {
33 const { strict = true, reviver } = opt
34
35 return new Transform({
36 writableObjectMode: false,
37 readableObjectMode: true,
38 transform(chunk: string, _, cb) {
39 try {
40 const data = JSON.parse(chunk, reviver)
41 cb(null, data)
42 } catch (err) {
43 if (strict) {
44 cb(err as Error) // emit error
45 } else {
46 console.error(err)
47 cb() // emit no error, but no result neither
48 }
49 }
50 },
51 })
52}
53
54// Based on: https://stackoverflow.com/a/34557997/4919972
55export const bufferReviver: Reviver = (k, v) => {
56 if (v !== null && typeof v === 'object' && v.type === 'Buffer' && Array.isArray(v.data)) {
57 return Buffer.from(v.data)
58 }
59
60 return v
61}