Skip to content

Commit 186d8cd

Browse files
committed
Resolves #7
1 parent ba4bf0b commit 186d8cd

File tree

4 files changed

+66
-17
lines changed

4 files changed

+66
-17
lines changed

.vscode/launch.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"type": "node",
9+
"request": "launch",
10+
"name": "Debug Mocha",
11+
"program": "${workspaceFolder}\\node_modules\\mocha\\bin\\_mocha",
12+
"stopOnEntry": false,
13+
"args": ["-R", "spec", "-b"],
14+
"cwd": "${workspaceFolder}",
15+
"runtimeExecutable": null
16+
}
17+
]
18+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "json-stream-stringify",
33
"description": "JSON.Stringify as a readable stream",
4-
"version": "2.0.0",
4+
"version": "2.0.1",
55
"license": "MIT",
66
"author": "Faleij <faleij@gmail.com> (https://github.com/faleij)",
77
"repository": {

src/JsonStreamStringify.js

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class JsonStreamStringify extends Readable {
120120
return value;
121121
}
122122

123-
addToStack(value, key, index) {
123+
addToStack(value, key, index, parent) {
124124
let realValue = value;
125125
if (this.replacerFunction) {
126126
realValue = this.replacerFunction(key || index, realValue, this);
@@ -138,6 +138,13 @@ class JsonStreamStringify extends Readable {
138138
}
139139
}
140140
let type = getType(realValue);
141+
if (((parent && parent.type === 'Array') ? true : realValue !== undefined) && type !== 'Promise') {
142+
if (parent && !parent.first) {
143+
this._push(',');
144+
}
145+
/* eslint-disable-next-line no-param-reassign */
146+
if (parent) parent.first = false;
147+
}
141148
if (realValue !== undefined && type !== 'Promise' && key) {
142149
if (this.gap) {
143150
this._push(`\n${this.gap.repeat(this.depth)}"${escapeString(key)}": `);
@@ -172,6 +179,8 @@ class JsonStreamStringify extends Readable {
172179
index,
173180
type,
174181
value: realValue,
182+
parent,
183+
first: true,
175184
};
176185

177186
if (type === 'Object') {
@@ -199,7 +208,6 @@ class JsonStreamStringify extends Readable {
199208
this.error = true;
200209
this.emit('error', err);
201210
});
202-
obj.first = true;
203211
}
204212
this.stack.unshift(obj);
205213
return obj;
@@ -222,10 +230,8 @@ class JsonStreamStringify extends Readable {
222230
const end = stackItemEnd[type];
223231
if (isObject && !item.isEmpty && this.gap) this._push(`\n${this.gap.repeat(this.depth)}`);
224232
if (end) this._push(end);
225-
if (item.addSeparatorAfterEnd) {
226-
this._push(',');
227-
}
228-
this.stack.splice(this.stack.indexOf(item), 1);
233+
const stackIndex = this.stack.indexOf(item);
234+
this.stack.splice(stackIndex, 1);
229235
}
230236

231237
_push(data) {
@@ -254,14 +260,15 @@ class JsonStreamStringify extends Readable {
254260
}
255261

256262
processObject(current) {
263+
// when no keys left, remove obj from stack
257264
if (!current.unread.length) {
258265
this.removeFromStack(current);
259266
return;
260267
}
261268
const key = current.unread.shift();
262269
const value = current.value[key];
263270

264-
this.addToStack(value, current.type === 'Object' && key, current.type === 'Array' && key).addSeparatorAfterEnd = !!current.unread.length;
271+
this.addToStack(value, current.type === 'Object' && key, current.type === 'Array' && key, current);
265272
}
266273

267274
processArray(current) {
@@ -319,14 +326,8 @@ class JsonStreamStringify extends Readable {
319326

320327
processPromise(current) {
321328
return recursiveResolve(current.value).then((value) => {
322-
const {
323-
addSeparatorAfterEnd,
324-
} = current;
325-
/* eslint-disable-next-line no-param-reassign */
326-
current.addSeparatorAfterEnd = false;
327329
this.removeFromStack(current);
328-
this.addToStack(value, current.key, current.index)
329-
.addSeparatorAfterEnd = addSeparatorAfterEnd;
330+
this.addToStack(value, current.key, current.index, current.parent);
330331
});
331332
}
332333

test-src/JsonStreamStringify.spec.js

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,23 @@ describe('JsonStreamStringify', () => {
8484
return v;
8585
}));
8686

87+
it('{a:1, b:2} should be {"a":1}', createTest({
88+
a: 1,
89+
b: 2,
90+
}, '{"a":1}', (k, v) => {
91+
if (k === 'a') {
92+
expect(v).to.be(1);
93+
return v;
94+
}
95+
if (k === 'b') {
96+
expect(v).to.be(2);
97+
return undefined;
98+
}
99+
if (k === undefined) return v;
100+
expect(['a', 'b', undefined]).to.contain(k);
101+
return v;
102+
}));
103+
87104
it('{a:1,b:2} should be {"b":2}', createTest({
88105
a: 1,
89106
b: 2,
@@ -93,11 +110,24 @@ describe('JsonStreamStringify', () => {
93110
a: 1,
94111
}, '{"a":1}'));
95112

96-
it('{a:function(){}} should be {}', createTest({
113+
it('{a:1,b:undefined} should be {"a":1}', createTest({
114+
a: 1,
115+
b: undefined,
116+
}, '{"a":1}'));
117+
118+
it('{a:1,b:Promise(undefined)} should be {"a":1}', createTest({
119+
a: 1,
120+
b: Promise.resolve(undefined),
121+
}, '{"a":1}'));
122+
123+
it('{a:function(){}, b: "b"} should be {"b": "b"}', createTest({
97124
a() {},
98-
}, '{}'));
125+
b: 'b',
126+
}, '{"b":"b"}'));
99127

100128
it('[function(){}] should be [null]', createTest([function a() {}], '[null]'));
129+
130+
it('[function(){}, undefined] should be [null,null]', createTest([function a() {}, undefined], '[null,null]'));
101131

102132
it('{a:date} should be {"a":date.toJSON()}', createTest({
103133
a: date,

0 commit comments

Comments
 (0)