Scribe.js/dist/libs/inspect.js
2016-02-13 16:02:44 -06:00

494 lines
13 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
var _getOwnPropertyDescriptor = require('babel-runtime/core-js/object/get-own-property-descriptor');
var _getOwnPropertyDescriptor2 = _interopRequireDefault(_getOwnPropertyDescriptor);
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _stringify = require('babel-runtime/core-js/json/stringify');
var _stringify2 = _interopRequireDefault(_stringify);
var _getOwnPropertyNames = require('babel-runtime/core-js/object/get-own-property-names');
var _getOwnPropertyNames2 = _interopRequireDefault(_getOwnPropertyNames);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _weakMap = require('babel-runtime/core-js/weak-map');
var _weakMap2 = _interopRequireDefault(_weakMap);
var _set = require('babel-runtime/core-js/set');
var _set2 = _interopRequireDefault(_set);
var _map = require('babel-runtime/core-js/map');
var _map2 = _interopRequireDefault(_map);
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _typeof2 = require('babel-runtime/helpers/typeof');
var _typeof3 = _interopRequireDefault(_typeof2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Module dependencies.
*/
var fe = require('format-error').format;
var strip = require('strip-ansi');
function formatError(ctx, value) {
return fe(value).split('\n').map(function (m) {
m = strip(m);
if (m.indexOf('Error: ') > -1) {
return ctx.stylize(m, 'error');
}
return ctx.stylize(m, 'stack');
}).join('\n');
}
/**
* Module exports.
*/
module.exports = inspect;
/**
* Echos the value of a value. Trys to print the value out
* in the best way possible given the different types.
*
* @param {Object} obj The object to print out.
* @param {Object} opts Optional options object that alters the output.
* @license MIT (© Joyent)
*/
/* legacy: obj, showHidden, depth, colors*/
function inspect(obj, opts) {
// default options
var ctx = {
seen: [],
stylize: stylizeNoColor
};
// legacy...
if (arguments.length >= 3) ctx.depth = arguments[2];
if (arguments.length >= 4) ctx.colors = arguments[3];
if (isBoolean(opts)) {
// legacy...
ctx.showHidden = opts;
} else if (opts) {
// got an "options" object
_extend(ctx, opts);
}
// set default options
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
if (isUndefined(ctx.depth)) ctx.depth = 2;
if (isUndefined(ctx.colors)) ctx.colors = false;
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
if (ctx.colors) ctx.stylize = stylizeWithColor;
return formatValue(ctx, obj, ctx.depth);
}
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
'bold': [1, 22],
'italic': [3, 23],
'underline': [4, 24],
'inverse': [7, 27],
'white': [37, 39],
'grey': [90, 39],
'black': [30, 39],
'blue': [34, 39],
'cyan': [36, 39],
'green': [32, 39],
'magenta': [35, 39],
'red': [31, 39],
'yellow': [33, 39]
};
// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
'special': 'cyan',
'number': 'yellow',
'boolean': 'yellow',
'undefined': 'grey',
'null': 'bold',
'string': 'green',
'date': 'magenta',
'error': ['bold', 'red'],
'stack': 'red',
// 'name': 'cyan',
'regexp': 'red',
'promise': 'green',
'map': 'cyan',
'set': 'cyan',
'weakmap': 'cyan',
'weakset': 'cyan'
};
function stylizeNoColor(str, styleType) {
return str;
}
function isBoolean(arg) {
return typeof arg === 'boolean';
}
function isUndefined(arg) {
return arg === void 0;
}
function stylizeWithColor(str, styleType) {
var style = inspect.styles[styleType];
if (Array.isArray(style)) {
for (var i = 0; i < style.length; i++) {
str = '\u001b[' + inspect.colors[style[i]][0] + 'm' + str + '\u001b[' + inspect.colors[style[i]][1] + 'm';
}
return str;
} else if (style) {
return '\u001b[' + inspect.colors[style][0] + 'm' + str + '\u001b[' + inspect.colors[style][1] + 'm';
} else {
return str;
}
}
function isFunction(arg) {
return typeof arg === 'function';
}
function isString(arg) {
return typeof arg === 'string';
}
function isNumber(arg) {
return typeof arg === 'number';
}
function isNull(arg) {
return arg === null;
}
function hasOwn(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
function isRegExp(re) {
return isObject(re) && objectToString(re) === '[object RegExp]';
}
function isObject(arg) {
return (typeof arg === 'undefined' ? 'undefined' : (0, _typeof3.default)(arg)) === 'object' && arg !== null;
}
function isError(e) {
return isObject(e) && (objectToString(e) === '[object Error]' || e instanceof Error);
}
function isDate(d) {
return isObject(d) && objectToString(d) === '[object Date]';
}
function objectToString(o) {
return Object.prototype.toString.call(o);
}
function isPromise(p) {
return p instanceof _promise2.default;
}
function isMap(m) {
return m instanceof _map2.default;
}
function isSet(m) {
return m instanceof _set2.default;
}
function isWeakMap(m) {
return m instanceof _weakMap2.default;
}
function isWeakSet(m) {
return m instanceof isWeakSet;
}
function arrayToHash(array) {
var hash = {};
array.forEach(function (val, idx) {
hash[val] = true;
});
return hash;
}
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
var output = [];
for (var i = 0, l = value.length; i < l; ++i) {
if (hasOwn(value, String(i))) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true));
} else {
output.push('');
}
}
keys.forEach(function (key) {
if (!key.match(/^\d+$/)) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key, true));
}
});
return output;
}
function formatValue(ctx, value, recurseTimes) {
// Provide a hook for user-specified inspect functions.
// Check that value is an object with an inspect function on it
if (ctx.customInspect && value && isFunction(value.inspect) &&
// Filter out the util module, it's inspect function is special
value.inspect !== inspect &&
// Also filter out any prototype objects using the circular check.
!(value.constructor && value.constructor.prototype === value)) {
var ret = value.inspect(recurseTimes, ctx);
if (!isString(ret)) {
ret = formatValue(ctx, ret, recurseTimes);
}
return ret;
}
// Primitive types cannot have properties
var primitive = formatPrimitive(ctx, value);
if (primitive) {
return primitive;
}
// Look up the keys of the object.
var keys = (0, _keys2.default)(value);
var visibleKeys = arrayToHash(keys);
try {
if (ctx.showHidden && _getOwnPropertyNames2.default) {
keys = (0, _getOwnPropertyNames2.default)(value);
}
} catch (e) {}
// ignore
// IE doesn't make error fields non-enumerable
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
if (isError(value) && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
return formatError(ctx, value);
}
// Some type of object without properties can be shortcutted.
if (keys.length === 0) {
if (isPromise(value)) {
return ctx.stylize('[Promise]', 'promise');
}
if (isWeakSet(value)) {
return ctx.stylize('[WeakSet] ', 'weakset') + inspect(JSON.parse((0, _stringify2.default)([].concat((0, _toConsumableArray3.default)(value)))), ctx);
}
if (isWeakMap(value)) {
return ctx.stylize('[WeakMap] ', 'weakmap') + inspect(JSON.parse((0, _stringify2.default)([].concat((0, _toConsumableArray3.default)(value)))), ctx);
}
if (isMap(value)) {
return ctx.stylize('[Map] ', 'map') + inspect(JSON.parse((0, _stringify2.default)([].concat((0, _toConsumableArray3.default)(value)))), ctx);
}
if (isSet(value)) {
return ctx.stylize('[Set] ', 'set') + inspect(JSON.parse((0, _stringify2.default)([].concat((0, _toConsumableArray3.default)(value)))), ctx);
}
if (isFunction(value)) {
var name = value.name ? ': ' + value.name : '';
return ctx.stylize('[Function' + name + ']', 'special');
}
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
}
if (isDate(value)) {
return ctx.stylize(Date.prototype.toString.call(value), 'date');
}
if (isError(value)) {
return formatError(ctx, value);
}
}
var base = '',
array = false,
braces = ['{', '}'];
// Make Array say that they are Array
if (Array.isArray(value)) {
array = true;
braces = ['[', ']'];
}
// Make functions say that they are functions
if (isFunction(value)) {
var n = value.name ? ': ' + value.name : '';
base = ' [Function' + n + ']';
}
// Make RegExps say that they are RegExps
if (isRegExp(value)) {
base = ' ' + RegExp.prototype.toString.call(value);
}
// Make dates with properties first say the date
if (isDate(value)) {
base = ' ' + Date.prototype.toUTCString.call(value);
}
// Make error with message first say the error
if (isError(value)) {
base = ' ' + formatError(ctx, value);
}
if (keys.length === 0 && (!array || value.length == 0)) {
return braces[0] + base + braces[1];
}
if (recurseTimes < 0) {
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
} else {
return ctx.stylize('[Object]', 'special');
}
}
ctx.seen.push(value);
var output;
if (array) {
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
} else {
output = keys.map(function (key) {
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
});
}
ctx.seen.pop();
return reduceToSingleString(output, base, braces);
}
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
var name, str, desc;
desc = { value: void 0 };
try {
// ie6 navigator.toString
// throws Error: Object doesn't support this property or method
desc.value = value[key];
} catch (e) {
// ignore
}
try {
// ie10 Object.getOwnPropertyDescriptor(window.location, 'hash')
// throws TypeError: Object doesn't support this action
if (_getOwnPropertyDescriptor2.default) {
desc = (0, _getOwnPropertyDescriptor2.default)(value, key) || desc;
}
} catch (e) {
// ignore
}
if (desc.get) {
if (desc.set) {
str = ctx.stylize('[Getter/Setter]', 'special');
} else {
str = ctx.stylize('[Getter]', 'special');
}
} else {
if (desc.set) {
str = ctx.stylize('[Setter]', 'special');
}
}
if (!hasOwn(visibleKeys, key)) {
name = '[' + key + ']';
}
if (!str) {
if (ctx.seen.indexOf(desc.value) < 0) {
if (isNull(recurseTimes)) {
str = formatValue(ctx, desc.value, null);
} else {
str = formatValue(ctx, desc.value, recurseTimes - 1);
}
if (str.indexOf('\n') > -1) {
if (array) {
str = str.split('\n').map(function (line) {
return ' ' + line;
}).join('\n').substr(2);
} else {
str = '\n' + str.split('\n').map(function (line) {
return ' ' + line;
}).join('\n');
}
}
} else {
str = ctx.stylize('[Circular]', 'special');
}
}
if (isUndefined(name)) {
if (array && key.match(/^\d+$/)) {
return str;
}
name = (0, _stringify2.default)('' + key);
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
name = name.substr(1, name.length - 2);
name = ctx.stylize(name, 'name');
} else {
name = name.replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'");
name = ctx.stylize(name, 'string');
}
}
return name + ': ' + str;
}
function formatPrimitive(ctx, value) {
if (isUndefined(value)) return ctx.stylize('undefined', 'undefined');
if (isString(value)) {
var simple = '\'' + (0, _stringify2.default)(value).replace(/^"|"$/g, '').replace(/'/g, "\\'").replace(/\\"/g, '"') + '\'';
return ctx.stylize(simple, 'string');
}
if (isNumber(value)) return ctx.stylize('' + value, 'number');
if (isBoolean(value)) return ctx.stylize('' + value, 'boolean');
// For some reason typeof null is "object", so special case here.
if (isNull(value)) return ctx.stylize('null', 'null');
}
function reduceToSingleString(output, base, braces) {
var numLinesEst = 0;
var length = output.reduce(function (prev, cur) {
numLinesEst++;
if (cur.indexOf('\n') >= 0) numLinesEst++;
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
}, 0);
if (length > 60) {
return braces[0] + (base === '' ? '' : base + '\n ') + ' ' + output.join(',\n ') + ' ' + braces[1];
}
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}
function _extend(origin, add) {
// Don't do anything if add isn't an object
if (!add || !isObject(add)) return origin;
var keys = (0, _keys2.default)(add);
var i = keys.length;
while (i--) {
origin[keys[i]] = add[keys[i]];
}
return origin;
}