Skip to content

Commit ff584db

Browse files
committed
fix: update test
1 parent 4e116f9 commit ff584db

12 files changed

Lines changed: 160 additions & 80 deletions

File tree

CONTRIBUTING.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Contributing Guide
2+
3+
## How to Contribute
4+
5+
1. Fork this repository
6+
2. Create your feature branch:
7+
git checkout -b feature/your-feature-name
8+
3. Commit your changes:
9+
git commit -m "feat: add new feature"
10+
4. Push to your branch
11+
5. Open a Pull Request
12+
13+
## Code Style
14+
15+
- Follow existing code structure
16+
- Use consistent naming conventions
17+
- Write clean and readable code
18+
19+
## Commit Convention
20+
21+
- feat: new feature
22+
- fix: bug fix
23+
- docs: documentation
24+
- refactor: code improvement

README.md

Lines changed: 112 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
<div align="center">
2-
<h1>🚀 Node Module Generator</h1>
3-
<p>A robust CLI tool for scaffolding Express.js projects using Clean Architecture & Dependency Injection.</p>
2+
<img src="https://raw.githubusercontent.com/saul-paulus/node-module-generator/main/assets/banner.png" alt="Node Module Generator Banner" width="600" style="max-width: 100%;" />
3+
<h1>🚀 Node Module Generator (NMG)</h1>
4+
<p><strong>The ultimate CLI companion for rapid, enterprise-grade Node.js scaffolding.</strong></p>
45
<p>
56
<a href="https://github.com/saul-paulus/node-module-generator/actions/workflows/ci.yml">
67
<img src="https://github.com/saul-paulus/node-module-generator/actions/workflows/ci.yml/badge.svg" alt="CI Status">
78
</a>
89
<a href="https://www.npmjs.com/package/@saulpaulus17/node-module-generator">
9-
<img src="https://img.shields.io/npm/v/@saulpaulus17/node-module-generator.svg" alt="NPM Version" />
10+
<img src="https://img.shields.io/npm/v/@saulpaulus17/node-module-generator.svg?logo=npm&logoColor=white" alt="NPM Version" />
1011
</a>
1112
<a href="https://www.npmjs.com/package/@saulpaulus17/node-module-generator">
12-
<img src="https://img.shields.io/npm/dt/@saulpaulus17/node-module-generator.svg" alt="NPM Downloads" />
13+
<img src="https://img.shields.io/npm/dt/@saulpaulus17/node-module-generator.svg?logo=npm&logoColor=white" alt="NPM Downloads" />
1314
</a>
1415
<a href="https://github.com/saul-paulus/node-module-generator/blob/main/LICENSE">
1516
<img src="https://img.shields.io/npm/l/@saulpaulus17/node-module-generator.svg" alt="License" />
@@ -19,107 +20,147 @@
1920

2021
---
2122

22-
## 📖 Overview
23+
## 🏛️ Architecture Overview
24+
25+
Node Module Generator (NMG) enforces **Clean Architecture** principles to ensure your backend remains scalable, testable, and decoupled. It is purpose-built for high-performance **Express.js** environments using **Awilix** for Dependency Injection.
26+
27+
### Layered Structure
28+
```mermaid
29+
graph TD
30+
UI[Interfaces Layer: Controllers & Routes] --> APP[Application Layer: Use Cases & DTOs]
31+
APP --> DOM[Domain Layer: Entities & Repository Interfaces]
32+
INF[Infrastructure Layer: Repository Impl & External Services] --> DOM
33+
34+
subgraph "Inner Layers"
35+
DOM
36+
APP
37+
end
38+
39+
subgraph "Outer Layers"
40+
UI
41+
INF
42+
end
43+
```
2344

24-
**Node Module Generator** provides a world-class Developer Experience (DX) equivalent to the robust CLIs found in ecosystems like NestJS or Angular, but designed specifically for pure Node.js environments utilizing **Express.js** and **Clean Architecture**.
45+
---
2546

26-
It instantly scaffolds fully-tested, decoupled, and highly cohesive module structures with built-in Dependency Injection using **Awilix**.
47+
## 🔥 Key Features
2748

28-
## ✨ Features
49+
- 💎 **Clean Architecture by Design**: Strict separation into Domain, Application, Infrastructure, and Interface layers.
50+
- 💉 **Native Dependency Injection**: Fully pre-configured for **Awilix**, providing seamless DI management.
51+
- 🧪 **Test-Ready Scaffolding**: Automatically generates **Jest** test suites for Controllers and Use Cases.
52+
- 🚀 **Modern Tooling**: Native support for **ES Modules (ESM)**, **Prisma ORM**, and **Joi/Zod** DTO patterns.
53+
- 🤖 **Granular Control**: Generate full modules or individual components (UseCases, Repos, DTOs) without disrupting existing code.
2954

30-
- 🏗️ **Clean Architecture by Default**: Automatically separates concerns into Domain, Application, Infrastructure, and Interface layers.
31-
- 💉 **Dependency Injection Ready**: Auto-generates Awilix configurations mapped correctly across use cases, controllers, and repositories.
32-
- 🧪 **Test-Driven Design**: Scaffolds adjoining `*.test.js` files containing boilerplates for Jest to promote TDD.
33-
- 🤖 **Continuous Integration**: Codebase natively incorporates GitHub Actions for automated unit testing checks.
34-
- 🧩 **Granular Scaffolding**: Generate specific components (UseCases, Repositories, DTOs) dynamically on demand without overriding existing folders!
55+
---
3556

3657
## 📦 Installation
3758

3859
### Prerequisites
39-
- **Node.js**: v18.0.0 or higher.
40-
- **NPM** or **Yarn**.
60+
- **Node.js**: v18.0.0 or higher (LTS recommended)
61+
- **NPM**, **Yarn**, or **PNPM**
4162

42-
To use this CLI tool locally or globally on your machine, you can install it directly from NPM.
63+
### Global Installation (Recommended)
64+
Install NMG globally to access the command from any project.
4365

4466
```bash
45-
# Install globally via NPM
4667
npm install -g @saulpaulus17/node-module-generator
4768
```
4869

49-
## 🚀 Usage
70+
### Direct Execution
71+
Run it on-the-fly without a permanent installation:
5072

51-
Once installed globally, you can execute the CLI commands from any of your Node.js project directories using the `nmg` command keyword.
73+
```bash
74+
npx @saulpaulus17/node-module-generator <command> <name>
75+
```
5276

53-
### Granular CLI Commands
54-
Scaffold specifically what you need, exactly how you do it in NestJS:
77+
---
5578

56-
```bash
57-
# 1. Scaffolds a new module architecture and empty DI registry
58-
nmg module product
79+
## 🚀 Detailed Usage
5980

81+
### 1. Generating a Full Module
82+
Scaffolds a complete standard architecture with all 4 layers and initial unit tests.
6083

61-
# 2. Creates a specific Use Case and its Test inside an existing module
62-
nmg usecase updateProduct --module=product
84+
```bash
85+
nmg module Auth
86+
```
6387

64-
# 3. Creates Domain Entity and Repository Interfaces/Implementations
65-
nmg repository product
88+
### 2. Generating Individual Components
89+
Quickly add specific components to an existing module structure.
90+
91+
```bash
92+
# Add a new UseCase (e.g., login) to the Auth module
93+
nmg usecase login --module=Auth
6694

67-
# 4. Scaffolds a DTO validation schema
68-
nmg dto getProduct --module=product
95+
# Add a Repository Interface and Implementation (Prisma)
96+
nmg repository User
6997

70-
# 5. Generates an entire full-stack CRUD Resource (Controller, Entity, Repos, DI, etc.)
71-
nmg resource order
98+
# Add a DTO validation schema
99+
nmg dto userRegistration --module=Auth
72100
```
73101

74-
_(Note: If you haven't installed the package globally, you can run it via `npx @saulpaulus17/node-module-generator <command> <name>`)_
102+
---
75103

76-
## 📂 Full Resource Structure
104+
## 📂 Project Blueprint
77105

78-
Running the powerhouse command `nmg resource user` instantly generates the following decoupled blueprint within your project's `src/modules` directory:
106+
Scaffolding a module (e.g., `nmg module Product`) produces the following industry-standard structure:
79107

80108
```text
81-
src/modules/user/
82-
├── application/ # Orchestration & Use Cases
83-
│ ├── dtos/ # (Generated schema references)
84-
│ └── usecases/
85-
│ ├── create-user.usecase.js # Business logically perfectly isolated
86-
│ └── create-user.usecase.test.js # Scaffolded test harness
87-
├── domain/ # Blueprints & Business Rules (Pure Logic)
88-
│ ├── entities/
89-
│ │ └── user.entity.js
90-
│ └── repositories/ # Repository Interfaces (Contracts)
91-
│ └── user.repository.interface.js
92-
├── infrastructure/ # Technical Details & Implementation
93-
│ ├── repositories/ # Implementations (mocked to replace with Prisma/TypeORM)
94-
│ │ └── user.repository.impl.js
95-
│ └── validation/ # Input validation schemas
96-
│ └── create-user.schema.js # Auto-stubbed validation schema
97-
├── interfaces/ # Entry Points (Web/API)
98-
│ ├── controllers/
99-
│ │ ├── user.controller.js # Express.js class handlers
100-
│ │ └── user.controller.test.js
101-
│ └── routes/
102-
│ └── user.routes.js # Express routers integrating the controller
103-
└── user.module.js # Centralised Awilix Dependency Injection bindings
109+
src/modules/Product/
110+
├── application/
111+
│ ├── dtos/ # DTO schemas (e.g., product.dto.js)
112+
│ └── usecases/ # Business orchestration
113+
│ ├── ProductUseCase.js # Logic implementation
114+
│ └── ProductUseCase.test.js # Unit tests
115+
├── domain/
116+
│ ├── entities/ # Business entity definitions
117+
│ │ └── Product.js
118+
│ └── repositories/ # Repository Interface (Contracts)
119+
│ └── ProductRepository.js
120+
├── infrastructure/
121+
│ ├── repositories/ # Implementation (default: Prisma)
122+
│ │ └── PrismaProductRepository.js
123+
├── interfaces/
124+
│ ├── controllers/ # Express handlers
125+
│ │ ├── ProductController.js
126+
│ │ └── ProductController.test.js
127+
│ └── routes/ # Express routes & method binding
128+
│ └── product.routes.js
129+
└── Product.module.js # Central Awilix Module Registration
104130
```
105131

106-
## 🛠️ Technological Footprint
132+
---
133+
134+
## 🛠️ Post-Scaffolding Integration
107135

108-
The scaffolded code integrates perfectly if you are using the following libraries in your Express application:
136+
To finalize your new module integration, follow these standard steps:
109137

110-
- **[Express.js](https://expressjs.com/)** - Web Framework
111-
- **[Awilix](https://github.com/jeffijoe/awilix)** - Powerful Dependency Injection container
112-
- **[Jest](https://jestjs.io/)** - For the colocated testing environments
113-
- **[Joi](https://joi.dev/)** - For infrastructure schema validations
138+
1. **DI Registration**: Open `src/container.js` and register any specific repository aliases or scoped usecases.
139+
2. **Route Mounting**: Mount the generated router in `src/app.js`:
140+
```javascript
141+
app.use('/api/v1/product', container.resolve('productRoutes'));
142+
```
143+
3. **Detailed Implementation**: Build out the specific logic in the generated templates (which are already integrated via Awilix).
114144

115-
## 🤝 Contributing
145+
---
146+
147+
## 🤝 Contributing & Support
116148

117-
Contributions are always welcome! Feel free to open issues or submit Pull Requests.
118-
1. Fork the repo and create your branch (`git checkout -b feature/amazing-feature`).
119-
2. Commit your changes (`git commit -m 'feat: add amazing feature'`).
120-
3. Push to the branch (`git push origin feature/amazing-feature`).
121-
4. Open a Pull Request.
149+
We welcome contributions from the community!
150+
1. Fork the project.
151+
2. Create your Feature Branch (`git checkout -b feat/NewFeature`).
152+
3. Commit your changes (`git commit -m 'feat: Add some NewFeature'`).
153+
4. Push to the Branch (`git push origin feat/NewFeature`).
154+
5. Open a Pull Request.
155+
156+
---
122157

123158
## 📝 License
124159

125-
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
160+
Distributed under the **MIT License**. See `LICENSE` for more information.
161+
162+
---
163+
<div align="center">
164+
<p>Built with ❤️ for modern Node.js developers</p>
165+
<sub>Copyright © 2024 saul-paulus</sub>
166+
</div>

generator/module.generator.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ module.exports = async function (name) {
1919
// Create directories
2020
dirs.forEach((dir) => fs.ensureDirSync(path.join(basePath, dir)));
2121

22+
// Generate scoped package.json for ESM support
23+
fs.writeJsonSync(path.join(basePath, "package.json"), { type: "module" }, { spaces: 2 });
24+
2225
const templateData = {
2326
name,
2427
className: pascalCase(name),

generator/resource.generator.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ module.exports = async function (name) {
1818

1919
dirs.forEach((dir) => fs.ensureDirSync(path.join(basePath, dir)));
2020

21+
// Generate scoped package.json for ESM support
22+
fs.writeJsonSync(path.join(basePath, "package.json"), { type: "module" }, { spaces: 2 });
23+
2124
const templateData = {
2225
name,
2326
className: pascalCase(name),

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"nmg": "./bin/cli.js"
1717
},
1818
"scripts": {
19-
"test": "jest"
19+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
2020
},
2121
"dependencies": {
2222
"chalk": "^5.6.2",

src/modules/Auth/application/usecases/AuthUseCase.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export default class AuthUseCase {
66

77
async execute(inputData) {
88
// Logic for AuthUseCase
9-
return { success: true, data: inputData };
9+
const result = await this.authRepository.create(inputData);
10+
return { success: true, data: result };
1011
}
1112
}

src/modules/Auth/application/usecases/AuthUseCase.test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
const AuthUseCase = require('./AuthUseCase');
1+
import { jest, describe, it, expect, beforeEach } from '@jest/globals';
2+
import AuthUseCase from './AuthUseCase.js';
23

34
describe('AuthUseCase', () => {
45
let useCase;
@@ -23,7 +24,7 @@ describe('AuthUseCase', () => {
2324
const result = await useCase.execute(mockDto);
2425

2526
expect(mockRepository.create).toHaveBeenCalledWith(mockDto);
26-
expect(result).toEqual({ success: true, data: mockDto });
27+
expect(result).toEqual({ success: true, data: mockResult });
2728
});
2829
});
2930
});

src/modules/Auth/interfaces/controllers/AuthController.test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
const AuthController = require('./AuthController');
1+
import { jest, describe, it, expect, beforeEach } from '@jest/globals';
2+
import AuthController from './AuthController.js';
23

34
describe('AuthController', () => {
45
let controller;

src/modules/Auth/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"type": "module"
3+
}

templates/module/controller.test.ejs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
const <%= className %>Controller = require('./<%= className %>Controller');
1+
import { jest, describe, it, expect, beforeEach } from '@jest/globals';
2+
import <%= className %>Controller from './<%= className %>Controller.js';
23

34
describe('<%= className %>Controller', () => {
45
let controller;

0 commit comments

Comments
 (0)