source: imaps-frontend/node_modules/json5/lib/stringify.js

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 6.8 KB
Line 
1const util = require('./util')
2
3module.exports = function stringify (value, replacer, space) {
4 const stack = []
5 let indent = ''
6 let propertyList
7 let replacerFunc
8 let gap = ''
9 let quote
10
11 if (
12 replacer != null &&
13 typeof replacer === 'object' &&
14 !Array.isArray(replacer)
15 ) {
16 space = replacer.space
17 quote = replacer.quote
18 replacer = replacer.replacer
19 }
20
21 if (typeof replacer === 'function') {
22 replacerFunc = replacer
23 } else if (Array.isArray(replacer)) {
24 propertyList = []
25 for (const v of replacer) {
26 let item
27
28 if (typeof v === 'string') {
29 item = v
30 } else if (
31 typeof v === 'number' ||
32 v instanceof String ||
33 v instanceof Number
34 ) {
35 item = String(v)
36 }
37
38 if (item !== undefined && propertyList.indexOf(item) < 0) {
39 propertyList.push(item)
40 }
41 }
42 }
43
44 if (space instanceof Number) {
45 space = Number(space)
46 } else if (space instanceof String) {
47 space = String(space)
48 }
49
50 if (typeof space === 'number') {
51 if (space > 0) {
52 space = Math.min(10, Math.floor(space))
53 gap = ' '.substr(0, space)
54 }
55 } else if (typeof space === 'string') {
56 gap = space.substr(0, 10)
57 }
58
59 return serializeProperty('', {'': value})
60
61 function serializeProperty (key, holder) {
62 let value = holder[key]
63 if (value != null) {
64 if (typeof value.toJSON5 === 'function') {
65 value = value.toJSON5(key)
66 } else if (typeof value.toJSON === 'function') {
67 value = value.toJSON(key)
68 }
69 }
70
71 if (replacerFunc) {
72 value = replacerFunc.call(holder, key, value)
73 }
74
75 if (value instanceof Number) {
76 value = Number(value)
77 } else if (value instanceof String) {
78 value = String(value)
79 } else if (value instanceof Boolean) {
80 value = value.valueOf()
81 }
82
83 switch (value) {
84 case null: return 'null'
85 case true: return 'true'
86 case false: return 'false'
87 }
88
89 if (typeof value === 'string') {
90 return quoteString(value, false)
91 }
92
93 if (typeof value === 'number') {
94 return String(value)
95 }
96
97 if (typeof value === 'object') {
98 return Array.isArray(value) ? serializeArray(value) : serializeObject(value)
99 }
100
101 return undefined
102 }
103
104 function quoteString (value) {
105 const quotes = {
106 "'": 0.1,
107 '"': 0.2,
108 }
109
110 const replacements = {
111 "'": "\\'",
112 '"': '\\"',
113 '\\': '\\\\',
114 '\b': '\\b',
115 '\f': '\\f',
116 '\n': '\\n',
117 '\r': '\\r',
118 '\t': '\\t',
119 '\v': '\\v',
120 '\0': '\\0',
121 '\u2028': '\\u2028',
122 '\u2029': '\\u2029',
123 }
124
125 let product = ''
126
127 for (let i = 0; i < value.length; i++) {
128 const c = value[i]
129 switch (c) {
130 case "'":
131 case '"':
132 quotes[c]++
133 product += c
134 continue
135
136 case '\0':
137 if (util.isDigit(value[i + 1])) {
138 product += '\\x00'
139 continue
140 }
141 }
142
143 if (replacements[c]) {
144 product += replacements[c]
145 continue
146 }
147
148 if (c < ' ') {
149 let hexString = c.charCodeAt(0).toString(16)
150 product += '\\x' + ('00' + hexString).substring(hexString.length)
151 continue
152 }
153
154 product += c
155 }
156
157 const quoteChar = quote || Object.keys(quotes).reduce((a, b) => (quotes[a] < quotes[b]) ? a : b)
158
159 product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar])
160
161 return quoteChar + product + quoteChar
162 }
163
164 function serializeObject (value) {
165 if (stack.indexOf(value) >= 0) {
166 throw TypeError('Converting circular structure to JSON5')
167 }
168
169 stack.push(value)
170
171 let stepback = indent
172 indent = indent + gap
173
174 let keys = propertyList || Object.keys(value)
175 let partial = []
176 for (const key of keys) {
177 const propertyString = serializeProperty(key, value)
178 if (propertyString !== undefined) {
179 let member = serializeKey(key) + ':'
180 if (gap !== '') {
181 member += ' '
182 }
183 member += propertyString
184 partial.push(member)
185 }
186 }
187
188 let final
189 if (partial.length === 0) {
190 final = '{}'
191 } else {
192 let properties
193 if (gap === '') {
194 properties = partial.join(',')
195 final = '{' + properties + '}'
196 } else {
197 let separator = ',\n' + indent
198 properties = partial.join(separator)
199 final = '{\n' + indent + properties + ',\n' + stepback + '}'
200 }
201 }
202
203 stack.pop()
204 indent = stepback
205 return final
206 }
207
208 function serializeKey (key) {
209 if (key.length === 0) {
210 return quoteString(key, true)
211 }
212
213 const firstChar = String.fromCodePoint(key.codePointAt(0))
214 if (!util.isIdStartChar(firstChar)) {
215 return quoteString(key, true)
216 }
217
218 for (let i = firstChar.length; i < key.length; i++) {
219 if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) {
220 return quoteString(key, true)
221 }
222 }
223
224 return key
225 }
226
227 function serializeArray (value) {
228 if (stack.indexOf(value) >= 0) {
229 throw TypeError('Converting circular structure to JSON5')
230 }
231
232 stack.push(value)
233
234 let stepback = indent
235 indent = indent + gap
236
237 let partial = []
238 for (let i = 0; i < value.length; i++) {
239 const propertyString = serializeProperty(String(i), value)
240 partial.push((propertyString !== undefined) ? propertyString : 'null')
241 }
242
243 let final
244 if (partial.length === 0) {
245 final = '[]'
246 } else {
247 if (gap === '') {
248 let properties = partial.join(',')
249 final = '[' + properties + ']'
250 } else {
251 let separator = ',\n' + indent
252 let properties = partial.join(separator)
253 final = '[\n' + indent + properties + ',\n' + stepback + ']'
254 }
255 }
256
257 stack.pop()
258 indent = stepback
259 return final
260 }
261}
Note: See TracBrowser for help on using the repository browser.