UNPKG

@eyjs/create-app

Version:

CLI tool to generate hexagonal folder structure for EyJS applications

369 lines (295 loc) • 9.48 kB
# @eyjs/create-app [![npm version](https://badge.fury.io/js/%40eyjs%2Fcreate-app.svg)](https://badge.fury.io/js/%40eyjs%2Fcreate-app) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) CLI tool to generate hexagonal architecture folder structure for EyJS applications. Quickly scaffold new projects with domain-driven design principles and clean architecture patterns. ## Features - šŸ—ļø **Hexagonal Architecture** - Generates clean architecture folder structure - šŸŽÆ **Domain-Driven Design** - Follows DDD principles with proper separation of concerns - šŸ“ **Automated Scaffolding** - Creates all necessary files and folders automatically - šŸ”§ **TypeScript Support** - Full TypeScript setup with proper type definitions - ⚔ **Zero Configuration** - Works out of the box with sensible defaults - šŸŽØ **Customizable Templates** - Flexible template system for different project types ## Installation ```bash # Using Bun (recommended) bun add -g @eyjs/create-app # Using npm npm install -g @eyjs/create-app # Using yarn yarn global add @eyjs/create-app # Using pnpm pnpm add -g @eyjs/create-app ``` ## Quick Start ```bash # Create a new EyJS application create-eyjs-app my-awesome-app # Create app in a specific directory create-eyjs-app my-app --path ./projects # Create with custom template create-eyjs-app my-app --template api ``` ## Generated Structure The CLI generates a complete hexagonal architecture structure: ``` my-app/ ā”œā”€ā”€ application/ # Application layer │ ā”œā”€ā”€ services/ │ │ └── my-app.service.ts # Main application service │ ā”œā”€ā”€ dtos/ │ │ └── create-my-app.dto.ts # Data transfer objects │ └── interfaces/ │ └── my-app.repository.interface.ts ā”œā”€ā”€ domain/ # Domain layer │ ā”œā”€ā”€ entities/ │ │ └── my-app.entity.ts # Domain entity │ ā”œā”€ā”€ value-objects/ │ │ └── id.value-object.ts # Value objects │ ā”œā”€ā”€ events/ │ │ └── my-app-created.event.ts │ └── interfaces/ │ └── my-app.repository.interface.ts ā”œā”€ā”€ infrastructure/ # Infrastructure layer │ ā”œā”€ā”€ controllers/ │ │ └── my-app.controller.ts # HTTP controllers │ ā”œā”€ā”€ repositories/ │ │ └── my-app-mongo.repository.ts # Database implementations │ ā”œā”€ā”€ middleware/ │ │ └── validation.middleware.ts │ └── config/ │ └── database.config.ts ā”œā”€ā”€ shared/ # Shared utilities │ ā”œā”€ā”€ errors/ │ ā”œā”€ā”€ types/ │ └── utils/ ā”œā”€ā”€ tests/ # Test files │ ā”œā”€ā”€ unit/ │ ā”œā”€ā”€ integration/ │ └── e2e/ ā”œā”€ā”€ package.json ā”œā”€ā”€ tsconfig.json ā”œā”€ā”€ .env.example └── README.md ``` ## Command Line Options ```bash create-eyjs-app <app-name> [options] Options: --path <path> Specify the directory to create the app --template <name> Choose a template (api, web, microservice) --skip-install Skip dependency installation --help Show help information --version Show version information ``` ### Available Templates | Template | Description | Use Case | |----------|-------------|----------| | `api` | REST API with controllers | Backend APIs, microservices | | `web` | Full-stack web application | Web applications with frontend | | `microservice` | Microservice with event bus | Event-driven microservices | ## Generated Files ### Application Layer **Service (`application/services/my-app.service.ts`)** ```typescript import { Injectable } from '@eyjs/core' import { MyAppRepository } from '../interfaces/my-app.repository.interface' import { CreateMyAppDto } from '../dtos/create-my-app.dto' @Injectable() export class MyAppService { constructor(private readonly repository: MyAppRepository) {} async create(dto: CreateMyAppDto) { // Business logic implementation } async findById(id: string) { // Find by ID logic } } ``` **DTO (`application/dtos/create-my-app.dto.ts`)** ```typescript export interface CreateMyAppDto { name: string description?: string // Additional fields } ``` ### Domain Layer **Entity (`domain/entities/my-app.entity.ts`)** ```typescript import { IdValueObject } from '../value-objects/id.value-object' export class MyAppEntity { constructor( public readonly id: IdValueObject, public readonly name: string, public readonly description?: string ) {} static create(name: string, description?: string) { return new MyAppEntity( IdValueObject.generate(), name, description ) } } ``` **Value Object (`domain/value-objects/id.value-object.ts`)** ```typescript import { v4 as uuidv4 } from 'uuid' export class IdValueObject { constructor(private readonly value: string) { if (!this.isValid(value)) { throw new Error('Invalid ID format') } } static generate(): IdValueObject { return new IdValueObject(uuidv4()) } toString(): string { return this.value } private isValid(value: string): boolean { // UUID validation logic return true } } ``` ### Infrastructure Layer **Controller (`infrastructure/controllers/my-app.controller.ts`)** ```typescript import { Controller, Get, Post } from '@eyjs/http-server' import { MyAppService } from '../../application/services/my-app.service' import { CreateMyAppDto } from '../../application/dtos/create-my-app.dto' @Controller('/my-app') export class MyAppController { constructor(private readonly service: MyAppService) {} @Post() async create(dto: CreateMyAppDto) { return await this.service.create(dto) } @Get('/:id') async findById(id: string) { return await this.service.findById(id) } } ``` **Repository (`infrastructure/repositories/my-app-mongo.repository.ts`)** ```typescript import { Injectable } from '@eyjs/core' import { MyAppRepository } from '../../domain/interfaces/my-app.repository.interface' import { MyAppEntity } from '../../domain/entities/my-app.entity' @Injectable() export class MyAppMongoRepository implements MyAppRepository { async save(entity: MyAppEntity): Promise<void> { // MongoDB implementation } async findById(id: string): Promise<MyAppEntity | null> { // MongoDB find implementation } } ``` ## Configuration Files ### Package.json ```json { "name": "my-app", "version": "1.0.0", "type": "module", "scripts": { "dev": "bun run --watch src/index.ts", "build": "tsc", "start": "bun run src/index.ts", "test": "bun test" }, "dependencies": { "@eyjs/core": "^1.0.4" }, "devDependencies": { "@types/node": "^20.0.0", "typescript": "^5.0.0" } } ``` ### TypeScript Configuration ```json { "compilerOptions": { "target": "ES2022", "module": "ESNext", "moduleResolution": "node", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "baseUrl": ".", "paths": { "@/*": ["./src/*"], "@/application/*": ["./src/application/*"], "@/domain/*": ["./src/domain/*"], "@/infrastructure/*": ["./src/infrastructure/*"] } }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] } ``` ## Usage Examples ### Creating Different Types of Applications ```bash # REST API create-eyjs-app user-api --template api # Web Application create-eyjs-app ecommerce-web --template web # Microservice create-eyjs-app notification-service --template microservice ``` ### Custom Directory Structure ```bash # Create in specific path create-eyjs-app my-app --path ./backend-services # Result: ./backend-services/my-app/ ``` ### Skip Installation ```bash # Generate files without installing dependencies create-eyjs-app my-app --skip-install ``` ## Integration with EyJS The generated applications are fully compatible with the EyJS ecosystem: ```typescript // Generated app automatically includes EyJS core import { EyJs } from '@eyjs/core' // Dependency injection works out of the box @Injectable() export class MyService { // Auto-injected dependencies } // HTTP server integration import { Controller, Get } from '@eyjs/http-server' @Controller('/api') export class ApiController { // HTTP endpoints } ``` ## Best Practices ### Domain-Driven Design - Keep business logic in the domain layer - Use value objects for complex data types - Implement domain events for side effects ### Clean Architecture - Dependencies point inward (toward domain) - Use interfaces for external dependencies - Keep infrastructure concerns separate ### Testing Strategy - Unit tests for domain logic - Integration tests for repositories - E2E tests for API endpoints ## Contributing Contributions are welcome! Please read our [Contributing Guide](https://github.com/elevenyellow/EyJS-core/blob/main/CONTRIBUTING.md) for details. ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## Support - šŸ“– [Documentation](https://github.com/elevenyellow/EyJS-core#readme) - šŸ› [Issue Tracker](https://github.com/elevenyellow/EyJS-core/issues) - šŸ’¬ [Discussions](https://github.com/elevenyellow/EyJS-core/discussions)