|
93 | 93 | /**
|
94 | 94 | * Serialize the path to a string.
|
95 | 95 | *
|
96 |
| - * @param {Array} path |
| 96 | + * @param {Array} path |
97 | 97 | * @return {string}
|
98 | 98 | */
|
99 | 99 | function toPath (path) {
|
|
111 | 111 | }
|
112 | 112 |
|
113 | 113 | /**
|
114 |
| - * Convert JavaScript objects into strings. |
| 114 | + * Stringify an array of values. |
| 115 | + * |
| 116 | + * @param {Array} array |
| 117 | + * @param {string} indent |
| 118 | + * @param {Function} next |
| 119 | + * @return {string} |
115 | 120 | */
|
116 |
| - var OBJECT_TYPES = { |
117 |
| - '[object Array]': function (array, indent, next) { |
118 |
| - // Map array values to their stringified values with correct indentation. |
119 |
| - var values = array.map(function (value, index) { |
120 |
| - var str = next(value, index); |
| 121 | + function stringifyArray (array, indent, next) { |
| 122 | + // Map array values to their stringified values with correct indentation. |
| 123 | + var values = array.map(function (value, index) { |
| 124 | + var str = next(value, index); |
121 | 125 |
|
122 |
| - if (str === undefined) { |
123 |
| - return String(str) |
124 |
| - } |
| 126 | + if (str === undefined) { |
| 127 | + return String(str); |
| 128 | + } |
125 | 129 |
|
126 |
| - return indent + str.split('\n').join('\n' + indent); |
127 |
| - }).join(indent ? ',\n' : ','); |
| 130 | + return indent + str.split('\n').join('\n' + indent); |
| 131 | + }).join(indent ? ',\n' : ','); |
128 | 132 |
|
129 |
| - // Wrap the array in newlines if we have indentation set. |
130 |
| - if (indent && values) { |
131 |
| - return '[\n' + values + '\n]'; |
132 |
| - } |
| 133 | + // Wrap the array in newlines if we have indentation set. |
| 134 | + if (indent && values) { |
| 135 | + return '[\n' + values + '\n]'; |
| 136 | + } |
133 | 137 |
|
134 |
| - return '[' + values + ']'; |
135 |
| - }, |
136 |
| - '[object Object]': function (object, indent, next) { |
137 |
| - if (typeof Buffer === 'function' && Buffer.isBuffer(object)) { |
138 |
| - return 'new Buffer(' + stringify(object.toString()) + ')'; |
139 |
| - } |
| 138 | + return '[' + values + ']'; |
| 139 | + } |
140 | 140 |
|
141 |
| - // Iterate over object keys and concat string together. |
142 |
| - var values = Object.keys(object).reduce(function (values, key) { |
143 |
| - var value = next(object[key], key); |
| 141 | + /** |
| 142 | + * Stringify a map of values. |
| 143 | + * |
| 144 | + * @param {Object} object |
| 145 | + * @param {string} indent |
| 146 | + * @param {Function} next |
| 147 | + * @return {string} |
| 148 | + */ |
| 149 | + function stringifyObject (object, indent, next) { |
| 150 | + // Iterate over object keys and concat string together. |
| 151 | + var values = Object.keys(object).reduce(function (values, key) { |
| 152 | + var value = next(object[key], key); |
144 | 153 |
|
145 |
| - // Omit `undefined` object values. |
146 |
| - if (value === undefined) { |
147 |
| - return values; |
148 |
| - } |
| 154 | + // Omit `undefined` object values. |
| 155 | + if (value === undefined) { |
| 156 | + return values; |
| 157 | + } |
149 | 158 |
|
150 |
| - // String format the key and value data. |
151 |
| - key = isValidVariableName(key) ? key : stringify(key); |
152 |
| - value = String(value).split('\n').join('\n' + indent); |
| 159 | + // String format the key and value data. |
| 160 | + key = isValidVariableName(key) ? key : stringify(key); |
| 161 | + value = String(value).split('\n').join('\n' + indent); |
153 | 162 |
|
154 |
| - // Push the current object key and value into the values array. |
155 |
| - values.push(indent + key + ':' + (indent ? ' ' : '') + value); |
| 163 | + // Push the current object key and value into the values array. |
| 164 | + values.push(indent + key + ':' + (indent ? ' ' : '') + value); |
156 | 165 |
|
157 |
| - return values; |
158 |
| - }, []).join(indent ? ',\n' : ','); |
| 166 | + return values; |
| 167 | + }, []).join(indent ? ',\n' : ','); |
159 | 168 |
|
160 |
| - // Wrap the object in newlines if we have indentation set. |
161 |
| - if (indent && values) { |
162 |
| - return '{\n' + values + '\n}'; |
163 |
| - } |
| 169 | + // Wrap the object in newlines if we have indentation set. |
| 170 | + if (indent && values) { |
| 171 | + return '{\n' + values + '\n}'; |
| 172 | + } |
164 | 173 |
|
165 |
| - return '{' + values + '}'; |
166 |
| - }, |
| 174 | + return '{' + values + '}'; |
| 175 | + } |
| 176 | + |
| 177 | + /** |
| 178 | + * Convert JavaScript objects into strings. |
| 179 | + */ |
| 180 | + var OBJECT_TYPES = { |
| 181 | + '[object Array]': stringifyArray, |
| 182 | + '[object Object]': stringifyObject, |
167 | 183 | '[object Date]': function (date) {
|
168 | 184 | return 'new Date(' + date.getTime() + ')';
|
169 | 185 | },
|
|
177 | 193 | return 'new Boolean(' + boolean + ')';
|
178 | 194 | },
|
179 | 195 | '[object Uint8Array]': function (array, indent) {
|
180 |
| - if (typeof Buffer === 'function' && Buffer.isBuffer(array)) { |
181 |
| - return 'new Buffer(' + stringify(array.toString()) + ')'; |
182 |
| - } |
183 |
| - |
184 |
| - if (indent) { |
185 |
| - var str = ''; |
186 |
| - |
187 |
| - for (var i = 0; i < array.length; i++) { |
188 |
| - str += indent + array[i] + ',\n' |
189 |
| - } |
190 |
| - |
191 |
| - return 'new Uint8Array([\n' + str + '\n])' |
192 |
| - } |
193 |
| - |
194 |
| - return 'new Uint8Array([' + array.join(indent ? ',\n' : ',') + '])' |
| 196 | + return 'new Uint8Array(' + stringifyArray(array) + ')'; |
195 | 197 | },
|
196 | 198 | '[object RegExp]': String,
|
197 | 199 | '[object Function]': String,
|
|
227 | 229 | return PRIMITIVE_TYPES[typeof value](value, indent, next);
|
228 | 230 | }
|
229 | 231 |
|
| 232 | + // Handle buffer objects before recursing (node < 6 was an object, node >= 6 is a `Uint8Array`). |
| 233 | + if (typeof Buffer === 'function' && Buffer.isBuffer(value)) { |
| 234 | + return 'new Buffer(' + next(value.toString()) + ')'; |
| 235 | + } |
| 236 | + |
230 | 237 | // Use the internal object string to select stringification method.
|
231 | 238 | var toString = OBJECT_TYPES[Object.prototype.toString.call(value)];
|
232 | 239 |
|
|
253 | 260 |
|
254 | 261 | var maxDepth = Number(options.maxDepth) || 100;
|
255 | 262 | var references = !!options.references;
|
| 263 | + var skipUndefinedProperties = !!options.skipUndefinedProperties; |
256 | 264 | var valueCount = Number(options.maxValues) || 100000;
|
257 | 265 |
|
258 | 266 | var path = [];
|
|
269 | 277 | * @return {string}
|
270 | 278 | */
|
271 | 279 | function next (value, key) {
|
| 280 | + if (skipUndefinedProperties && value === undefined) { |
| 281 | + return undefined; |
| 282 | + } |
| 283 | + |
272 | 284 | path.push(key);
|
273 | 285 | var result = recurse(value, stringify);
|
274 | 286 | path.pop();
|
|
0 commit comments