| var json = typeof JSON !== 'undefined' ? JSON : require('jsonify'); |
| |
| module.exports = function (obj, opts) { |
| if (!opts) opts = {}; |
| if (typeof opts === 'function') opts = { cmp: opts }; |
| var cmp = opts.cmp && (function (f) { |
| return function (node) { |
| return function (a, b) { |
| var aobj = { key: a, value: node[a] }; |
| var bobj = { key: b, value: node[b] }; |
| return f(aobj, bobj); |
| }; |
| }; |
| })(opts.cmp); |
| |
| return (function stringify (node) { |
| if (typeof node !== 'object' || node === null) { |
| return json.stringify(node); |
| } |
| if (isArray(node)) { |
| var out = []; |
| for (var i = 0; i < node.length; i++) { |
| out.push(stringify(node[i])); |
| } |
| return '[' + out.join(',') + ']'; |
| } |
| else { |
| var keys = objectKeys(node).sort(cmp && cmp(node)); |
| var out = []; |
| for (var i = 0; i < keys.length; i++) { |
| var key = keys[i]; |
| out.push(stringify(key) + ':' + stringify(node[key])); |
| } |
| return '{' + out.join(',') + '}'; |
| } |
| })(obj); |
| }; |
| |
| var isArray = Array.isArray || function (x) { |
| return {}.toString.call(x) === '[object Array]'; |
| }; |
| |
| var objectKeys = Object.keys || function (obj) { |
| var has = Object.prototype.hasOwnProperty || function () { return true }; |
| var keys = []; |
| for (var key in obj) { |
| if (has.call(obj, key)) keys.push(key); |
| } |
| return keys; |
| }; |