# 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 /generate-clean-arch-macos-arm64 -o generate-clean-arch chmod +x generate-clean-arch && ./generate-clean-arch -i swagger.yaml # macOS (Intel) curl -L /generate-clean-arch-macos-x64 -o generate-clean-arch chmod +x generate-clean-arch && ./generate-clean-arch -i swagger.yaml # Linux x64 curl -L /generate-clean-arch-linux-x64 -o generate-clean-arch chmod +x generate-clean-arch && ./generate-clean-arch -i swagger.yaml # Windows (PowerShell) curl -L /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 the registry ```bash bun add -g @blas/openapi-clean-arch-generator --registry https://git.blassanto.me/api/packages/blas/npm/ ``` Or configure the registry in your `.npmrc` / `bunfig.toml` and then run: ```bash generate-clean-arch -i swagger.yaml ``` ### Option 2: Clone and use locally ```bash git clone 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 OpenAPI/Swagger file (yaml or json) [default: swagger.yaml] -o, --output Output directory [default: ./src/app] -t, --templates Custom templates directory [default: ./templates] -s, --select-endpoints Interactively select tags and endpoints to generate --skip-install Skip dependency installation --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 β”‚ β”‚ β”œβ”€β”€ order-type/ β”‚ β”‚ β”‚ └── order-type.dto.ts β”‚ β”‚ └── supply-mode/ β”‚ β”‚ └── supply-mode.dto.ts β”‚ β”œβ”€β”€ repositories/ # Repository implementations β”‚ β”‚ β”œβ”€β”€ node.repository.impl.ts β”‚ β”‚ β”œβ”€β”€ order-type.repository.impl.ts β”‚ β”‚ └── supply-mode.repository.impl.ts β”‚ └── mappers/ # DTO β†’ Entity transformers β”‚ β”œβ”€β”€ node.mapper.ts β”‚ β”œβ”€β”€ order-type.mapper.ts β”‚ └── supply-mode.mapper.ts β”œβ”€β”€ domain/ # Domain layer β”‚ β”œβ”€β”€ repositories/ # Repository contracts β”‚ β”‚ β”œβ”€β”€ node.repository.contract.ts β”‚ β”‚ β”œβ”€β”€ order-type.repository.contract.ts β”‚ β”‚ └── supply-mode.repository.contract.ts β”‚ └── use-cases/ # Use cases β”‚ β”œβ”€β”€ node/ β”‚ β”‚ β”œβ”€β”€ node.use-cases.contract.ts β”‚ β”‚ └── node.use-cases.impl.ts β”‚ β”œβ”€β”€ order-type/ β”‚ β”‚ β”œβ”€β”€ order-type.use-cases.contract.ts β”‚ β”‚ └── order-type.use-cases.impl.ts β”‚ └── supply-mode/ β”‚ β”œβ”€β”€ supply-mode.use-cases.contract.ts β”‚ └── supply-mode.use-cases.impl.ts β”œβ”€β”€ di/ # Dependency injection β”‚ β”œβ”€β”€ repositories/ # Repository providers β”‚ β”‚ β”œβ”€β”€ node.repository.provider.ts β”‚ β”‚ β”œβ”€β”€ order-type.repository.provider.ts β”‚ β”‚ └── supply-mode.repository.provider.ts β”‚ └── use-cases/ # Use case providers β”‚ β”œβ”€β”€ node.use-cases.provider.ts β”‚ β”œβ”€β”€ order-type.use-cases.provider.ts β”‚ └── supply-mode.use-cases.provider.ts └── entities/ # Domain entities └── models/ β”œβ”€β”€ node.model.ts β”œβ”€β”€ order-type.model.ts └── supply-mode.model.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-entity.mustache` | Domain entity models | | `mapper.mustache` | DTO β†’ Entity mappers | | `api.repository.contract.mustache` | Repository contracts | | `api.repository.impl.mustache` | Repository implementations | | `api.use-cases.contract.mustache` | Use case contracts | | `api.use-cases.impl.mustache` | Use case implementations | | `repository.provider.mustache` | Repository DI providers | | `use-cases.provider.mustache` | Use case DI providers | ### 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, "outputDirectory": "./src/app", "structure": { "dtos": 15, "repositories": 9, "mappers": 3, "useCases": 6 } } ``` ## 🎯 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