2
2
// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
3
3
4
4
var getName = require ( 'get-func-name' ) ;
5
- var getProperties = require ( './getProperties' ) ;
6
- var getEnumerableProperties = require ( './getEnumerableProperties' ) ;
5
+ var loupe = require ( 'loupe' ) ;
7
6
var config = require ( '../config' ) ;
8
7
9
8
module . exports = inspect ;
@@ -24,356 +23,11 @@ module.exports = inspect;
24
23
* @name inspect
25
24
*/
26
25
function inspect ( obj , showHidden , depth , colors ) {
27
- var ctx = {
26
+ var options = {
27
+ colors : colors ,
28
+ depth : ( typeof depth === 'undefined' ? 2 : depth ) ,
28
29
showHidden : showHidden ,
29
- seen : [ ] ,
30
- stylize : function ( str ) { return str ; }
30
+ truncate : config . truncateThreshold ? config . truncateThreshold : Infinity ,
31
31
} ;
32
- return formatValue ( ctx , obj , ( typeof depth === 'undefined' ? 2 : depth ) ) ;
33
- }
34
-
35
- // Returns true if object is a DOM element.
36
- var isDOMElement = function ( object ) {
37
- if ( typeof HTMLElement === 'object' ) {
38
- return object instanceof HTMLElement ;
39
- } else {
40
- return object &&
41
- typeof object === 'object' &&
42
- 'nodeType' in object &&
43
- object . nodeType === 1 &&
44
- typeof object . nodeName === 'string' ;
45
- }
46
- } ;
47
-
48
- function formatValue ( ctx , value , recurseTimes ) {
49
- // Provide a hook for user-specified inspect functions.
50
- // Check that value is an object with an inspect function on it
51
- if ( value && typeof value . inspect === 'function' &&
52
- // Filter out the util module, it's inspect function is special
53
- value . inspect !== exports . inspect &&
54
- // Also filter out any prototype objects using the circular check.
55
- ! ( value . constructor && value . constructor . prototype === value ) ) {
56
- var ret = value . inspect ( recurseTimes , ctx ) ;
57
- if ( typeof ret !== 'string' ) {
58
- ret = formatValue ( ctx , ret , recurseTimes ) ;
59
- }
60
- return ret ;
61
- }
62
-
63
- // Primitive types cannot have properties
64
- var primitive = formatPrimitive ( ctx , value ) ;
65
- if ( primitive ) {
66
- return primitive ;
67
- }
68
-
69
- // If this is a DOM element, try to get the outer HTML.
70
- if ( isDOMElement ( value ) ) {
71
- if ( 'outerHTML' in value ) {
72
- return value . outerHTML ;
73
- // This value does not have an outerHTML attribute,
74
- // it could still be an XML element
75
- } else {
76
- // Attempt to serialize it
77
- try {
78
- if ( document . xmlVersion ) {
79
- var xmlSerializer = new XMLSerializer ( ) ;
80
- return xmlSerializer . serializeToString ( value ) ;
81
- } else {
82
- // Firefox 11- do not support outerHTML
83
- // It does, however, support innerHTML
84
- // Use the following to render the element
85
- var ns = "http://www.w3.org/1999/xhtml" ;
86
- var container = document . createElementNS ( ns , '_' ) ;
87
-
88
- container . appendChild ( value . cloneNode ( false ) ) ;
89
- var html = container . innerHTML
90
- . replace ( '><' , '>' + value . innerHTML + '<' ) ;
91
- container . innerHTML = '' ;
92
- return html ;
93
- }
94
- } catch ( err ) {
95
- // This could be a non-native DOM implementation,
96
- // continue with the normal flow:
97
- // printing the element as if it is an object.
98
- }
99
- }
100
- }
101
-
102
- // Look up the keys of the object.
103
- var visibleKeys = getEnumerableProperties ( value ) ;
104
- var keys = ctx . showHidden ? getProperties ( value ) : visibleKeys ;
105
-
106
- var name , nameSuffix ;
107
-
108
- // Some type of object without properties can be shortcut.
109
- // In IE, errors have a single `stack` property, or if they are vanilla `Error`,
110
- // a `stack` plus `description` property; ignore those for consistency.
111
- if ( keys . length === 0 || ( isError ( value ) && (
112
- ( keys . length === 1 && keys [ 0 ] === 'stack' ) ||
113
- ( keys . length === 2 && keys [ 0 ] === 'description' && keys [ 1 ] === 'stack' )
114
- ) ) ) {
115
- if ( typeof value === 'function' ) {
116
- name = getName ( value ) ;
117
- nameSuffix = name ? ': ' + name : '' ;
118
- return ctx . stylize ( '[Function' + nameSuffix + ']' , 'special' ) ;
119
- }
120
- if ( isRegExp ( value ) ) {
121
- return ctx . stylize ( RegExp . prototype . toString . call ( value ) , 'regexp' ) ;
122
- }
123
- if ( isDate ( value ) ) {
124
- return ctx . stylize ( Date . prototype . toUTCString . call ( value ) , 'date' ) ;
125
- }
126
- if ( isError ( value ) ) {
127
- return formatError ( value ) ;
128
- }
129
- }
130
-
131
- var base = ''
132
- , array = false
133
- , typedArray = false
134
- , braces = [ '{' , '}' ] ;
135
-
136
- if ( isTypedArray ( value ) ) {
137
- typedArray = true ;
138
- braces = [ '[' , ']' ] ;
139
- }
140
-
141
- // Make Array say that they are Array
142
- if ( isArray ( value ) ) {
143
- array = true ;
144
- braces = [ '[' , ']' ] ;
145
- }
146
-
147
- // Make functions say that they are functions
148
- if ( typeof value === 'function' ) {
149
- name = getName ( value ) ;
150
- nameSuffix = name ? ': ' + name : '' ;
151
- base = ' [Function' + nameSuffix + ']' ;
152
- }
153
-
154
- // Make RegExps say that they are RegExps
155
- if ( isRegExp ( value ) ) {
156
- base = ' ' + RegExp . prototype . toString . call ( value ) ;
157
- }
158
-
159
- // Make dates with properties first say the date
160
- if ( isDate ( value ) ) {
161
- base = ' ' + Date . prototype . toUTCString . call ( value ) ;
162
- }
163
-
164
- // Make error with message first say the error
165
- if ( isError ( value ) ) {
166
- return formatError ( value ) ;
167
- }
168
-
169
- if ( keys . length === 0 && ( ! array || value . length == 0 ) ) {
170
- return braces [ 0 ] + base + braces [ 1 ] ;
171
- }
172
-
173
- if ( recurseTimes < 0 ) {
174
- if ( isRegExp ( value ) ) {
175
- return ctx . stylize ( RegExp . prototype . toString . call ( value ) , 'regexp' ) ;
176
- } else {
177
- return ctx . stylize ( '[Object]' , 'special' ) ;
178
- }
179
- }
180
-
181
- ctx . seen . push ( value ) ;
182
-
183
- var output ;
184
- if ( array ) {
185
- output = formatArray ( ctx , value , recurseTimes , visibleKeys , keys ) ;
186
- } else if ( typedArray ) {
187
- return formatTypedArray ( value ) ;
188
- } else {
189
- output = keys . map ( function ( key ) {
190
- return formatProperty ( ctx , value , recurseTimes , visibleKeys , key , array ) ;
191
- } ) ;
192
- }
193
-
194
- ctx . seen . pop ( ) ;
195
-
196
- return reduceToSingleString ( output , base , braces ) ;
197
- }
198
-
199
- function formatPrimitive ( ctx , value ) {
200
- switch ( typeof value ) {
201
- case 'undefined' :
202
- return ctx . stylize ( 'undefined' , 'undefined' ) ;
203
-
204
- case 'string' :
205
- var simple = '\'' + JSON . stringify ( value ) . replace ( / ^ " | " $ / g, '' )
206
- . replace ( / ' / g, "\\'" )
207
- . replace ( / \\ " / g, '"' ) + '\'' ;
208
- return ctx . stylize ( simple , 'string' ) ;
209
-
210
- case 'number' :
211
- if ( value === 0 && ( 1 / value ) === - Infinity ) {
212
- return ctx . stylize ( '-0' , 'number' ) ;
213
- }
214
- return ctx . stylize ( '' + value , 'number' ) ;
215
-
216
- case 'boolean' :
217
- return ctx . stylize ( '' + value , 'boolean' ) ;
218
-
219
- case 'symbol' :
220
- return ctx . stylize ( value . toString ( ) , 'symbol' ) ;
221
-
222
- case 'bigint' :
223
- return ctx . stylize ( value . toString ( ) + 'n' , 'bigint' ) ;
224
- }
225
- // For some reason typeof null is "object", so special case here.
226
- if ( value === null ) {
227
- return ctx . stylize ( 'null' , 'null' ) ;
228
- }
229
- }
230
-
231
- function formatError ( value ) {
232
- return '[' + Error . prototype . toString . call ( value ) + ']' ;
233
- }
234
-
235
- function formatArray ( ctx , value , recurseTimes , visibleKeys , keys ) {
236
- var output = [ ] ;
237
- for ( var i = 0 , l = value . length ; i < l ; ++ i ) {
238
- if ( Object . prototype . hasOwnProperty . call ( value , String ( i ) ) ) {
239
- output . push ( formatProperty ( ctx , value , recurseTimes , visibleKeys ,
240
- String ( i ) , true ) ) ;
241
- } else {
242
- output . push ( '' ) ;
243
- }
244
- }
245
-
246
- keys . forEach ( function ( key ) {
247
- if ( ! key . match ( / ^ \d + $ / ) ) {
248
- output . push ( formatProperty ( ctx , value , recurseTimes , visibleKeys ,
249
- key , true ) ) ;
250
- }
251
- } ) ;
252
- return output ;
253
- }
254
-
255
- function formatTypedArray ( value ) {
256
- var str = '[ ' ;
257
-
258
- for ( var i = 0 ; i < value . length ; ++ i ) {
259
- if ( str . length >= config . truncateThreshold - 7 ) {
260
- str += '...' ;
261
- break ;
262
- }
263
- str += value [ i ] + ', ' ;
264
- }
265
- str += ' ]' ;
266
-
267
- // Removing trailing `, ` if the array was not truncated
268
- if ( str . indexOf ( ', ]' ) !== - 1 ) {
269
- str = str . replace ( ', ]' , ' ]' ) ;
270
- }
271
-
272
- return str ;
273
- }
274
-
275
- function formatProperty ( ctx , value , recurseTimes , visibleKeys , key , array ) {
276
- var name ;
277
- var propDescriptor = Object . getOwnPropertyDescriptor ( value , key ) ;
278
- var str ;
279
-
280
- if ( propDescriptor ) {
281
- if ( propDescriptor . get ) {
282
- if ( propDescriptor . set ) {
283
- str = ctx . stylize ( '[Getter/Setter]' , 'special' ) ;
284
- } else {
285
- str = ctx . stylize ( '[Getter]' , 'special' ) ;
286
- }
287
- } else {
288
- if ( propDescriptor . set ) {
289
- str = ctx . stylize ( '[Setter]' , 'special' ) ;
290
- }
291
- }
292
- }
293
- if ( visibleKeys . indexOf ( key ) < 0 ) {
294
- name = '[' + key + ']' ;
295
- }
296
- if ( ! str ) {
297
- if ( ctx . seen . indexOf ( value [ key ] ) < 0 ) {
298
- if ( recurseTimes === null ) {
299
- str = formatValue ( ctx , value [ key ] , null ) ;
300
- } else {
301
- str = formatValue ( ctx , value [ key ] , recurseTimes - 1 ) ;
302
- }
303
- if ( str . indexOf ( '\n' ) > - 1 ) {
304
- if ( array ) {
305
- str = str . split ( '\n' ) . map ( function ( line ) {
306
- return ' ' + line ;
307
- } ) . join ( '\n' ) . substr ( 2 ) ;
308
- } else {
309
- str = '\n' + str . split ( '\n' ) . map ( function ( line ) {
310
- return ' ' + line ;
311
- } ) . join ( '\n' ) ;
312
- }
313
- }
314
- } else {
315
- str = ctx . stylize ( '[Circular]' , 'special' ) ;
316
- }
317
- }
318
- if ( typeof name === 'undefined' ) {
319
- if ( array && key . match ( / ^ \d + $ / ) ) {
320
- return str ;
321
- }
322
- name = JSON . stringify ( '' + key ) ;
323
- if ( name . match ( / ^ " ( [ a - z A - Z _ ] [ a - z A - Z _ 0 - 9 ] * ) " $ / ) ) {
324
- name = name . substr ( 1 , name . length - 2 ) ;
325
- name = ctx . stylize ( name , 'name' ) ;
326
- } else {
327
- name = name . replace ( / ' / g, "\\'" )
328
- . replace ( / \\ " / g, '"' )
329
- . replace ( / ( ^ " | " $ ) / g, "'" ) ;
330
- name = ctx . stylize ( name , 'string' ) ;
331
- }
332
- }
333
-
334
- return name + ': ' + str ;
335
- }
336
-
337
- function reduceToSingleString ( output , base , braces ) {
338
- var length = output . reduce ( function ( prev , cur ) {
339
- return prev + cur . length + 1 ;
340
- } , 0 ) ;
341
-
342
- if ( length > 60 ) {
343
- return braces [ 0 ] +
344
- ( base === '' ? '' : base + '\n ' ) +
345
- ' ' +
346
- output . join ( ',\n ' ) +
347
- ' ' +
348
- braces [ 1 ] ;
349
- }
350
-
351
- return braces [ 0 ] + base + ' ' + output . join ( ', ' ) + ' ' + braces [ 1 ] ;
352
- }
353
-
354
- function isTypedArray ( ar ) {
355
- // Unfortunately there's no way to check if an object is a TypedArray
356
- // We have to check if it's one of these types
357
- return ( typeof ar === 'object' && / \w + A r r a y ] $ / . test ( objectToString ( ar ) ) ) ;
358
- }
359
-
360
- function isArray ( ar ) {
361
- return Array . isArray ( ar ) ||
362
- ( typeof ar === 'object' && objectToString ( ar ) === '[object Array]' ) ;
363
- }
364
-
365
- function isRegExp ( re ) {
366
- return typeof re === 'object' && objectToString ( re ) === '[object RegExp]' ;
367
- }
368
-
369
- function isDate ( d ) {
370
- return typeof d === 'object' && objectToString ( d ) === '[object Date]' ;
371
- }
372
-
373
- function isError ( e ) {
374
- return typeof e === 'object' && objectToString ( e ) === '[object Error]' ;
375
- }
376
-
377
- function objectToString ( o ) {
378
- return Object . prototype . toString . call ( o ) ;
32
+ return loupe . inspect ( obj , options ) ;
379
33
}
0 commit comments