-
-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added pretty json print options to visualise better logs
- Loading branch information
1 parent
7ca0e8d
commit 5c95c90
Showing
4 changed files
with
278 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './pretty'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import chalk from 'chalk'; | ||
|
||
const TWO_SPACES = ' '; | ||
|
||
const COLOR_STRING = chalk.hex('#98c379'); // Soft green for strings | ||
const COLOR_KEY = chalk.hex('#61afef'); // Muted cyan for keys | ||
const COLOR_NUMBER = chalk.hex('#d19a66'); // Light orange for numbers | ||
const COLOR_BOOLEAN = chalk.hex('#c678dd'); // Light purple for booleans | ||
const COLOR_NULL = chalk.hex('#c678dd'); // Light purple for null | ||
const COLOR_BRACKETS = chalk.hex('#abb2bf'); // Soft white for object and array brackets | ||
|
||
const processString = ( | ||
str: string, | ||
indent: string, | ||
handleMultiline: boolean, | ||
): string => { | ||
if (handleMultiline && str.includes('\n')) { | ||
const lines = str.split('\n'); | ||
const indentedLines = lines.map( | ||
(line) => indent + TWO_SPACES + COLOR_STRING(line), | ||
); | ||
return ( | ||
COLOR_STRING('"') + | ||
'\n' + | ||
indentedLines.join('\n') + | ||
'\n' + | ||
indent + | ||
COLOR_STRING('"') | ||
); | ||
} | ||
return COLOR_STRING(`"${str}"`); | ||
}; | ||
|
||
// Function to format and colorize JSON by traversing it | ||
const formatJson = ( | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
obj: any, | ||
indentLevel: number = 0, | ||
handleMultiline: boolean = false, | ||
): string => { | ||
const indent = TWO_SPACES.repeat(indentLevel); | ||
|
||
if (obj === null) return COLOR_NULL('null'); | ||
if (typeof obj === 'string') | ||
return processString(obj, indent, handleMultiline); | ||
if (typeof obj === 'number') return COLOR_NUMBER(String(obj)); | ||
if (typeof obj === 'boolean') return COLOR_BOOLEAN(String(obj)); | ||
|
||
// Handle arrays | ||
if (Array.isArray(obj)) { | ||
const arrayItems = obj.map((item) => | ||
formatJson(item, indentLevel + 1, handleMultiline), | ||
); | ||
return `${COLOR_BRACKETS('[')}\n${indent} ${arrayItems.join( | ||
`,\n${indent} `, | ||
)}\n${indent}${COLOR_BRACKETS(']')}`; | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument | ||
const entries = Object.entries(obj).map( | ||
([key, value]) => | ||
`${COLOR_KEY(`"${key}"`)}: ${formatJson( | ||
value, | ||
indentLevel + 1, | ||
handleMultiline, | ||
)}`, | ||
); | ||
return `${COLOR_BRACKETS('{')}\n${indent} ${entries.join( | ||
`,\n${indent} `, | ||
)}\n${indent}${COLOR_BRACKETS('}')}`; | ||
}; | ||
|
||
export const prettyPrintJson = ( | ||
obj: unknown, | ||
handleMultiline: boolean = false, | ||
): string => formatJson(obj, 0, handleMultiline); |
128 changes: 128 additions & 0 deletions
128
src/packages/dumbo/src/core/tracing/printing/pretty.unit.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import assert from 'assert'; | ||
import chalk from 'chalk'; | ||
import { describe, it } from 'node:test'; | ||
import { prettyPrintJson } from './pretty'; | ||
|
||
// Define a basic test suite | ||
void describe('prettyPrintJson', () => { | ||
// Turn off chalk colorization during tests for easy comparison | ||
chalk.level = 0; | ||
|
||
void it('formats a simple object correctly without multiline strings', () => { | ||
const input = { | ||
name: 'John Doe', | ||
age: 30, | ||
}; | ||
|
||
const expectedOutput = `{ | ||
"name": "John Doe", | ||
"age": 30 | ||
}`; | ||
|
||
const output = prettyPrintJson(input, false); // Multiline handling off | ||
assert.strictEqual(output, expectedOutput); | ||
}); | ||
|
||
void it('formats a simple object with multiline string handling', () => { | ||
const input = { | ||
name: 'John Doe', | ||
bio: 'This is line one.\nThis is line two.', | ||
}; | ||
|
||
const expectedOutput = `{ | ||
"name": "John Doe", | ||
"bio": " | ||
This is line one. | ||
This is line two. | ||
" | ||
}`; | ||
|
||
const output = prettyPrintJson(input, true); // Multiline handling on | ||
assert.strictEqual(output, expectedOutput); | ||
}); | ||
|
||
void it('formats nested objects correctly', () => { | ||
const input = { | ||
user: { | ||
name: 'Alice', | ||
age: 25, | ||
location: { | ||
city: 'Wonderland', | ||
country: 'Fiction', | ||
}, | ||
}, | ||
}; | ||
|
||
const expectedOutput = `{ | ||
"user": { | ||
"name": "Alice", | ||
"age": 25, | ||
"location": { | ||
"city": "Wonderland", | ||
"country": "Fiction" | ||
} | ||
} | ||
}`; | ||
|
||
const output = prettyPrintJson(input, false); // Multiline handling off | ||
assert.strictEqual(output, expectedOutput); | ||
}); | ||
|
||
void it('handles arrays and numbers correctly', () => { | ||
const input = { | ||
numbers: [1, 2, 3, 4, 5], | ||
active: true, | ||
}; | ||
|
||
const expectedOutput = `{ | ||
"numbers": [ | ||
1, | ||
2, | ||
3, | ||
4, | ||
5 | ||
], | ||
"active": true | ||
}`; | ||
|
||
const output = prettyPrintJson(input, false); // Multiline handling off | ||
assert.strictEqual(output, expectedOutput); | ||
}); | ||
|
||
void it('formats an object with null values and booleans correctly', () => { | ||
const input = { | ||
name: 'Test', | ||
isActive: false, | ||
tags: null, | ||
}; | ||
|
||
const expectedOutput = `{ | ||
"name": "Test", | ||
"isActive": false, | ||
"tags": null | ||
}`; | ||
|
||
const output = prettyPrintJson(input, false); // Multiline handling off | ||
assert.strictEqual(output, expectedOutput); | ||
}); | ||
|
||
void it('handles multiline SQL-like queries in strings', () => { | ||
const input = { | ||
query: | ||
'CREATE TABLE users (\n id INT PRIMARY KEY,\n name TEXT NOT NULL\n)', | ||
}; | ||
|
||
const expectedOutput = `{ | ||
"query": " | ||
CREATE TABLE users ( | ||
id INT PRIMARY KEY, | ||
name TEXT NOT NULL | ||
) | ||
" | ||
}`; | ||
|
||
const output = prettyPrintJson(input, true); // Multiline handling on | ||
console.log(output); | ||
assert.strictEqual(output, expectedOutput); | ||
}); | ||
}); |