@@ -5,7 +5,30 @@ class JSONFormatter {
55 * @returns A string containing the formatted HTML.
66 */
77 public static format ( json : any ) : string {
8- return this . formatJSON ( json , 0 ) ;
8+ return `
9+ <div class="json-formatter" style="
10+ max-width: 100%;
11+ overflow-wrap: break-word;
12+ word-wrap: break-word;
13+ word-break: break-word;
14+ ">
15+ ${ this . formatJSON ( json , 0 ) }
16+ </div>
17+ ` ;
18+ }
19+
20+ /**
21+ * Transforms camelCase, snake_case, and PascalCase text to space-separated words
22+ * @param text - The text to transform
23+ * @returns The transformed text
24+ */
25+ private static transformKey ( text : string ) : string {
26+ return text
27+ . replace ( / ( [ A - Z ] ) / g, ' $1' )
28+ . replace ( / _ / g, ' ' )
29+ . trim ( )
30+ . toLowerCase ( )
31+ . replace ( / ^ \w / , ( c ) => c . toUpperCase ( ) ) ;
932 }
1033
1134 /**
@@ -31,20 +54,42 @@ class JSONFormatter {
3154 * @returns A string containing the formatted HTML.
3255 */
3356 private static formatArray ( array : any [ ] , indentLevel : number ) : string {
34- let html = '' ;
57+ if ( array . length === 0 ) {
58+ return '<div style="color: #666;">(empty array)</div>' ;
59+ }
60+
61+ let html = '<div class="json-array" style="width: 100%;">' ;
3562 array . forEach ( ( item , index ) => {
3663 if ( typeof item === 'object' && item !== null ) {
37- // Add a styled section for arrays of objects
38- html += `<div style="margin: 10px 0; padding: 10px; border: 1px solid #ddd; border-radius: 5px; background: #f9f9f9;">
39- ${ this . formatJSON ( item , indentLevel + 1 ) }
40- </div>` ;
64+ html += `
65+ <div class="json-object-container" style="
66+ margin: 12px 0;
67+ padding: 16px;
68+ border: 1px solid #ddd;
69+ border-radius: 8px;
70+ background: #f9f9f9;
71+ overflow-wrap: break-word;
72+ word-wrap: break-word;
73+ word-break: break-word;
74+ ">
75+ ${ this . formatJSON ( item , indentLevel + 1 ) }
76+ </div>
77+ ` ;
4178 } else {
42- // Regular array items (non-objects)
43- html += `<div style="margin-left: ${
44- indentLevel * 20
45- } px;">- ${ this . formatJSON ( item , indentLevel + 1 ) } </div>`;
79+ html += `
80+ <div class="json-array-item" style="
81+ padding: 4px 0;
82+ margin-left: ${ indentLevel * 24 } px;
83+ display: flex;
84+ align-items: flex-start;
85+ ">
86+ <span style="margin-right: 8px;">•</span>
87+ <div style="flex: 1;">${ this . formatJSON ( item , indentLevel + 1 ) } </div>
88+ </div>
89+ ` ;
4690 }
4791 } ) ;
92+ html += '</div>' ;
4893 return html ;
4994 }
5095
@@ -55,13 +100,64 @@ class JSONFormatter {
55100 * @returns A string containing the formatted HTML.
56101 */
57102 private static formatObject ( obj : { [ key : string ] : any } , indentLevel : number ) : string {
58- let html = '' ;
103+ if ( Object . keys ( obj ) . length === 0 ) {
104+ return '<div style="color: #666;">(empty object)</div>' ;
105+ }
106+
107+ let html = '<div class="json-object" style="width: 100%;">' ;
59108 const keys = Object . keys ( obj ) ;
60109 keys . forEach ( ( key , index ) => {
61- html += `<div style="margin-left: ${ indentLevel * 20 } px;">
62- <strong>${ key } :</strong> ${ this . formatJSON ( obj [ key ] , indentLevel + 1 ) }
63- </div>` ;
110+ const value = obj [ key ] ;
111+ const isNested = typeof value === 'object' && value !== null ;
112+
113+ if ( isNested ) {
114+ // Nested objects/arrays get their own block
115+ html += `
116+ <div class="json-property nested" style="
117+ padding: 8px 0;
118+ margin-left: ${ indentLevel * 24 } px;
119+ ">
120+ <div style="
121+ font-weight: bold;
122+ margin-bottom: 8px;
123+ ">${ this . transformKey ( key ) } :</div>
124+ <div style="
125+ padding-left: 24px;
126+ ">
127+ ${ this . formatJSON ( value , indentLevel + 1 ) }
128+ </div>
129+ </div>
130+ ` ;
131+ } else {
132+ // Primitive values stay inline
133+ html += `
134+ <div class="json-property" style="
135+ padding: 8px 0;
136+ margin-left: ${ indentLevel * 24 } px;
137+ display: flex;
138+ flex-wrap: wrap;
139+ align-items: flex-start;
140+ ">
141+ <strong style="
142+ min-width: 120px;
143+ max-width: 100%;
144+ margin-right: 12px;
145+ margin-bottom: 4px;
146+ ">${ this . transformKey ( key ) } :</strong>
147+ <div style="
148+ flex: 1;
149+ min-width: 200px;
150+ overflow-wrap: break-word;
151+ word-wrap: break-word;
152+ word-break: break-word;
153+ ">
154+ ${ this . formatJSON ( value , indentLevel + 1 ) }
155+ </div>
156+ </div>
157+ ` ;
158+ }
64159 } ) ;
160+ html += '</div>' ;
65161 return html ;
66162 }
67163
@@ -72,15 +168,24 @@ class JSONFormatter {
72168 * @returns A string containing the formatted HTML.
73169 */
74170 private static formatPrimitive ( value : any , indentLevel : number ) : string {
171+ const style = `
172+ color: #444;
173+ font-family: monospace;
174+ overflow-wrap: break-word;
175+ word-wrap: break-word;
176+ word-break: break-word;
177+ ` ;
178+
75179 if ( typeof value === 'string' ) {
76- return `<span>"${ value } "</span>` ; // Wrap strings in quotes for clarity
180+ return `<span style=" ${ style } " >"${ value } "</span>` ;
77181 } else if ( value === null ) {
78- return ' <span>null</span>' ; // Handle null values
182+ return ` <span style=" ${ style } " >null</span>` ;
79183 } else if ( typeof value === 'undefined' ) {
80- return ' <span>undefined</span>' ; // Handle undefined values
184+ return ` <span style=" ${ style } " >undefined</span>` ;
81185 } else {
82- return `<span>${ value . toString ( ) } </span>` ; // Numbers, booleans, etc.
186+ return `<span style=" ${ style } " >${ value . toString ( ) } </span>` ;
83187 }
84188 }
85189}
190+
86191export default JSONFormatter ;
0 commit comments