337 lines
10 KiB
Markdown
337 lines
10 KiB
Markdown
# OpenAPI Clean Architecture Generator
|
|
|
|
Angular code generator that creates clean architecture boilerplate from OpenAPI/Swagger specifications. Automates the creation of DTOs, repositories, mappers, use cases and dependency injection providers.
|
|
|
|
## 📦 Requirements
|
|
|
|
- [Bun](https://bun.sh) >= 1.0.0
|
|
- [Java](https://www.java.com) (required by `openapi-generator-cli`)
|
|
|
|
## 🚀 Installation
|
|
|
|
### Option 0: Prebuilt binary (no dependencies)
|
|
|
|
Download the binary for your platform from the releases page and run it directly — no Node, Bun or Java required:
|
|
|
|
```bash
|
|
# macOS (Apple Silicon)
|
|
curl -L https://git.blassanto.me/blas/openapi-clean-arch-gen/releases/latest/download/generate-clean-arch-macos-arm64 -o generate-clean-arch
|
|
chmod +x generate-clean-arch && ./generate-clean-arch -i swagger.yaml
|
|
|
|
# macOS (Intel)
|
|
curl -L https://git.blassanto.me/blas/openapi-clean-arch-gen/releases/latest/download/generate-clean-arch-macos-x64 -o generate-clean-arch
|
|
chmod +x generate-clean-arch && ./generate-clean-arch -i swagger.yaml
|
|
|
|
# Linux x64
|
|
curl -L https://git.blassanto.me/blas/openapi-clean-arch-gen/releases/latest/download/generate-clean-arch-linux-x64 -o generate-clean-arch
|
|
chmod +x generate-clean-arch && ./generate-clean-arch -i swagger.yaml
|
|
|
|
# Windows (PowerShell)
|
|
curl -L https://git.blassanto.me/blas/openapi-clean-arch-gen/releases/latest/download/generate-clean-arch-windows-x64.exe -o generate-clean-arch.exe
|
|
.\generate-clean-arch.exe -i swagger.yaml
|
|
```
|
|
|
|
### Option 1: Install as a global CLI from npm
|
|
|
|
```bash
|
|
bun add -g @0kmpo/openapi-clean-arch-generator
|
|
```
|
|
|
|
Then run:
|
|
|
|
```bash
|
|
generate-clean-arch -i swagger.yaml
|
|
```
|
|
|
|
### Option 2: Clone and use locally
|
|
|
|
```bash
|
|
git clone <repo>
|
|
cd openapi-clean-arch-generator
|
|
bun install
|
|
bun run setup # installs openapi-generator-cli globally
|
|
```
|
|
|
|
## 📖 Usage
|
|
|
|
### Basic command
|
|
|
|
```bash
|
|
# Installed globally
|
|
generate-clean-arch -i swagger.yaml
|
|
|
|
# From the repository (compiled)
|
|
bun run generate -- -i swagger.yaml
|
|
|
|
# From the repository (development, no compilation needed)
|
|
bun run generate:dev -- -i swagger.yaml
|
|
```
|
|
|
|
### Available options
|
|
|
|
```
|
|
Options:
|
|
-V, --version Show version
|
|
-i, --input <file> OpenAPI/Swagger file (yaml or json) [default: swagger.yaml]
|
|
-o, --output <dir> Output directory [default: ./src/app]
|
|
-t, --templates <dir> Custom templates directory [default: ./templates]
|
|
-s, --select-endpoints Interactively select tags and endpoints to generate
|
|
-c, --config <file> Use a JSON configuration file (skips interactive prompts)
|
|
--init-config [file] Generate a JSON configuration file instead of generating code
|
|
--skip-install Skip dependency installation
|
|
--skip-lint Skip post-generation linting and formatting
|
|
--dry-run Simulate without writing files
|
|
-h, --help Show help
|
|
```
|
|
|
|
### Examples
|
|
|
|
```bash
|
|
# Generate from swagger.yaml into src/app
|
|
generate-clean-arch -i swagger.yaml -o ./src/app
|
|
|
|
# Interactively select tags/endpoints
|
|
generate-clean-arch -i api.yaml -s
|
|
|
|
# Use custom templates
|
|
generate-clean-arch -i api.yaml -t ./my-templates
|
|
|
|
# Dry run (no files written)
|
|
generate-clean-arch -i swagger.yaml --dry-run
|
|
|
|
# Full example with all options
|
|
generate-clean-arch -i ./docs/api.yaml -o ./frontend/src/app -t ./custom-templates
|
|
```
|
|
|
|
## 📁 Generated Structure
|
|
|
|
The generator creates the following structure following Clean Architecture:
|
|
|
|
```
|
|
src/app/
|
|
├── data/ # Data layer
|
|
│ ├── dtos/ # Data Transfer Objects
|
|
│ │ ├── node/
|
|
│ │ │ ├── node.dto.ts
|
|
│ │ │ └── node.dto.mock.ts
|
|
│ │ ├── order-type/
|
|
│ │ │ ├── order-type.dto.ts
|
|
│ │ │ └── order-type.dto.mock.ts
|
|
│ │ └── supply-mode/
|
|
│ │ ├── supply-mode.dto.ts
|
|
│ │ └── supply-mode.dto.mock.ts
|
|
│ ├── repositories/ # Repository implementations
|
|
│ │ ├── node.repository.impl.ts
|
|
│ │ ├── node.repository.impl.mock.ts
|
|
│ │ ├── node.repository.impl.spec.ts
|
|
│ │ ├── order-type.repository.impl.ts
|
|
│ │ ├── order-type.repository.impl.mock.ts
|
|
│ │ ├── order-type.repository.impl.spec.ts
|
|
│ │ └── ...
|
|
│ └── mappers/ # DTO → Entity transformers
|
|
│ ├── node.mapper.ts
|
|
│ ├── node.mapper.spec.ts
|
|
│ ├── order-type.mapper.ts
|
|
│ ├── order-type.mapper.spec.ts
|
|
│ └── ...
|
|
├── domain/ # Domain layer
|
|
│ ├── repositories/ # Repository contracts
|
|
│ │ ├── node.repository.contract.ts
|
|
│ │ └── ...
|
|
│ └── use-cases/ # Use cases
|
|
│ ├── node/
|
|
│ │ ├── node.use-cases.contract.ts
|
|
│ │ ├── node.use-cases.impl.ts
|
|
│ │ ├── node.use-cases.mock.ts
|
|
│ │ └── node.use-cases.impl.spec.ts
|
|
│ └── ...
|
|
├── di/ # Dependency injection
|
|
│ ├── repositories/ # Repository providers
|
|
│ │ ├── node.repository.provider.ts
|
|
│ │ ├── node.repository.provider.mock.ts
|
|
│ │ └── ...
|
|
│ └── use-cases/ # Use case providers
|
|
│ ├── node.use-cases.provider.ts
|
|
│ ├── node.use-cases.provider.mock.ts
|
|
│ └── ...
|
|
└── entities/ # Domain entities
|
|
└── models/
|
|
├── node.model.ts
|
|
├── node.model.mock.ts
|
|
├── node.model.spec.ts
|
|
└── ...
|
|
```
|
|
|
|
## 🔧 Template Customization
|
|
|
|
Templates live in `templates/` and use [Mustache](https://mustache.github.io/) syntax. Override them by passing your own directory with `-t`.
|
|
|
|
| Template | Generates |
|
|
|---|---|
|
|
| `model.mustache` | DTOs |
|
|
| `model.mock.mustache` | DTO mocks |
|
|
| `dto.mock.mustache` | DTO mocks (alternative) |
|
|
| `model-entity.mustache` | Domain entity models |
|
|
| `model-entity.spec.mustache` | Entity model specs |
|
|
| `mapper.mustache` | DTO → Entity mappers |
|
|
| `mapper.spec.mustache` | Mapper specs |
|
|
| `api.repository.contract.mustache` | Repository contracts |
|
|
| `api.repository.impl.mustache` | Repository implementations |
|
|
| `api.repository.impl.mock.mustache` | Repository mocks |
|
|
| `api.repository.impl.spec.mustache` | Repository specs |
|
|
| `api.use-cases.contract.mustache` | Use case contracts |
|
|
| `api.use-cases.impl.mustache` | Use case implementations |
|
|
| `api.use-cases.mock.mustache` | Use case mocks |
|
|
| `api.use-cases.impl.spec.mustache` | Use case specs |
|
|
| `repository.provider.mustache` | Repository DI providers |
|
|
| `repository.provider.mock.mustache` | Repository provider mocks |
|
|
| `use-cases.provider.mustache` | Use case DI providers |
|
|
| `use-cases.provider.mock.mustache` | Use case provider mocks |
|
|
|
|
### Available Mustache variables
|
|
|
|
```mustache
|
|
{{classname}} - Class name (e.g. "OrderType")
|
|
{{classVarName}} - camelCase name (e.g. "orderType")
|
|
{{classFilename}} - File name (e.g. "order-type")
|
|
{{constantName}} - UPPER_SNAKE_CASE constant (e.g. "ORDER_TYPE")
|
|
{{description}} - Schema description
|
|
{{httpMethod}} - HTTP method (get, post, put, delete…)
|
|
{{path}} - Endpoint path
|
|
{{nickname}} - Method name
|
|
{{allParams}} - All endpoint parameters
|
|
{{returnType}} - Return type
|
|
{{vars}} - Model variables
|
|
```
|
|
|
|
## 📊 Generation Report
|
|
|
|
After each run a `generation-report.json` file is created:
|
|
|
|
```json
|
|
{
|
|
"timestamp": "2025-01-15T10:30:00.000Z",
|
|
"tags": 3,
|
|
"endpoints": 8,
|
|
"tagDetails": [
|
|
{ "name": "User", "description": "User operations", "endpoints": 3 },
|
|
{ "name": "Product", "description": "Product operations", "endpoints": 2 }
|
|
],
|
|
"outputDirectory": "./src/app",
|
|
"linting": {
|
|
"prettier": { "ran": true, "filesFormatted": 42 },
|
|
"eslint": { "ran": true, "filesFixed": 42 }
|
|
},
|
|
"structure": {
|
|
"dtos": 15,
|
|
"repositories": 9,
|
|
"mappers": 5,
|
|
"useCases": 6,
|
|
"providers": 12,
|
|
"mocks": 18,
|
|
"specs": 14
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🎯 Angular Integration Example
|
|
|
|
### 1. Generate code
|
|
|
|
```bash
|
|
generate-clean-arch -i ./docs/api.yaml -o ./src/app
|
|
```
|
|
|
|
### 2. Register providers
|
|
|
|
In your `app.config.ts` (Angular 17+ standalone):
|
|
|
|
```typescript
|
|
import { ApplicationConfig } from '@angular/core';
|
|
import { NodeRepositoryProvider } from './di/repositories/node.repository.provider';
|
|
import { NodeUseCasesProvider } from './di/use-cases/node.use-cases.provider';
|
|
|
|
export const appConfig: ApplicationConfig = {
|
|
providers: [
|
|
NodeRepositoryProvider,
|
|
NodeUseCasesProvider,
|
|
// ... rest of generated providers
|
|
]
|
|
};
|
|
```
|
|
|
|
### 3. Use in components
|
|
|
|
```typescript
|
|
import { Component, inject } from '@angular/core';
|
|
import { NODE_USE_CASES } from './domain/use-cases/node/node.use-cases.contract';
|
|
|
|
@Component({
|
|
selector: 'app-nodes',
|
|
template: `...`
|
|
})
|
|
export class NodesComponent {
|
|
readonly #nodeUseCases = inject(NODE_USE_CASES);
|
|
|
|
loadNodes(): void {
|
|
this.#nodeUseCases.getNodes().subscribe((nodes) => {
|
|
console.log(nodes);
|
|
});
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🐛 Troubleshooting
|
|
|
|
### `openapi-generator-cli` not found
|
|
|
|
```bash
|
|
bun run setup
|
|
# or manually:
|
|
bun add -g @openapitools/openapi-generator-cli
|
|
```
|
|
|
|
### swagger.yaml file not found
|
|
|
|
Specify the correct path with `-i`:
|
|
|
|
```bash
|
|
generate-clean-arch -i ./path/to/your/api.yaml
|
|
```
|
|
|
|
### Path aliases `@/` not resolving
|
|
|
|
Configure the aliases in your Angular project's `tsconfig.json`:
|
|
|
|
```json
|
|
{
|
|
"compilerOptions": {
|
|
"paths": {
|
|
"@/*": ["src/app/*"]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Templates not generating expected code
|
|
|
|
1. Make sure your templates are in `./templates/` or pass the path with `-t`
|
|
2. Check the Mustache syntax
|
|
3. Use `--dry-run` to simulate without writing files
|
|
|
|
## 📝 Notes
|
|
|
|
- The generator produces ready-to-use `.ts` files, it does not compile them
|
|
- Providers must be registered manually in your Angular module or config
|
|
- Requires Angular 17+ (uses the `inject()` function)
|
|
- Compatible with both standalone and module-based projects
|
|
|
|
## 🤝 Contributing
|
|
|
|
Found a bug or have an improvement? Open an issue or PR in the repository.
|
|
|
|
## 📄 License
|
|
|
|
MIT
|
|
|