7
7
* file that was distributed with this source code.
8
8
*/
9
9
10
+ import { styleText } from 'node:util'
10
11
import { dump as consoleDump } from '@poppinss/dumper/console'
11
12
import type { HTMLDumpConfig } from '@poppinss/dumper/html/types'
12
13
import type { ConsoleDumpConfig } from '@poppinss/dumper/console/types'
@@ -43,12 +44,16 @@ const DUMP_TITLE_STYLES = `
43
44
border-top-right-radius: 0;
44
45
}`
45
46
47
+ const IDE = process . env . ADONIS_IDE ?? process . env . EDITOR ?? ''
48
+
46
49
/**
47
- * Dumper exposes the API to dump or die/dump values via your
50
+ * Dumper exposes the API to dump or die/dump values in your
48
51
* AdonisJS application. An singleton instance of the Dumper
49
52
* is shared as a service and may use it follows.
50
53
*
51
54
* ```ts
55
+ * const dumper = container.make('dumper')
56
+ *
52
57
* dumper.configureHtmlOutput({
53
58
* // parser + html formatter config
54
59
* })
@@ -62,20 +67,62 @@ const DUMP_TITLE_STYLES = `
62
67
*
63
68
* // Returns style and script tags that must be
64
69
* // injeted to the head of the HTML document
70
+ *
65
71
* const head = dumper.getHeadElements()
66
72
* ```
67
73
*/
68
74
export class Dumper {
69
75
#app: Application < any >
76
+
77
+ /**
78
+ * Configuration for the HTML formatter
79
+ */
70
80
#htmlConfig: HTMLDumpConfig = { }
81
+
82
+ /**
83
+ * Configuration for the Console formatter
84
+ */
71
85
#consoleConfig: ConsoleDumpConfig = {
72
86
collapse : [ 'DateTime' , 'Date' ] ,
73
87
}
74
88
89
+ /**
90
+ * A collections of known editors to create URLs to open
91
+ * them
92
+ */
93
+ #editors: Record < string , string > = {
94
+ textmate : 'txmt://open?url=file://%f&line=%l' ,
95
+ macvim : 'mvim://open?url=file://%f&line=%l' ,
96
+ emacs : 'emacs://open?url=file://%f&line=%l' ,
97
+ sublime : 'subl://open?url=file://%f&line=%l' ,
98
+ phpstorm : 'phpstorm://open?file=%f&line=%l' ,
99
+ atom : 'atom://core/open/file?filename=%f&line=%l' ,
100
+ vscode : 'vscode://file/%f:%l' ,
101
+ }
102
+
75
103
constructor ( app : Application < any > ) {
76
104
this . #app = app
77
105
}
78
106
107
+ /**
108
+ * Returns the link to open the file using dd inside one
109
+ * of the known code editors
110
+ */
111
+ #getEditorLink( source ?: {
112
+ location : string
113
+ line : number
114
+ } ) : { href : string ; text : string } | undefined {
115
+ const editorURL = this . #editors[ IDE ] || IDE
116
+ if ( ! editorURL || ! source ) {
117
+ return
118
+ }
119
+
120
+ return {
121
+ href : editorURL . replace ( '%f' , source . location ) . replace ( '%l' , String ( source . line ) ) ,
122
+ text : `${ this . #app. relativePath ( source . location ) } :${ source . line } ` ,
123
+ }
124
+ }
125
+
79
126
/**
80
127
* Configure the HTML formatter output
81
128
*/
@@ -98,7 +145,7 @@ export class Dumper {
98
145
*/
99
146
getHeadElements ( cspNonce ?: string ) : string {
100
147
return (
101
- ' <style id="dumper-styles">' +
148
+ ` <style id="dumper-styles">` +
102
149
createStyleSheet ( ) +
103
150
DUMP_TITLE_STYLES +
104
151
'</style>' +
@@ -111,28 +158,78 @@ export class Dumper {
111
158
/**
112
159
* Dump value to HTML ouput
113
160
*/
114
- dumpToHtml ( value : unknown , cspNonce ?: string ) {
115
- return dump ( value , { cspNonce, ...this . #htmlConfig } )
161
+ dumpToHtml (
162
+ value : unknown ,
163
+ options : {
164
+ cspNonce ?: string
165
+ title ?: string
166
+ source ?: {
167
+ location : string
168
+ line : number
169
+ }
170
+ } = { }
171
+ ) {
172
+ const link = this . #getEditorLink( options . source ) ?? null
173
+ const title = options . title || 'DUMP'
174
+
175
+ return (
176
+ '<div class="adonisjs-dump-header">' +
177
+ `<span class="adonisjs-dump-header-title">${ title } </span>` +
178
+ ( link ? `<a href="${ link . href } " class="adonisjs-dump-header-source">${ link . text } </a>` : '' ) +
179
+ '</div>' +
180
+ dump ( value , { cspNonce : options . cspNonce , ...this . #htmlConfig } )
181
+ )
116
182
}
117
183
118
184
/**
119
185
* Dump value to ANSI output
120
186
*/
121
- dumpToAnsi ( value : unknown ) {
122
- return consoleDump ( value , this . #consoleConfig)
187
+ dumpToAnsi (
188
+ value : unknown ,
189
+ options : {
190
+ title ?: string
191
+ source ?: {
192
+ location : string
193
+ line : number
194
+ }
195
+ } = { }
196
+ ) {
197
+ const columns = process . stdout . columns
198
+
199
+ /**
200
+ * Link to the source file
201
+ */
202
+ const link = `${ this . #getEditorLink( options . source ) ?. text ?? '' } `
203
+
204
+ /**
205
+ * Dump title
206
+ */
207
+ const title = ` ${ options . title || 'DUMP' } `
208
+
209
+ /**
210
+ * Whitespace between the title and the link to align them
211
+ * on each side of x axis
212
+ */
213
+ const whiteSpace = new Array ( columns - link . length - title . length - 4 ) . join ( ' ' )
214
+
215
+ /**
216
+ * Styled heading with background color and bold text
217
+ */
218
+ const heading = styleText ( 'bgRed' , styleText ( 'bold' , `${ title } ${ whiteSpace } ${ link } ` ) )
219
+
220
+ return `${ heading } \n${ consoleDump ( value , this . #consoleConfig) } `
123
221
}
124
222
125
223
/**
126
224
* Dump values and die. The formatter will be picked
127
225
* based upon where your app is running.
128
226
*
129
- * - In CLI commands, the ANSI output will be printed
130
- * to the console.
131
227
* - During an HTTP request, the HTML output will be
132
228
* sent to the server.
229
+ * - Otherwise the value will be logged in the console
133
230
*/
134
231
dd ( value : unknown , traceSourceIndex : number = 1 ) {
135
- const error = new E_DUMP_DIE_EXCEPTION ( value , this , this . #app )
232
+ const error = new E_DUMP_DIE_EXCEPTION ( value , this )
136
233
error . setTraceSourceIndex ( traceSourceIndex )
137
234
throw error
138
235
}
0 commit comments