| 'use strict'; |
| module.exports = function (object, filterFn) { |
| return cleanYamlObj(object, filterFn || defaultFilter, true, []); |
| }; |
| |
| function cleanYamlObj(object, filter, isRoot, seen) { |
| if (object === undefined) { |
| return null; |
| } |
| |
| if (typeof object === 'function') { |
| return object.toString(); |
| } |
| |
| if (Buffer.isBuffer(object)) { |
| return 'Buffer\n' + object.toString('hex').split('') |
| .reduce(function (set, c) { |
| if (set.length && set[set.length - 1].length === 1) { |
| set[set.length - 1] += c; |
| if (set.length && set.length % 20 === 0) { |
| set[set.length - 1] += '\n'; |
| } else { |
| set[set.length - 1] += ' '; |
| } |
| } else { |
| set.push(c); |
| } |
| return set; |
| }, []).join('').trim(); |
| } |
| |
| if (object && typeof object === 'object') { |
| if (object instanceof RegExp) { |
| return object.toString(); |
| } |
| |
| seen = seen.concat([object]); |
| |
| var isArray = Array.isArray(object); |
| |
| // Fill in any holes. This means we lose expandos, |
| // but we were gonna lose those anyway. |
| if (isArray) { |
| object = Array.apply(null, object); |
| } |
| |
| var isError = object && typeof object === 'object' && object instanceof Error; |
| |
| var set = isArray ? [] : {}; |
| |
| // name is typically not an ownProperty on an Error |
| if (isError && object.name && !object.hasOwnProperty('name') && filter('name', isRoot, object, set)) { |
| setProp('name', object, set, seen, filter); |
| } |
| |
| var keys = Object.getOwnPropertyNames(object); |
| return keys.reduce(function (set, k) { |
| // magic property! |
| if (isArray && k === 'length') { |
| return set; |
| } |
| |
| // Don't dump massive EventEmitter and Domain |
| // objects onto the output, that's never friendly. |
| if (isError && /^domain/.test(k)) { |
| return set; |
| } |
| |
| if (!filter(k, isRoot, object, set)) { |
| return set; |
| } |
| |
| setProp(k, object, set, seen, filter); |
| |
| return set; |
| }, set); |
| } |
| |
| return object; |
| } |
| |
| function setProp(propName, source, target, seen, filter) { |
| if (seen.indexOf(source[propName]) === -1) { |
| target[propName] = cleanYamlObj(source[propName], filter, false, seen); |
| } else { |
| target[propName] = '[Circular]'; |
| } |
| } |
| |
| function defaultFilter() { |
| return true; |
| } |