Skip to content
Draft
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4363730
chore: update Node.js version to 20 in configuration files
devalexanderdaza Jun 28, 2025
aef0314
chore(deps): updated dependencies to latest compatible versions
devalexanderdaza Jun 28, 2025
7569f30
feat: improve API documentation and validation for greeter service
devalexanderdaza Jun 28, 2025
f471e61
feat: add IRepository interface with CRUD and aggregation methods
devalexanderdaza Jun 28, 2025
30a82a5
feat: implement product creation and retrieval endpoints with in-memo…
devalexanderdaza Jun 28, 2025
ca108c5
feat: update welcomeName in index.html to reflect new user
devalexanderdaza Jun 28, 2025
44b215f
Revert "feat: update welcomeName in index.html to reflect new user"
devalexanderdaza Jun 28, 2025
a77974f
feat: add product service and repository with basic actions and tests
devalexanderdaza Jun 28, 2025
c8af88f
feat: refactor validation logic and reorganize repository interfaces
devalexanderdaza Jun 28, 2025
06d7cf6
feat: add validation and improve API response structure for service a…
devalexanderdaza Jun 28, 2025
ca348c1
feat: add generate:dto script for creating new DTOs with Hygen and up…
devalexanderdaza Jun 28, 2025
e987de5
Merge branch 'develop'
devalexanderdaza Jun 28, 2025
37576cb
fix: update services/greeter.service.ts
devalexanderdaza Jun 28, 2025
e893d2f
chore: remove unused
jellydn Jun 29, 2025
bb66019
chore: Update text on services/product/product.service.ts
devalexanderdaza Jul 3, 2025
e1e03fc
fix: correct schema definition for DTO generation in hello.ejs.t
devalexanderdaza Jul 3, 2025
7b9ce80
fix: add repository to ServiceThis type and update context in create …
devalexanderdaza Jul 3, 2025
af15210
fix: update log message for parameter validation in welcome action
devalexanderdaza Jul 3, 2025
0782c42
fix: update comments for repository interface and product service for…
devalexanderdaza Jul 3, 2025
ef18ca7
fix: add error handling for YAML file generation in hello.ejs.t
devalexanderdaza Jul 3, 2025
f49c5f1
fix: update import statement for consistency in product.service.ts
devalexanderdaza Jul 3, 2025
64f20a2
fix: add error handling for product repository initialization in prod…
devalexanderdaza Jul 3, 2025
ad17261
fix: improve parameter validation for list action using zod schema
devalexanderdaza Jul 3, 2025
6da4130
fix: enhance validation for list parameters with detailed error messages
devalexanderdaza Jul 3, 2025
8723d8b
fix: update Node.js version requirement in README and refactor produc…
devalexanderdaza Jul 3, 2025
fb7095a
fix: update package.json to use pnpm for swagger generation and SDK t…
devalexanderdaza Jul 3, 2025
287f38b
fix: add @vitest/coverage-v8 dependency for improved test coverage re…
devalexanderdaza Jul 3, 2025
edcb367
Initial plan
Copilot Jul 9, 2025
ad98325
Merge pull request #1 from devalexanderdaza/copilot/fix-8e337501-87be…
devalexanderdaza Jul 9, 2025
87a5211
Merge pull request #2 from devalexanderdaza/develop
devalexanderdaza Jul 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: ⎔ Setup node
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20

- name: 📥 Install pnpm
run: npm install -g pnpm
Expand All @@ -44,7 +44,7 @@ jobs:
- name: ⎔ Setup node
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20

- name: 📥 Install pnpm
run: npm install -g pnpm
Expand All @@ -68,7 +68,7 @@ jobs:
- name: ⎔ Setup node
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20

- name: 📥 Install pnpm
run: npm install -g pnpm
Expand Down
5 changes: 5 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"pavittarx.moleculer-snippets"
]
}
197 changes: 190 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Welcome to moleculer-typescript-template 👋

![Version](https://img.shields.io/badge/version-0.1.1-blue.svg?cacheSeconds=2592000)
![Version](https://img.shields.io/badge/version-0.3.0-blue.svg?cacheSeconds=2592000)
![Prerequisite](https://img.shields.io/badge/node-%3E%3D%2014.x.x-blue.svg)
[![Twitter: jellydn](https://img.shields.io/twitter/follow/jellydn.svg?style=social)](https://twitter.com/jellydn)

Expand All @@ -18,7 +18,7 @@

## Prerequisites

- node >= 18.17.x
- node >= 20.0.0

## Init new project

Expand All @@ -36,6 +36,10 @@ npx degit jellydn/moleculer-typescript-template [PROJECT-NAME]
- ✨ [moleculer-zod-validator](https://github.com/TheAppleFreak/moleculer-zod-validator) - A validator for the Moleculer microservice framework to allow the use of [Zod](https://zod.dev/).
- 🔏 [asteasolutions/zod-to-openapi](https://github.com/asteasolutions/zod-to-openapi#defining-schemas) - A library that generates OpenAPI (Swagger) docs from Zod schemas.
- 🪄 [hey-api/openapi-ts](https://github.com/hey-api/openapi-ts) - Turn your OpenAPI specification into a beautiful TypeScript client.
- 🔐 **Enhanced Validation** - Shared validation utilities with Zod schemas for consistent parameter validation across all services.
- 📝 **Comprehensive Documentation** - Auto-generated Swagger documentation with complete error handling (200, 422, 500 responses).
- 🎯 **Type Safety** - Strong TypeScript typing throughout the application with proper service interfaces.
- 📊 **Structured Responses** - Consistent JSON response format with `success`, `message`, and `data` fields.

## Install

Expand All @@ -51,7 +55,7 @@ cp .env.example .env
pnpm dev
```

After starting, open the http://localhost:3000/ URL in your browser.
After starting, open the <http://localhost:3000/> URL in your browser.
On the welcome page you can test the generated services via API Gateway and check the nodes & services.
![https://gyazo.com/c8a8c8b05319504d36922458d9807db2.gif](https://gyazo.com/c8a8c8b05319504d36922458d9807db2.gif)

Expand All @@ -72,6 +76,17 @@ In the terminal, try the following commands:

This project uses [hygen](http://www.hygen.io/) to generate code templates, saving you time and ensuring consistency across your codebase.

## Code Generation

All generated templates include modern best practices:

- ✅ **Automatic validation** with shared `validateParams` utility
- ✅ **Complete Swagger documentation** with error responses
- ✅ **Strong TypeScript typing** with proper service interfaces
- ✅ **Structured JSON responses** with consistent format
- ✅ **Validation hooks** for all actions
- ✅ **Comprehensive logging** throughout the application

### Adding a New Service

To add a new service to your project, use the following command:
Expand All @@ -80,6 +95,14 @@ To add a new service to your project, use the following command:
pnpm generate:service [service-name]
```

This generates a basic service with:

- Two sample actions (`hello` and `welcome`)
- Validation hooks with `validateParams` integration
- Complete Swagger documentation
- Strong TypeScript typing
- Structured error handling

### Adding a New Action to a Service

To add a new action to an existing service, use the following command:
Expand All @@ -88,6 +111,13 @@ To add a new action to an existing service, use the following command:
pnpm generate:action [action-name] --service [service-name]
```

Generated actions include:

- Parameter validation with Zod schemas
- Complete Swagger documentation with error codes
- Structured JSON response format
- TypeScript interfaces for parameters and responses

### Generating CRUD Services

To generate a service with Create, Read, Update, and Delete (CRUD) operations, use the following command:
Expand All @@ -96,6 +126,150 @@ To generate a service with Create, Read, Update, and Delete (CRUD) operations, u
pnpm generate:crud [service-name]
```

This creates a complete CRUD service with:

- **5 actions**: `create`, `list`, `view`, `update`, `delete`
- **Pagination support** in list actions
- **Validation hooks** in all actions
- **Complete Swagger documentation** for all endpoints
- **Structured responses** with success/error handling
- **Authentication** and **authorization** ready

### Generating Data Transfer Objects (DTOs)

To generate Zod schemas with OpenAPI documentation, use:

```sh
pnpm generate:dto [dto-name]
```

This generates:

- **Zod schemas** with OpenAPI annotations
- **Automatic YAML generation** for Swagger integration
- **Type-safe validation** for request/response data
- **Reusable schemas** across services

## Enhanced Template Features

### 🔐 Automatic Parameter Validation

All generated actions include automatic parameter validation using Zod schemas:

```typescript
// Generated validation hook in every action
hooks: {
before(ctx) {
this.logger.info('Validating parameters for [action] action');
validateParams(ctx, yourSchema); // Automatically included
},
}
```

### 📖 Complete Swagger Documentation

Every generated action includes comprehensive Swagger documentation:

- **Request/Response schemas** with examples
- **Error response codes** (422 for validation, 500 for server errors)
- **Parameter descriptions** and constraints
- **Security requirements** for protected endpoints

### 🎯 Type-Safe Development

All templates generate strongly-typed TypeScript code:

- **Service interfaces** with proper method signatures
- **Context typing** for action parameters
- **Response type definitions** for consistent returns
- **Generic repository interfaces** for data access

### 📊 Structured JSON Responses

Consistent response format across all services:

```json
{
"success": true,
"message": "Operation completed successfully",
"data": {},
"pagination": {
"page": 1,
"limit": 10,
"total": 0
}
}
```

## Architecture & Patterns

This template implements several architectural patterns and best practices:

### Shared Validation Utilities

All services use a shared validation utility (`services/common/validation.utils.ts`) that provides:

- **Consistent validation** across all services
- **Zod schema integration** with Moleculer context
- **Automatic error handling** with structured error responses
- **TypeScript type safety** for validation parameters

```typescript
// Usage in any service action
hooks: {
before(ctx) {
validateParams(ctx, yourZodSchema);
},
}
```

### Structured Response Format

All actions return a consistent JSON structure:

```typescript
// Success Response
{
"success": true,
"message": "Operation completed successfully",
"data": { /* your data here */ }
}

// Error Response
{
"error": "Parameters validation error!",
"code": "VALIDATION_ERROR"
}
```

### Repository Pattern

The template includes an example repository pattern implementation for data access:

- **Interface-based design** for easy testing and swapping implementations
- **Type-safe operations** with TypeScript
- **Separation of concerns** between business logic and data access

### Service Organization

Services are organized with a clear structure:

```text
services/
├── common/ # Shared utilities and interfaces
│ ├── index.ts
│ ├── validation.utils.ts
│ └── repository.interface.ts
├── dtos/ # Data Transfer Objects with Zod schemas
│ ├── [name].dto.ts
│ └── [name]-dto.swagger.yaml
└── [service]/ # Individual service folders
├── [service].service.ts
├── [service].repository.ts
└── actions/ # Action implementations
└── [action].action.ts
```

## API Documentation

This template also reads your [JSDoc-annotated](https://github.com/Surnet/swagger-jsdoc/blob/v6/docs/README.md) source code and generates an OpenAPI (Swagger) specification.
Expand All @@ -106,7 +280,7 @@ Run the following command to generate the Swagger documentation:
pnpm generate:swagger
```

Open the http://localhost:3000/docs URL in your browser, you will see the Swagger UI as
Open the <http://localhost:3000/docs> URL in your browser, you will see the Swagger UI as

![https://gyazo.com/a4fe2413414c94dde636a531eee1a4a0.gif](https://gyazo.com/a4fe2413414c94dde636a531eee1a4a0.gif)

Expand Down Expand Up @@ -149,8 +323,8 @@ We use GitHub Actions for continuous integration and deployment. Anything that g

## Useful links

- Moleculer website: https://moleculer.services/
- Moleculer Documentation: https://moleculer.services/docs/0.14/
- Moleculer website: <https://moleculer.services/>
- Moleculer Documentation: <https://moleculer.services/docs/0.14/>

## NPM scripts

Expand All @@ -162,6 +336,15 @@ We use GitHub Actions for continuous integration and deployment. Anything that g
- `pnpm dc:up`: Start the stack with Docker Compose
- `pnpm dc:down`: Stop the stack with Docker Compose

### Code Generation Scripts

- `pnpm generate:service [name]`: Generate a new basic service with validation and documentation
- `pnpm generate:crud [name]`: Generate a complete CRUD service with all operations
- `pnpm generate:action [name] --service [service]`: Add a new action to an existing service
- `pnpm generate:dto [name]`: Generate Zod schemas with OpenAPI documentation
- `pnpm generate:swagger`: Generate OpenAPI documentation from JSDoc comments
- `pnpm generate:sdk`: Generate TypeScript client from OpenAPI specification

## Pre-commit hooks

This template uses [Pre-commit](https://pre-commit.com/) to run checks before you commit your code. This ensures that your code is formatted correctly and passes all tests before you push it to your repository.
Expand All @@ -180,7 +363,7 @@ pre-commit run --all-files

👤 **Dung Huynh**

- Website: https://productsway.com/
- Website: <https://productsway.com/>
- Twitter: [@jellydn](https://twitter.com/jellydn)
- Github: [@jellydn](https://github.com/jellydn)

Expand Down
43 changes: 36 additions & 7 deletions _templates/action/new/hello.ejs.t
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
to: services/<%= service %>/actions/<%= name %>.action.ts
---
import type { Context, ServiceActionsSchema } from "moleculer";
import { validateParams } from "../../common";

/**
* The <%= name %> action.
*
* @swagger
* /welcome:
* /api/<%= service %>/<%= name %>:
* get:
* summary: Returns a greeting and calculates the age in days.
* tags:
* - <%= service %>
* parameters:
* - in: query
* name: name
Expand All @@ -27,20 +30,43 @@ import type { Context, ServiceActionsSchema } from "moleculer";
* 200:
* description: A greeting message and the age in days.
* content:
* text/plain:
* application/json:
* schema:
* type: string
* example: "Hello John, you are 10950 days old!"
* type: object
* properties:
* message:
* type: string
* example: "Hello John, you are 10950 days old!"
* success:
* type: boolean
* example: true
* 422:
* description: Validation error
* content:
* application/json:
* schema:
* type: object
* properties:
* error:
* type: string
* example: Parameters validation error!
*/
const <%= name %>Action: ServiceActionsSchema = {
rest: {
method: "GET",
path: "/welcome",
path: "/<%= name %>",
},
params: {
name: "string",
age: "number",
},
hooks: {
before(ctx) {
this.logger.info('Validating parameters for <%= name %> action');
// Add your validation schema here
// validateParams(ctx, your<%= h.capitalize(name) %>Schema);
},
},
handler: <%= name %>Handler,
};

Expand All @@ -52,11 +78,14 @@ function <%= name %>Handler(
name: string;
age: number;
}>,
): string {
): { message: string; success: boolean } {
// Calculate the age in days
const ageInDays = ctx.params.age * 365;

return `Hello ${ctx.params.name}, you are ${ageInDays} days old!`;
return {
message: `Hello ${ctx.params.name}, you are ${ageInDays} days old!`,
success: true,
};
}

export default <%= name %>Action;
Expand Down
Loading
Loading