// --------------------------------------------------------------------------- // DevDoctor — Plugin Development Example // Shows how to create a custom DevDoctor plugin // --------------------------------------------------------------------------- import { getPluginRegistry } from 'devdoctor'; import type { DevDoctorPlugin, ParsedError, DiagnosisResult } from 'devdoctor'; /** * Example plugin: GraphQL error patterns */ const graphqlPlugin: DevDoctorPlugin = { metadata: { name: 'devdoctor-plugin-graphql', version: '1.0.0', description: 'GraphQL error pattern detection for DevDoctor', author: 'Your Name', }, // Custom error patterns patterns: [ { id: 'graphql-validation-error', regex: /GraphQL.*validation.*failed|Cannot query field "(\w+)" on type "(\w+)"/, category: 'GraphQL', handler: (error: ParsedError, match: RegExpMatchArray): DiagnosisResult => ({ summary: `GraphQL validation error${match[1] ? `: field "${match[1]}" not found on type "${match[2]}"` : ''}`, rootCause: 'The GraphQL query references a field that does not exist on the schema type', possibleReasons: [ 'Typo in field name', 'Schema was updated but query was not', 'Using wrong type in the query', 'Missing field resolver', ], fixes: [ { description: 'Check the GraphQL schema for available fields', command: 'npx graphql-inspector introspect http://localhost:4000/graphql', }, { description: 'Regenerate types from schema', command: 'npx graphql-codegen', }, ], confidence: 0.9, source: 'plugin', errorType: error.name, framework: 'GraphQL', }), }, ], // Custom framework analyzer analyzers: [ { name: 'GraphQL', async detect(projectPath: string): Promise { // Check for common GraphQL packages try { const { readFileSync } = await import('fs'); const pkg = JSON.parse( readFileSync(`${projectPath}/package.json`, 'utf-8'), ); const deps = { ...pkg.dependencies, ...pkg.devDependencies }; return 'graphql' in deps || '@apollo/server' in deps; } catch { return false; } }, async analyzeProject() { return [ { severity: 'info' as const, category: 'config', title: 'Consider enabling GraphQL introspection in development', description: 'Introspection helps with debugging but should be disabled in production.', fix: { description: 'Enable introspection conditionally', code: `new ApolloServer({\n introspection: process.env.NODE_ENV !== 'production',\n})`, }, framework: 'GraphQL', }, ]; }, }, ], // Lifecycle hooks async onLoad() { console.log('GraphQL plugin loaded!'); }, async onUnload() { console.log('GraphQL plugin unloaded!'); }, }; // Register the plugin async function main() { const registry = getPluginRegistry(); await registry.register(graphqlPlugin); console.log('Plugin registered:', registry.getLoadedPlugins()); // Now DevDoctor will use the plugin's patterns and analyzers // when running explain() or scanProject() } main().catch(console.error);