Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80713 views
1
#! /usr/bin/env node
2
3
var Parser = require('jsonparse')
4
, through = require('through')
5
6
/*
7
8
the value of this.stack that creationix's jsonparse has is weird.
9
10
it makes this code ugly, but his problem is way harder that mine,
11
so i'll forgive him.
12
13
*/
14
15
exports.parse = function (path, map) {
16
17
var parser = new Parser()
18
var stream = through(function (chunk) {
19
if('string' === typeof chunk)
20
chunk = new Buffer(chunk)
21
parser.write(chunk)
22
},
23
function (data) {
24
if(data)
25
stream.write(data)
26
stream.queue(null)
27
})
28
29
if('string' === typeof path)
30
path = path.split('.').map(function (e) {
31
if (e === '*')
32
return true
33
else if (e === '') // '..'.split('.') returns an empty string
34
return {recurse: true}
35
else
36
return e
37
})
38
39
40
var count = 0, _key
41
if(!path || !path.length)
42
path = null
43
44
parser.onValue = function () {
45
if (!this.root && this.stack.length == 1)
46
stream.root = this.value
47
48
if(! path) return
49
50
var i = 0 // iterates on path
51
var j = 0 // iterates on stack
52
while (i < path.length) {
53
var key = path[i]
54
var c
55
j++
56
57
if (key && !key.recurse) {
58
c = (j === this.stack.length) ? this : this.stack[j]
59
if (!c) return
60
if (! check(key, c.key)) return
61
i++
62
} else {
63
i++
64
var nextKey = path[i]
65
if (! nextKey) return
66
while (true) {
67
c = (j === this.stack.length) ? this : this.stack[j]
68
if (!c) return
69
if (check(nextKey, c.key)) { i++; break}
70
j++
71
}
72
}
73
}
74
if (j !== this.stack.length) return
75
76
count ++
77
var data = this.value[this.key]
78
if(null != data)
79
if(null != (data = map ? map(data) : data))
80
stream.queue(data)
81
delete this.value[this.key]
82
}
83
parser._onToken = parser.onToken;
84
85
parser.onToken = function (token, value) {
86
parser._onToken(token, value);
87
if (this.stack.length === 0) {
88
if (stream.root) {
89
if(!path)
90
stream.queue(stream.root)
91
stream.emit('root', stream.root, count)
92
count = 0;
93
stream.root = null;
94
}
95
}
96
}
97
98
parser.onError = function (err) {
99
stream.emit('error', err)
100
}
101
102
103
return stream
104
}
105
106
function check (x, y) {
107
if ('string' === typeof x)
108
return y == x
109
else if (x && 'function' === typeof x.exec)
110
return x.exec(y)
111
else if ('boolean' === typeof x)
112
return x
113
else if ('function' === typeof x)
114
return x(y)
115
return false
116
}
117
118
exports.stringify = function (op, sep, cl, indent) {
119
indent = indent || 0
120
if (op === false){
121
op = ''
122
sep = '\n'
123
cl = ''
124
} else if (op == null) {
125
126
op = '[\n'
127
sep = '\n,\n'
128
cl = '\n]\n'
129
130
}
131
132
//else, what ever you like
133
134
var stream
135
, first = true
136
, anyData = false
137
stream = through(function (data) {
138
anyData = true
139
var json = JSON.stringify(data, null, indent)
140
if(first) { first = false ; stream.queue(op + json)}
141
else stream.queue(sep + json)
142
},
143
function (data) {
144
if(!anyData)
145
stream.queue(op)
146
stream.queue(cl)
147
stream.queue(null)
148
})
149
150
return stream
151
}
152
153
exports.stringifyObject = function (op, sep, cl, indent) {
154
indent = indent || 0
155
if (op === false){
156
op = ''
157
sep = '\n'
158
cl = ''
159
} else if (op == null) {
160
161
op = '{\n'
162
sep = '\n,\n'
163
cl = '\n}\n'
164
165
}
166
167
//else, what ever you like
168
169
var first = true
170
, anyData = false
171
stream = through(function (data) {
172
anyData = true
173
var json = JSON.stringify(data[0]) + ':' + JSON.stringify(data[1], null, indent)
174
if(first) { first = false ; this.queue(op + json)}
175
else this.queue(sep + json)
176
},
177
function (data) {
178
if(!anyData) this.queue(op)
179
this.queue(cl)
180
181
this.queue(null)
182
})
183
184
return stream
185
}
186
187
if(!module.parent && process.title !== 'browser') {
188
process.stdin
189
.pipe(exports.parse(process.argv[2]))
190
.pipe(exports.stringify('[', ',\n', ']\n', 2))
191
.pipe(process.stdout)
192
}
193
194