blob: e1632c3bbd0369b1ac415a5921277da8ad1f7ed9 [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001var hasMap = typeof Map === 'function' && Map.prototype;
2var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;
3var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;
4var mapForEach = hasMap && Map.prototype.forEach;
5var hasSet = typeof Set === 'function' && Set.prototype;
6var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;
7var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;
8var setForEach = hasSet && Set.prototype.forEach;
9var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;
10var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;
11var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;
12var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;
13var booleanValueOf = Boolean.prototype.valueOf;
14var objectToString = Object.prototype.toString;
15var functionToString = Function.prototype.toString;
16var match = String.prototype.match;
17var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;
18var gOPS = Object.getOwnPropertySymbols;
19var symToString = typeof Symbol === 'function' ? Symbol.prototype.toString : null;
20var isEnumerable = Object.prototype.propertyIsEnumerable;
21
22var inspectCustom = require('./util.inspect').custom;
23var inspectSymbol = inspectCustom && isSymbol(inspectCustom) ? inspectCustom : null;
24
25module.exports = function inspect_(obj, options, depth, seen) {
26 var opts = options || {};
27
28 if (has(opts, 'quoteStyle') && (opts.quoteStyle !== 'single' && opts.quoteStyle !== 'double')) {
29 throw new TypeError('option "quoteStyle" must be "single" or "double"');
30 }
31 if (
32 has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'
33 ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity
34 : opts.maxStringLength !== null
35 )
36 ) {
37 throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');
38 }
39 var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;
40 if (typeof customInspect !== 'boolean') {
41 throw new TypeError('option "customInspect", if provided, must be `true` or `false`');
42 }
43
44 if (
45 has(opts, 'indent')
46 && opts.indent !== null
47 && opts.indent !== '\t'
48 && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)
49 ) {
50 throw new TypeError('options "indent" must be "\\t", an integer > 0, or `null`');
51 }
52
53 if (typeof obj === 'undefined') {
54 return 'undefined';
55 }
56 if (obj === null) {
57 return 'null';
58 }
59 if (typeof obj === 'boolean') {
60 return obj ? 'true' : 'false';
61 }
62
63 if (typeof obj === 'string') {
64 return inspectString(obj, opts);
65 }
66 if (typeof obj === 'number') {
67 if (obj === 0) {
68 return Infinity / obj > 0 ? '0' : '-0';
69 }
70 return String(obj);
71 }
72 if (typeof obj === 'bigint') {
73 return String(obj) + 'n';
74 }
75
76 var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;
77 if (typeof depth === 'undefined') { depth = 0; }
78 if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {
79 return isArray(obj) ? '[Array]' : '[Object]';
80 }
81
82 var indent = getIndent(opts, depth);
83
84 if (typeof seen === 'undefined') {
85 seen = [];
86 } else if (indexOf(seen, obj) >= 0) {
87 return '[Circular]';
88 }
89
90 function inspect(value, from, noIndent) {
91 if (from) {
92 seen = seen.slice();
93 seen.push(from);
94 }
95 if (noIndent) {
96 var newOpts = {
97 depth: opts.depth
98 };
99 if (has(opts, 'quoteStyle')) {
100 newOpts.quoteStyle = opts.quoteStyle;
101 }
102 return inspect_(value, newOpts, depth + 1, seen);
103 }
104 return inspect_(value, opts, depth + 1, seen);
105 }
106
107 if (typeof obj === 'function') {
108 var name = nameOf(obj);
109 var keys = arrObjKeys(obj, inspect);
110 return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + keys.join(', ') + ' }' : '');
111 }
112 if (isSymbol(obj)) {
113 var symString = symToString.call(obj);
114 return typeof obj === 'object' ? markBoxed(symString) : symString;
115 }
116 if (isElement(obj)) {
117 var s = '<' + String(obj.nodeName).toLowerCase();
118 var attrs = obj.attributes || [];
119 for (var i = 0; i < attrs.length; i++) {
120 s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);
121 }
122 s += '>';
123 if (obj.childNodes && obj.childNodes.length) { s += '...'; }
124 s += '</' + String(obj.nodeName).toLowerCase() + '>';
125 return s;
126 }
127 if (isArray(obj)) {
128 if (obj.length === 0) { return '[]'; }
129 var xs = arrObjKeys(obj, inspect);
130 if (indent && !singleLineValues(xs)) {
131 return '[' + indentedJoin(xs, indent) + ']';
132 }
133 return '[ ' + xs.join(', ') + ' ]';
134 }
135 if (isError(obj)) {
136 var parts = arrObjKeys(obj, inspect);
137 if (parts.length === 0) { return '[' + String(obj) + ']'; }
138 return '{ [' + String(obj) + '] ' + parts.join(', ') + ' }';
139 }
140 if (typeof obj === 'object' && customInspect) {
141 if (inspectSymbol && typeof obj[inspectSymbol] === 'function') {
142 return obj[inspectSymbol]();
143 } else if (typeof obj.inspect === 'function') {
144 return obj.inspect();
145 }
146 }
147 if (isMap(obj)) {
148 var mapParts = [];
149 mapForEach.call(obj, function (value, key) {
150 mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));
151 });
152 return collectionOf('Map', mapSize.call(obj), mapParts, indent);
153 }
154 if (isSet(obj)) {
155 var setParts = [];
156 setForEach.call(obj, function (value) {
157 setParts.push(inspect(value, obj));
158 });
159 return collectionOf('Set', setSize.call(obj), setParts, indent);
160 }
161 if (isWeakMap(obj)) {
162 return weakCollectionOf('WeakMap');
163 }
164 if (isWeakSet(obj)) {
165 return weakCollectionOf('WeakSet');
166 }
167 if (isNumber(obj)) {
168 return markBoxed(inspect(Number(obj)));
169 }
170 if (isBigInt(obj)) {
171 return markBoxed(inspect(bigIntValueOf.call(obj)));
172 }
173 if (isBoolean(obj)) {
174 return markBoxed(booleanValueOf.call(obj));
175 }
176 if (isString(obj)) {
177 return markBoxed(inspect(String(obj)));
178 }
179 if (!isDate(obj) && !isRegExp(obj)) {
180 var ys = arrObjKeys(obj, inspect);
181 if (ys.length === 0) { return '{}'; }
182 if (indent) {
183 return '{' + indentedJoin(ys, indent) + '}';
184 }
185 return '{ ' + ys.join(', ') + ' }';
186 }
187 return String(obj);
188};
189
190function wrapQuotes(s, defaultStyle, opts) {
191 var quoteChar = (opts.quoteStyle || defaultStyle) === 'double' ? '"' : "'";
192 return quoteChar + s + quoteChar;
193}
194
195function quote(s) {
196 return String(s).replace(/"/g, '&quot;');
197}
198
199function isArray(obj) { return toStr(obj) === '[object Array]'; }
200function isDate(obj) { return toStr(obj) === '[object Date]'; }
201function isRegExp(obj) { return toStr(obj) === '[object RegExp]'; }
202function isError(obj) { return toStr(obj) === '[object Error]'; }
203function isSymbol(obj) { return toStr(obj) === '[object Symbol]'; }
204function isString(obj) { return toStr(obj) === '[object String]'; }
205function isNumber(obj) { return toStr(obj) === '[object Number]'; }
206function isBigInt(obj) { return toStr(obj) === '[object BigInt]'; }
207function isBoolean(obj) { return toStr(obj) === '[object Boolean]'; }
208
209var hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };
210function has(obj, key) {
211 return hasOwn.call(obj, key);
212}
213
214function toStr(obj) {
215 return objectToString.call(obj);
216}
217
218function nameOf(f) {
219 if (f.name) { return f.name; }
220 var m = match.call(functionToString.call(f), /^function\s*([\w$]+)/);
221 if (m) { return m[1]; }
222 return null;
223}
224
225function indexOf(xs, x) {
226 if (xs.indexOf) { return xs.indexOf(x); }
227 for (var i = 0, l = xs.length; i < l; i++) {
228 if (xs[i] === x) { return i; }
229 }
230 return -1;
231}
232
233function isMap(x) {
234 if (!mapSize || !x || typeof x !== 'object') {
235 return false;
236 }
237 try {
238 mapSize.call(x);
239 try {
240 setSize.call(x);
241 } catch (s) {
242 return true;
243 }
244 return x instanceof Map; // core-js workaround, pre-v2.5.0
245 } catch (e) {}
246 return false;
247}
248
249function isWeakMap(x) {
250 if (!weakMapHas || !x || typeof x !== 'object') {
251 return false;
252 }
253 try {
254 weakMapHas.call(x, weakMapHas);
255 try {
256 weakSetHas.call(x, weakSetHas);
257 } catch (s) {
258 return true;
259 }
260 return x instanceof WeakMap; // core-js workaround, pre-v2.5.0
261 } catch (e) {}
262 return false;
263}
264
265function isSet(x) {
266 if (!setSize || !x || typeof x !== 'object') {
267 return false;
268 }
269 try {
270 setSize.call(x);
271 try {
272 mapSize.call(x);
273 } catch (m) {
274 return true;
275 }
276 return x instanceof Set; // core-js workaround, pre-v2.5.0
277 } catch (e) {}
278 return false;
279}
280
281function isWeakSet(x) {
282 if (!weakSetHas || !x || typeof x !== 'object') {
283 return false;
284 }
285 try {
286 weakSetHas.call(x, weakSetHas);
287 try {
288 weakMapHas.call(x, weakMapHas);
289 } catch (s) {
290 return true;
291 }
292 return x instanceof WeakSet; // core-js workaround, pre-v2.5.0
293 } catch (e) {}
294 return false;
295}
296
297function isElement(x) {
298 if (!x || typeof x !== 'object') { return false; }
299 if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {
300 return true;
301 }
302 return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';
303}
304
305function inspectString(str, opts) {
306 if (str.length > opts.maxStringLength) {
307 var remaining = str.length - opts.maxStringLength;
308 var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');
309 return inspectString(str.slice(0, opts.maxStringLength), opts) + trailer;
310 }
311 // eslint-disable-next-line no-control-regex
312 var s = str.replace(/(['\\])/g, '\\$1').replace(/[\x00-\x1f]/g, lowbyte);
313 return wrapQuotes(s, 'single', opts);
314}
315
316function lowbyte(c) {
317 var n = c.charCodeAt(0);
318 var x = {
319 8: 'b',
320 9: 't',
321 10: 'n',
322 12: 'f',
323 13: 'r'
324 }[n];
325 if (x) { return '\\' + x; }
326 return '\\x' + (n < 0x10 ? '0' : '') + n.toString(16).toUpperCase();
327}
328
329function markBoxed(str) {
330 return 'Object(' + str + ')';
331}
332
333function weakCollectionOf(type) {
334 return type + ' { ? }';
335}
336
337function collectionOf(type, size, entries, indent) {
338 var joinedEntries = indent ? indentedJoin(entries, indent) : entries.join(', ');
339 return type + ' (' + size + ') {' + joinedEntries + '}';
340}
341
342function singleLineValues(xs) {
343 for (var i = 0; i < xs.length; i++) {
344 if (indexOf(xs[i], '\n') >= 0) {
345 return false;
346 }
347 }
348 return true;
349}
350
351function getIndent(opts, depth) {
352 var baseIndent;
353 if (opts.indent === '\t') {
354 baseIndent = '\t';
355 } else if (typeof opts.indent === 'number' && opts.indent > 0) {
356 baseIndent = Array(opts.indent + 1).join(' ');
357 } else {
358 return null;
359 }
360 return {
361 base: baseIndent,
362 prev: Array(depth + 1).join(baseIndent)
363 };
364}
365
366function indentedJoin(xs, indent) {
367 if (xs.length === 0) { return ''; }
368 var lineJoiner = '\n' + indent.prev + indent.base;
369 return lineJoiner + xs.join(',' + lineJoiner) + '\n' + indent.prev;
370}
371
372function arrObjKeys(obj, inspect) {
373 var isArr = isArray(obj);
374 var xs = [];
375 if (isArr) {
376 xs.length = obj.length;
377 for (var i = 0; i < obj.length; i++) {
378 xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';
379 }
380 }
381 for (var key in obj) { // eslint-disable-line no-restricted-syntax
382 if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
383 if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
384 if ((/[^\w$]/).test(key)) {
385 xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));
386 } else {
387 xs.push(key + ': ' + inspect(obj[key], obj));
388 }
389 }
390 if (typeof gOPS === 'function') {
391 var syms = gOPS(obj);
392 for (var j = 0; j < syms.length; j++) {
393 if (isEnumerable.call(obj, syms[j])) {
394 xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));
395 }
396 }
397 }
398 return xs;
399}