@@ -68,7 +68,8 @@ const inspectDefaultOptions = Object.seal({
6868customInspect : true ,
6969showProxy : false ,
7070maxArrayLength : 100 ,
71- breakLength : 60
71+ breakLength : 60 ,
72+ compact : true
7273} ) ;
7374
7475const propertyIsEnumerable = Object . prototype . propertyIsEnumerable ;
@@ -86,6 +87,10 @@ const strEscapeSequencesReplacer = /[\x00-\x1f\x27\x5c]/g;
8687const keyStrRegExp = / ^ [ a - z A - Z _ ] [ a - z A - Z _ 0 - 9 ] * $ / ;
8788const numberRegExp = / ^ ( 0 | [ 1 - 9 ] [ 0 - 9 ] * ) $ / ;
8889
90+ const readableRegExps = { } ;
91+
92+ const MIN_LINE_LENGTH = 16 ;
93+
8994// Escaped special characters. Use empty strings to fill up unused entries.
9095const meta = [
9196'\\u0000' , '\\u0001' , '\\u0002' , '\\u0003' , '\\u0004' ,
@@ -276,7 +281,8 @@ function inspect(value, opts){
276281showProxy : inspectDefaultOptions . showProxy ,
277282maxArrayLength : inspectDefaultOptions . maxArrayLength ,
278283breakLength : inspectDefaultOptions . breakLength ,
279- indentationLvl : 0
284+ indentationLvl : 0 ,
285+ compact : inspectDefaultOptions . compact
280286} ;
281287// Legacy...
282288if ( arguments . length > 2 ) {
@@ -374,7 +380,7 @@ function ensureDebugIsInitialized(){
374380function formatValue ( ctx , value , recurseTimes , ln ) {
375381// Primitive types cannot have properties
376382if ( typeof value !== 'object' && typeof value !== 'function' ) {
377- return formatPrimitive ( ctx . stylize , value ) ;
383+ return formatPrimitive ( ctx . stylize , value , ctx ) ;
378384}
379385if ( value === null ) {
380386return ctx . stylize ( 'null' , 'null' ) ;
@@ -481,10 +487,10 @@ function formatValue(ctx, value, recurseTimes, ln){
481487} catch ( e ) { /* ignore */ }
482488
483489if ( typeof raw === 'string' ) {
484- const formatted = formatPrimitive ( stylizeNoColor , raw ) ;
490+ const formatted = formatPrimitive ( stylizeNoColor , raw , ctx ) ;
485491if ( keyLength === raw . length )
486492return ctx . stylize ( `[String: ${ formatted } ]` , 'string' ) ;
487- base = ` [String: ${ formatted } ]` ;
493+ base = `[String: ${ formatted } ]` ;
488494// For boxed Strings, we have to remove the 0-n indexed entries,
489495// since they just noisy up the output and are redundant
490496// Make boxed primitive Strings look like such
@@ -505,25 +511,25 @@ function formatValue(ctx, value, recurseTimes, ln){
505511const name = `${ constructor . name } ${ value . name ? `: ${ value . name } ` : '' } ` ;
506512if ( keyLength === 0 )
507513return ctx . stylize ( `[${ name } ]` , 'special' ) ;
508- base = ` [${ name } ]` ;
514+ base = `[${ name } ]` ;
509515} else if ( isRegExp ( value ) ) {
510516// Make RegExps say that they are RegExps
511517if ( keyLength === 0 || recurseTimes < 0 )
512518return ctx . stylize ( regExpToString . call ( value ) , 'regexp' ) ;
513- base = `${ regExpToString . call ( value ) } ` ;
519+ base = `${ regExpToString . call ( value ) } ` ;
514520} else if ( isDate ( value ) ) {
515521if ( keyLength === 0 ) {
516522if ( Number . isNaN ( value . getTime ( ) ) )
517523return ctx . stylize ( value . toString ( ) , 'date' ) ;
518524return ctx . stylize ( dateToISOString . call ( value ) , 'date' ) ;
519525}
520526// Make dates with properties first say the date
521- base = `${ dateToISOString . call ( value ) } ` ;
527+ base = `${ dateToISOString . call ( value ) } ` ;
522528} else if ( isError ( value ) ) {
523529// Make error with message first say the error
524530if ( keyLength === 0 )
525531return formatError ( value ) ;
526- base = `${ formatError ( value ) } ` ;
532+ base = `${ formatError ( value ) } ` ;
527533} else if ( isAnyArrayBuffer ( value ) ) {
528534// Fast path for ArrayBuffer and SharedArrayBuffer.
529535// Can't do the same for DataView because it has a non-primitive
@@ -553,13 +559,13 @@ function formatValue(ctx, value, recurseTimes, ln){
553559const formatted = formatPrimitive ( stylizeNoColor , raw ) ;
554560if ( keyLength === 0 )
555561return ctx . stylize ( `[Number: ${ formatted } ]` , 'number' ) ;
556- base = ` [Number: ${ formatted } ]` ;
562+ base = `[Number: ${ formatted } ]` ;
557563} else if ( typeof raw === 'boolean' ) {
558564// Make boxed primitive Booleans look like such
559565const formatted = formatPrimitive ( stylizeNoColor , raw ) ;
560566if ( keyLength === 0 )
561567return ctx . stylize ( `[Boolean: ${ formatted } ]` , 'boolean' ) ;
562- base = ` [Boolean: ${ formatted } ]` ;
568+ base = `[Boolean: ${ formatted } ]` ;
563569} else if ( typeof raw === 'symbol' ) {
564570const formatted = formatPrimitive ( stylizeNoColor , raw ) ;
565571return ctx . stylize ( `[Symbol: ${ formatted } ]` , 'symbol' ) ;
@@ -603,9 +609,42 @@ function formatNumber(fn, value){
603609return fn ( `${ value } ` , 'number' ) ;
604610}
605611
606- function formatPrimitive ( fn , value ) {
607- if ( typeof value === 'string' )
612+ function formatPrimitive ( fn , value , ctx ) {
613+ if ( typeof value === 'string' ) {
614+ if ( ctx . compact === false &&
615+ value . length > MIN_LINE_LENGTH &&
616+ ctx . indentationLvl + value . length > ctx . breakLength ) {
617+ // eslint-disable-next-line max-len
618+ const minLineLength = Math . max ( ctx . breakLength - ctx . indentationLvl , MIN_LINE_LENGTH ) ;
619+ // eslint-disable-next-line max-len
620+ const averageLineLength = Math . ceil ( value . length / Math . ceil ( value . length / minLineLength ) ) ;
621+ const divisor = Math . max ( averageLineLength , MIN_LINE_LENGTH ) ;
622+ var res = '' ;
623+ if ( readableRegExps [ divisor ] === undefined ) {
624+ // Build a new RegExp that naturally breaks text into multiple lines.
625+ //
626+ // Rules
627+ // 1. Greedy match all text up the max line length that ends with a
628+ // whitespace or the end of the string.
629+ // 2. If none matches, non-greedy match any text up to a whitespace or
630+ // the end of the string.
631+ //
632+ // eslint-disable-next-line max-len, no-unescaped-regexp-dot
633+ readableRegExps [ divisor ] = new RegExp ( `(.|\\n){1,${ divisor } }(\\s|$)|(\\n|.)+?(\\s|$)` , 'gm' ) ;
634+ }
635+ const indent = ' ' . repeat ( ctx . indentationLvl ) ;
636+ const matches = value . match ( readableRegExps [ divisor ] ) ;
637+ if ( matches . length > 1 ) {
638+ res += `${ fn ( strEscape ( matches [ 0 ] ) , 'string' ) } +\n` ;
639+ for ( var i = 1 ; i < matches . length - 1 ; i ++ ) {
640+ res += `${ indent } ${ fn ( strEscape ( matches [ i ] ) , 'string' ) } +\n` ;
641+ }
642+ res += `${ indent } ${ fn ( strEscape ( matches [ i ] ) , 'string' ) } ` ;
643+ return res ;
644+ }
645+ }
608646return fn ( strEscape ( value ) , 'string' ) ;
647+ }
609648if ( typeof value === 'number' )
610649return formatNumber ( fn , value ) ;
611650if ( typeof value === 'boolean' )
@@ -806,7 +845,7 @@ function formatProperty(ctx, value, recurseTimes, key, array){
806845const desc = Object . getOwnPropertyDescriptor ( value , key ) ||
807846{ value : value [ key ] , enumerable : true } ;
808847if ( desc . value !== undefined ) {
809- const diff = array === 0 ? 3 : 2 ;
848+ const diff = array !== 0 || ctx . compact === false ? 2 : 3 ;
810849ctx . indentationLvl += diff ;
811850str = formatValue ( ctx , desc . value , recurseTimes , array === 0 ) ;
812851ctx . indentationLvl -= diff ;
@@ -839,25 +878,36 @@ function formatProperty(ctx, value, recurseTimes, key, array){
839878
840879function reduceToSingleString ( ctx , output , base , braces , addLn ) {
841880const breakLength = ctx . breakLength ;
881+ var i = 0 ;
882+ if ( ctx . compact === false ) {
883+ const indentation = ' ' . repeat ( ctx . indentationLvl ) ;
884+ var res = `${ base ? `${ base } ` : '' } ${ braces [ 0 ] } \n${ indentation } ` ;
885+ for ( ; i < output . length - 1 ; i ++ ) {
886+ res += `${ output [ i ] } ,\n${ indentation } ` ;
887+ }
888+ res += `${ output [ i ] } \n${ indentation } ${ braces [ 1 ] } ` ;
889+ return res ;
890+ }
842891if ( output . length * 2 <= breakLength ) {
843892var length = 0 ;
844- for ( var i = 0 ; i < output . length && length <= breakLength ; i ++ ) {
893+ for ( ; i < output . length && length <= breakLength ; i ++ ) {
845894if ( ctx . colors ) {
846895length += removeColors ( output [ i ] ) . length + 1 ;
847896} else {
848897length += output [ i ] . length + 1 ;
849898}
850899}
851900if ( length <= breakLength )
852- return `${ braces [ 0 ] } ${ base } ${ join ( output , ', ' ) } ${ braces [ 1 ] } ` ;
901+ return `${ braces [ 0 ] } ${ base ? ` ${ base } ` : '' } ${ join ( output , ', ' ) } ` +
902+ braces [ 1 ] ;
853903}
854904// If the opening "brace" is too large, like in the case of "Set{",
855905// we need to force the first item to be on the next line or the
856906// items will not line up correctly.
857907const indentation = ' ' . repeat ( ctx . indentationLvl ) ;
858908const extraLn = addLn === true ? `\n${ indentation } ` : '' ;
859909const ln = base === '' && braces [ 0 ] . length === 1 ?
860- ' ' : `${ base } \n${ indentation } ` ;
910+ ' ' : `${ base ? ` ${ base } ` : base } \n${ indentation } ` ;
861911const str = join ( output , `,\n${ indentation } ` ) ;
862912return `${ extraLn } ${ braces [ 0 ] } ${ ln } ${ str } ${ braces [ 1 ] } ` ;
863913}
0 commit comments