feat: implement Phase 1 of generator abstraction layer (RFC #45)#46
feat: implement Phase 1 of generator abstraction layer (RFC #45)#46michaelbe812 wants to merge 2 commits into
Conversation
- Created core interfaces and base classes for plugin system - Implemented generator registry and plugin loader - Added bundled OpenAPI Tools plugin for backward compatibility - Created external plugin package structure - Implemented auto-installation mechanism for missing plugins - Updated executor to use new abstraction layer - Added generator and autoInstall fields to schema - Maintained 100% backward compatibility Breaking changes: None This is Phase 1 of the multi-package architecture implementation as described in GitHub issue #45. Existing configurations will continue to work without any changes. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
Code Review - Phase 1 Generator Abstraction LayerOverviewThis is a well-structured implementation of Phase 1 of the generator abstraction layer as outlined in RFC #45. The implementation provides a solid foundation for pluggable generators with auto-installation and registry support while maintaining backward compatibility. ✅ StrengthsArchitecture Design:
Implementation Quality:
Backward Compatibility:
🔧 Issues Requiring AttentionCritical - Linting Errors:
Medium Priority:
📋 Specific RecommendationsFix Linting Issues: // In executor.ts line 184, remove unused destructured variables:
const { inputSpec, outputPath } = options; // Keep only what's used
// In command-builder.ts, replace 'any' with proper types:
buildArgs(options: Record<string, unknown>): string[]Improve Type Safety:
Dependencies: 🧪 Testing Status
📊 SummaryThis is a solid Phase 1 implementation that establishes the core architecture well. The code demonstrates good software engineering practices and provides a clean foundation for future generator plugins. Recommendation: Request changes to fix linting issues and investigate test failures before approval. Priority: Fix the linting errors first, then address test failures. The architectural decisions are sound. |
| const available = gen.isAvailable() ? '✓' : '✗'; | ||
| lines.push(` - ${gen.name} (${gen.displayName}) [${available}]`); |
There was a problem hiding this comment.
isAvailable() returns a Promise but is being used synchronously here. This will store the Promise object itself rather than its resolved value. Consider either:
- Making
getSummary()async and usingawait gen.isAvailable(), or - Using a synchronous check like
gen.packageName ? '?' : '✓'as a fallback indicator, or - Pre-computing availability status for all generators before building the summary
This will prevent displaying misleading availability indicators in the registry summary.
Spotted by Diamond
Is this helpful? React 👍 or 👎 to let us know.
- Fixed TypeScript compilation errors in abstraction layer - Updated tests to work with new generator architecture - Fixed linting violations across all files - Added missing project.json for nx-openapi-plugin-openapi-tools package - Fixed async/sync type mismatches - Added proper dependency declarations - All tests (119) now pass successfully - Both packages build without errors
| if (key === 'globalProperties' && typeof value === 'object' && value !== null) { | ||
| this.addGlobalProperties(args, value as Record<string, string>); | ||
| continue; | ||
| } |
There was a problem hiding this comment.
The buildArgs method handles globalProperties but is missing similar handling for additionalProperties. This creates an inconsistency where additional properties defined in the options won't be passed to the generator. Consider adding the following case after the globalProperties handling:
if (key === 'additionalProperties' && typeof value === 'object' && value !== null) {
this.addAdditionalProperties(args, value as Record<string, string>);
continue;
}The addAdditionalProperties method is already defined but not being used, which suggests this was likely an oversight.
| if (key === 'globalProperties' && typeof value === 'object' && value !== null) { | |
| this.addGlobalProperties(args, value as Record<string, string>); | |
| continue; | |
| } | |
| if (key === 'globalProperties' && typeof value === 'object' && value !== null) { | |
| this.addGlobalProperties(args, value as Record<string, string>); | |
| continue; | |
| } | |
| if (key === 'additionalProperties' && typeof value === 'object' && value !== null) { | |
| this.addAdditionalProperties(args, value as Record<string, string>); | |
| continue; | |
| } |
Spotted by Diamond
Is this helpful? React 👍 or 👎 to let us know.
Summary
This PR implements Phase 1 of RFC #45: Generator Abstraction Layer for Multi-Generator Support. It introduces a pluggable architecture that removes tight coupling with @openapitools/openapi-generator-cli while maintaining 100% backward compatibility.
✅ Status: Ready for Review
All issues from the initial code review have been addressed:
Key Changes
Core Abstraction Layer
GeneratorPlugininterface and supporting typesBaseGeneratorabstract class for plugin developmentGeneratorRegistrysingleton for plugin managementPluginLoaderfor dynamic plugin discovery and loadingPluginAutoInstallerfor automatic missing plugin installationBundled OpenAPI Tools Generator
GeneratorPlugininterfaceExternal Plugin Package
@lambda-solutions/nx-openapi-plugin-openapi-toolspackageSchema Enhancements
generatorfield for selecting generator plugingeneratorTypefield for generator-specific typesautoInstallfield for automatic plugin installationArchitecture Benefits
Testing
Files Changed
packages/nx-plugin-openapi/src/lib/core/Next Steps (Phase 2)
Related
🤖 Generated with Claude Code