Skip to content

Commit

Permalink
feat: add console formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Aug 27, 2024
1 parent 5eb7295 commit 4beb62f
Show file tree
Hide file tree
Showing 12 changed files with 842 additions and 70 deletions.
17 changes: 17 additions & 0 deletions examples/console.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* @poppinss/dumper
*
* (c) Poppinss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { dump, themes } from '../formatters/console/main.js'
import { obj } from './values.js'

console.log(
dump(obj, {
styles: themes.dark,
})
)
24 changes: 16 additions & 8 deletions examples/values.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

const fooSymbol = Symbol.for('foo')
const blob = new Blob(['hello'])

class User {
constructor() {
Expand Down Expand Up @@ -37,19 +38,22 @@ class User {
}
}

const holes = ['a', 'b']
const holes: any[] = ['a', 'b']
holes[4] = 'e'
holes[6] = 'g'
holes[7] = holes

const hooks: Set<(() => void) | { name: string; fn: () => void }> = new Set()
const hooks: Set<(() => void) | { name: string; fn: (() => void) | Set<any> }> = new Set()
hooks.add(() => {})
hooks.add({ name: 'afterCreate', fn: async () => {} })
hooks.add({ name: 'beforeCreate', fn: async () => {} })
hooks.add({ name: 'self', fn: hooks })

const middleware: Map<{ name: string; type: string }, { fn: Function }> = new Map()
const middleware: Map<{ name: string; type: string }, { fn: Function } | Map<any, any>> = new Map()
middleware.set({ name: 'auth', type: 'global' }, { fn: () => {} })
middleware.set({ name: 'bouncer', type: 'router' }, { fn: () => {} })
middleware.set({ name: 'assets', type: 'server' }, { fn: () => {} })
middleware.set({ name: 'self', type: 'reference' }, middleware)

class Collection<T> extends Array<T> {
items: T[] = []
Expand All @@ -76,6 +80,13 @@ class Model {
}

const collection = new Collection(new User())
const e = {
regex: /^x/i,
buf: Buffer.from('abc'),
holes: holes,
circular: {},
}
e.circular = e

export const obj = {
'a': 1,
Expand All @@ -84,15 +95,12 @@ export const obj = {
'bio': `Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.`,
'c': undefined,
'd': null,
blob,
'user': new User(),
'User': User,
'error': new Error('Something went wrong'),
'url': new URL('./index.js?username=virk', 'https://unpkg.com'),
'e': {
regex: /^x/i,
buf: Buffer.from('abc'),
holes: holes,
},
'e': e,
collection,
hooks,
'promise': new Promise((resolve) => resolve('foo')),
Expand Down
93 changes: 93 additions & 0 deletions formatters/console/formatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* @poppinss/dumper
*
* (c) Poppinss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { themes } from './themes.js'
import type { Token } from '../../src/types.js'
import { ConsolePrinters } from './printers/main.js'
import type { ConsoleFormatterConfig, ConsolePrinterStyles } from './types.js'

/**
* ConsoleFormatter is used to format a collection of parser
* tokens to CLI output.
*
* @example
* ```ts
* const parser = new Parser()
* parser.parse(value)
*
* const tokens = parser.flush()
*
* const formatter = new ConsoleFormatter()
* const output = formatter.format(tokens)
* ```
*/
export class ConsoleFormatter {
/**
* Styles for output elements
*/
readonly styles: ConsolePrinterStyles

/**
* Context maintained through out the printing
* phase. Each instance has its own context
* that gets mutated internally.
*/
context: Record<string, any>

/**
* Value for the newline character
*/
readonly newLine = '\n'

/**
* Utility to manage indentation
*/
readonly indentation = {
counter: 0,

/**
* Increment the identation by 1 step
*/
increment() {
this.counter++
},

/**
* Decrement the identation by 1 step
*/
decrement() {
this.counter--
},

/**
* Get the identation spaces as per the current
* identation level
*/
getSpaces() {
return new Array(this.counter * 2 + 1).join(' ')
},
}

constructor(config?: ConsoleFormatterConfig, context?: Record<string, any>) {
this.context = context || {}
this.styles = Object.freeze({ ...themes.dark, ...config?.styles })
}

/**
* Format a collection of tokens to ANSI output
*/
format(tokens: Token[]) {
return tokens
.map((token) => {
const formatter = ConsolePrinters[token.type]
return formatter(token as any, this) || ''
})
.join('')
}
}
45 changes: 45 additions & 0 deletions formatters/console/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* @poppinss/dumper
*
* (c) Poppinss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { Parser } from '../../src/parser.js'
import { ConsoleFormatter } from './formatter.js'
import type { ConsoleDumpConfig } from './types.js'

export { ConsoleFormatter }
export { themes } from './themes.js'
export { ConsolePrinters } from './printers/main.js'

/**
* Generate pretty printed HTML output for the provided value. You can
* specify the parser and the formatter options as the 2nd argument.
*
* @example
* ```ts
* const html = dump(someValue)
*
* // With Parser options
* const html = dump(someValue, {
* inspectObjectPrototype: true,
* depth: 10,
* showHidden: true,
* })
*
* // With Formatter options
* const html = dump(someValue, {
* styles: {
* number: 'color: yellow; font-weight: bold;'
* }
* })
* ```
*/
export function dump(value: any, config?: ConsoleDumpConfig) {
const parser = new Parser(config)
parser.parse(value)
return new ConsoleFormatter(config).format(parser.flush())
}
Loading

0 comments on commit 4beb62f

Please sign in to comment.