index.js (1845B)
1 'use strict'; 2 3 module.exports = function (data, opts) { 4 if (!opts) opts = {}; 5 if (typeof opts === 'function') opts = { cmp: opts }; 6 var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false; 7 8 var cmp = opts.cmp && (function (f) { 9 return function (node) { 10 return function (a, b) { 11 var aobj = { key: a, value: node[a] }; 12 var bobj = { key: b, value: node[b] }; 13 return f(aobj, bobj); 14 }; 15 }; 16 })(opts.cmp); 17 18 var seen = []; 19 return (function stringify (node) { 20 if (node && node.toJSON && typeof node.toJSON === 'function') { 21 node = node.toJSON(); 22 } 23 24 if (node === undefined) return; 25 if (typeof node == 'number') return isFinite(node) ? '' + node : 'null'; 26 if (typeof node !== 'object') return JSON.stringify(node); 27 28 var i, out; 29 if (Array.isArray(node)) { 30 out = '['; 31 for (i = 0; i < node.length; i++) { 32 if (i) out += ','; 33 out += stringify(node[i]) || 'null'; 34 } 35 return out + ']'; 36 } 37 38 if (node === null) return 'null'; 39 40 if (seen.indexOf(node) !== -1) { 41 if (cycles) return JSON.stringify('__cycle__'); 42 throw new TypeError('Converting circular structure to JSON'); 43 } 44 45 var seenIndex = seen.push(node) - 1; 46 var keys = Object.keys(node).sort(cmp && cmp(node)); 47 out = ''; 48 for (i = 0; i < keys.length; i++) { 49 var key = keys[i]; 50 var value = stringify(node[key]); 51 52 if (!value) continue; 53 if (out) out += ','; 54 out += JSON.stringify(key) + ':' + value; 55 } 56 seen.splice(seenIndex, 1); 57 return '{' + out + '}'; 58 })(data); 59 };