import defaults = require('lodash/defaults'); import identity = require('lodash/identity'); import {inspect} from 'util'; function truncateString(s: string|Uint8Array, maxLen: number, optStringMapper?: (arg: any) => string): string { const m: (arg: any) => string = optStringMapper || identity; return s.length <= maxLen ? m(s) : m(s.slice(0, maxLen)) + "... (" + s.length + " length)"; } function formatUint8Array(array: Uint8Array): string { const s = Buffer.from(array).toString('binary'); // eslint-disable-next-line no-control-regex return s.replace(/[\x00-\x1f\x7f-\xff]/g, '?'); } interface DescLimits { maxArrayLength: number; maxObjectKeys: number; maxStringLength: number; maxBufferLength: number; } const defaultLimits: DescLimits = { maxArrayLength: 5, maxObjectKeys: 10, maxStringLength: 80, maxBufferLength: 80, }; /** * Produce a human-readable concise description of the object as a string. Similar to * util.inspect(), but more concise and more readable. * @param {Object} optLimits: Optional limits on how much of a value to include. Supports * maxArrayLength, maxObjectKeys, maxStringLength, maxBufferLength. */ export function shortDesc(topObj: any, optLimits?: DescLimits): string { const lim = defaults(optLimits || {}, defaultLimits); function _shortDesc(obj: any): string { if (Array.isArray(obj)) { return "[" + obj.slice(0, lim.maxArrayLength).map(_shortDesc).join(", ") + (obj.length > lim.maxArrayLength ? ", ... (" + obj.length + " items)" : "") + "]"; } else if (obj instanceof Uint8Array) { return "b'" + truncateString(obj, lim.maxBufferLength, formatUint8Array) + "'"; } else if (obj && typeof obj === 'object' && !Buffer.isBuffer(obj)) { const keys = Object.keys(obj); return "{" + keys.slice(0, lim.maxObjectKeys).map(function(key) { return key + ": " + _shortDesc(obj[key]); }).join(", ") + (keys.length > lim.maxObjectKeys ? ", ... (" + keys.length + " keys)" : "") + "}"; } else if (typeof obj === 'string') { return inspect(truncateString(obj, lim.maxStringLength)); } else { return inspect(obj); } } return _shortDesc(topObj); }