Skip to content

Commit 02f510f

Browse files
feat: add comprehensive GraphQL debug dashboard with VFS inspection (#42)
* feat: add comprehensive GraphQL debug dashboard - Add new debug endpoint at /_nitro/graphql/debug - Display environment, scanned files, and runtime info - Show resolver exports with color-coded type badges - Add virtual module inspection - Implement GraphQL brand colors and professional design - Support scrollable lists for large resolver counts - Add JSON API endpoint with ?format=json Features: - Color-coded resolver types (query/mutation/type/directive) - Unique symbols for each resolver type - Tailwind CSS v4 with custom scrollbars - GraphQL pink (#E535AB) brand theming - Responsive grid layouts - File path listings for schemas and documents 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: display generated virtual module source code in debug dashboard - Add virtualModules field to debugInfo with generated code - Create expandable/collapsible details for each virtual module - Show module statistics (line count, byte size) - Add copy-to-clipboard functionality for each module - Color-code modules by type (schemas, resolvers, directives, config) - Display modules: - server-schemas (blue) - server-resolvers (GraphQL pink) - server-directives (amber) - module-config (purple) - graphql-config (emerald) Improvements: - Users can now inspect generated VFS code at runtime - Each module shows size and line count - One-click copy functionality - Scrollable code blocks with max-height - Professional color coding matching resolver types 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: use actual virtual module source code instead of runtime samples - Fix virtualModules field to use debugInfo.virtualModules (string code) - Rename runtime sample data to virtualModuleSamples - Add null check for virtualModules to prevent errors - Now displays actual generated TypeScript/JavaScript code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: resolve TypeScript type errors in virtual modules and debug route - Add type casting for virtual module generators (as string) - Add explicit any types for import map parameters - Fix Promise<string> | string type conflicts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent fb03474 commit 02f510f

File tree

5 files changed

+806
-98
lines changed

5 files changed

+806
-98
lines changed

src/index.ts

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -206,43 +206,64 @@ export default defineNitroModule({
206206
nitro.scanDocuments = docs
207207

208208
// Validate resolver setup and provide helpful diagnostics (only in dev)
209-
if (nitro.options.dev && resolvers.length > 0) {
210-
const totalExports = resolvers.reduce((sum, r) => sum + r.imports.length, 0)
211-
consola.success(`[nitro-graphql] Found ${totalExports} resolver export(s) from ${resolvers.length} file(s)`)
212-
213-
// Show breakdown by type for better visibility
214-
const typeCount = {
215-
query: 0,
216-
mutation: 0,
217-
resolver: 0,
218-
type: 0,
219-
subscription: 0,
220-
directive: 0,
221-
}
222-
for (const resolver of resolvers) {
223-
for (const imp of resolver.imports) {
224-
if (imp.type in typeCount) {
225-
typeCount[imp.type as keyof typeof typeCount]++
209+
if (nitro.options.dev) {
210+
consola.box({
211+
title: 'Nitro GraphQL',
212+
message: [
213+
`Framework: ${nitro.options.graphql?.framework || 'Not configured'}`,
214+
`Schemas: ${schemas.length}`,
215+
`Resolvers: ${resolvers.length}`,
216+
`Directives: ${directives.length}`,
217+
`Documents: ${docs.length}`,
218+
'',
219+
'Debug Dashboard: /_nitro/graphql/debug',
220+
].join('\n'),
221+
style: {
222+
borderColor: 'cyan',
223+
borderStyle: 'rounded',
224+
},
225+
})
226+
227+
if (resolvers.length > 0) {
228+
const totalExports = resolvers.reduce((sum, r) => sum + r.imports.length, 0)
229+
230+
// Show breakdown by type for better visibility
231+
const typeCount = {
232+
query: 0,
233+
mutation: 0,
234+
resolver: 0,
235+
type: 0,
236+
subscription: 0,
237+
directive: 0,
238+
}
239+
for (const resolver of resolvers) {
240+
for (const imp of resolver.imports) {
241+
if (imp.type in typeCount) {
242+
typeCount[imp.type as keyof typeof typeCount]++
243+
}
226244
}
227245
}
228-
}
229246

230-
const breakdown: string[] = []
231-
if (typeCount.query > 0)
232-
breakdown.push(`${typeCount.query} query`)
233-
if (typeCount.mutation > 0)
234-
breakdown.push(`${typeCount.mutation} mutation`)
235-
if (typeCount.resolver > 0)
236-
breakdown.push(`${typeCount.resolver} resolver`)
237-
if (typeCount.type > 0)
238-
breakdown.push(`${typeCount.type} type`)
239-
if (typeCount.subscription > 0)
240-
breakdown.push(`${typeCount.subscription} subscription`)
241-
if (typeCount.directive > 0)
242-
breakdown.push(`${typeCount.directive} directive`)
243-
244-
if (breakdown.length > 0) {
245-
consola.info(`[nitro-graphql] Resolver breakdown: ${breakdown.join(', ')}`)
247+
const breakdown: string[] = []
248+
if (typeCount.query > 0)
249+
breakdown.push(`${typeCount.query} query`)
250+
if (typeCount.mutation > 0)
251+
breakdown.push(`${typeCount.mutation} mutation`)
252+
if (typeCount.resolver > 0)
253+
breakdown.push(`${typeCount.resolver} resolver`)
254+
if (typeCount.type > 0)
255+
breakdown.push(`${typeCount.type} type`)
256+
if (typeCount.subscription > 0)
257+
breakdown.push(`${typeCount.subscription} subscription`)
258+
if (typeCount.directive > 0)
259+
breakdown.push(`${typeCount.directive} directive`)
260+
261+
if (breakdown.length > 0) {
262+
consola.success(`[nitro-graphql] ${totalExports} resolver export(s): ${breakdown.join(', ')}`)
263+
}
264+
}
265+
else {
266+
consola.warn('[nitro-graphql] No resolvers found. Check /_nitro/graphql/debug for details.')
246267
}
247268
}
248269
})
@@ -292,6 +313,16 @@ export default defineNitroModule({
292313
method: 'get',
293314
})
294315

316+
// Debug endpoint (development only)
317+
if (nitro.options.dev) {
318+
nitro.options.handlers.push({
319+
route: '/_nitro/graphql/debug',
320+
handler: join(runtime, 'debug'),
321+
method: 'get',
322+
})
323+
consola.info('[nitro-graphql] Debug dashboard available at: /_nitro/graphql/debug')
324+
}
325+
295326
// Auto-import utilities
296327
if (nitro.options.imports) {
297328
nitro.options.imports.presets ??= []

0 commit comments

Comments
 (0)