UNPKG

3.36 kBJavaScriptView Raw
1var deserialize = require('./deserialize');
2var serialize = require('./serialize');
3var shell = require('./modes/shell');
4var log = require('./modes/log');
5var es = require('event-stream');
6var JSONStream = require('JSONStream');
7var raf = require('raf');
8var format = require('util').format;
9
10function preprocess(text, mode) {
11 /* eslint indent:0 */
12 mode = mode || 'strict';
13
14 switch (mode) {
15 case 'strict': return text;
16 case 'shell': return shell.toStrict(text);
17 case 'log': return log.toStrict(text);
18 default:
19 throw new Error(
20 format('unknown mode `%s`. Use `strict` (default), `shell` or `log`.', mode)
21 );
22 }
23}
24
25/**
26 * parses a string in strict, shell or log mode extended JSON and returns object with BSON values
27 * @param {String} text string to parse
28 * @param {Function} reviver callback function for custom parsing, @see ./reviver.js
29 * @param {Enum} mode one of `strict`, `shell`, `log`
30 * @return {Object} Object with native and/or BSON values
31 */
32module.exports.parse = function(text, reviver, mode) {
33 var normalized = preprocess(text, mode);
34 var parsed = JSON.parse(normalized, reviver);
35 return deserialize(parsed);
36};
37
38/**
39 * stringifies an object with native and/or BSON values back into strict extended JSON
40 * @param {Object} value Object or value to stringify
41 * @param {Function|Array} replacer Custom replacement
42 * @param {Number|String} space Custom spacing
43 * @return {String} JSON representation of value
44 *
45 * @see http://mzl.la/1fms8sL JSON.stringify() documentation
46 */
47module.exports.stringify = function(value, replacer, space) {
48 return JSON.stringify(serialize(value), replacer, space);
49};
50
51module.exports.deserialize = deserialize;
52module.exports.serialize = serialize;
53module.exports.reviver = require('./reviver');
54
55// JSONStream.stringify
56module.exports.createStringifyStream = function(op, sep, cl, indent) {
57 indent = indent || 0;
58 if (op === false) {
59 op = '';
60 sep = '\n';
61 cl = '';
62 } else if (op === null || op === undefined) {
63 op = '[\n';
64 sep = '\n,\n';
65 cl = '\n]\n';
66 }
67
68 // else, what ever you like
69
70 var first = true;
71 var anyData = false;
72
73 return es.through(function(data) {
74 anyData = true;
75 var json = module.exports.stringify(data, null, indent);
76 if (first) {
77 first = false;
78 this.emit('data', op + json);
79 } else {
80 this.emit('data', sep + json);
81 }
82 }, function() {
83 if (!anyData) {
84 this.emit('data', op);
85 }
86 this.emit('data', cl);
87 this.emit('end');
88 });
89};
90
91module.exports.createParseStream = function(path, map) {
92 var parser = JSONStream.parse(path, map);
93 var wrapper = es.through(function(data) {
94 raf(function() {
95 parser.write(data);
96 });
97 }, function() {
98 this.emit('end');
99 });
100
101 var emit = function ejsonParseEmit(data) {
102 wrapper.emit('data', data);
103 };
104
105 parser.on('data', function(data) {
106 deserialize.async(data, function(_, parsed) {
107 if (!Array.isArray(parsed)) {
108 emit(parsed);
109 } else {
110 for (var i = 0; i < parsed.length; i++) {
111 emit(parsed[i]);
112 }
113 }
114 });
115 })
116 .on('error', function(err) {
117 wrapper.emit('error', err);
118 })
119 .on('end', function() {
120 wrapper.emit('end');
121 });
122 return wrapper;
123};