https://github.com/nigussolomon/nest-util
Supercharge NestJS development with a generic CRUD engine, automated CLI generator (ncnu), and essential utilities. Features deep TypeORM integration, automated Swagger/OpenAPI documentation, and rapid boilerplate generation.
https://github.com/nigussolomon/nest-util
automation backend boiler cli crud generator ncnu nest-util nestjs openapi swagger typeorm typescript
Last synced: 3 months ago
JSON representation
Supercharge NestJS development with a generic CRUD engine, automated CLI generator (ncnu), and essential utilities. Features deep TypeORM integration, automated Swagger/OpenAPI documentation, and rapid boilerplate generation.
- Host: GitHub
- URL: https://github.com/nigussolomon/nest-util
- Owner: nigussolomon
- Created: 2026-02-05T06:35:43.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-04-11T12:50:03.000Z (3 months ago)
- Last Synced: 2026-04-11T14:15:48.206Z (3 months ago)
- Topics: automation, backend, boiler, cli, crud, generator, ncnu, nest-util, nestjs, openapi, swagger, typeorm, typescript
- Language: TypeScript
- Homepage: https://nigussolomon.github.io/nest-util/
- Size: 738 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Nest Util



[](https://github.com/nigussolomon/nest-util/actions/workflows/ci.yml)
[](https://github.com/nigussolomon/nest-util/actions/workflows/security.yml)
[](https://github.com/nigussolomon/nest-util/actions/workflows/deploy-docs.yml)
[](https://github.com/nigussolomon/nest-util/actions/workflows/publish.yml)
**A modern, production-ready collection of NestJS utilities designed to accelerate development by providing reusable, battle-tested patterns for CRUD operations, authentication, and rapid code generation.**
📖 **[Docs Index](./docs/README.md)** | 🚀 **[Quick Start](#-quick-start)** | ⚙️ **[demo-api config](./docs/demo-api/README.md)**
---
## 🎯 What is Nest-Util?
Nest-Util is a comprehensive toolkit that eliminates boilerplate and accelerates NestJS development. Instead of writing repetitive CRUD logic, authentication flows, and entity scaffolding for every project, Nest-Util provides:
- **Production-Ready Components**: Battle-tested services, controllers, and modules that handle common patterns
- **Type-Safe Code Generation**: CLI tool that generates fully-typed entities, DTOs, services, and controllers
- **Flexible Authentication**: Dynamic auth system that adapts to your schema without forcing a specific user model
- **Built-in Best Practices**: Automatic pagination, filtering, Swagger documentation, and error handling
### Why Nest-Util?
| Problem | Nest-Util Solution |
| --------------------------------------------- | -------------------------------------------------------------------- |
| Writing the same CRUD logic for every entity | `@nest-util/nest-crud` - Generic CRUD service and controller factory |
| Manually scaffolding entities, DTOs, services | `ncnu` - Code generator with smart type mapping |
| Implementing secure JWT authentication | `@nest-util/nest-auth` - Flexible auth module with token rotation |
| Tracking entity-level mutations | `@nest-util/nest-audit` - Audit logs for create/update/delete flows |
| Inconsistent API responses | Built-in response interceptors and transformers |
| Manual Swagger documentation | Automatic OpenAPI documentation with proper decorators |
---
## 🏗️ Architecture Overview
Nest-Util is composed of focused modules that integrate into the same NestJS app.
**Architecture Components:**
- `ncnu`: generates entities, DTOs, services, and controllers
- `@nest-util/nest-crud`: provides reusable CRUD service/controller building blocks
- `@nest-util/nest-auth`: handles JWT auth, refresh tokens, and permissions
- `@nest-util/nest-audit`: records audit events for mutating operations
- `TypeORM + Database`: persistence layer used by all runtime modules
### Integration Flow
1. Configure TypeORM and entity loading.
2. Add `NestUtilNestAuditModule`.
3. Add `AuthModule.forRoot(...)`.
4. Build services with `NestCrudService`.
5. Build controllers with `CreateNestedCrudController(...)`.
6. Configure `main.ts` globals (validation pipe, query parser, Swagger, DB exception filter).
**Typical Workflow:**
1. Use `ncnu` to generate entities, DTOs, services, and controllers
2. Generated code automatically extends `NestCrudService` and `CreateNestedCrudController`
3. Add `@nest-util/nest-auth` for authentication on protected routes
4. Enable `@nest-util/nest-audit` interceptor for mutation logging
5. Get automatic pagination, filtering, Swagger docs, and error handling
---
## 🚀 Key Features
### 1. 📦 @nest-util/nest-crud
A powerful and flexible CRUD library featuring:
- **`NestCrudService`**: Generic base service for common TypeORM operations with built-in filtering and pagination
- **`CreateNestedCrudController`**: Controller factory that generates fully-functional REST endpoints
- **`IBaseController`**: TypeScript interface for proper type inference
- **Advanced Filtering**: Query-based filtering with operators like `eq`, `cont`, `gte`, `lte`
- **Automatic Pagination**: Out-of-the-box support for page-based and limit-offset pagination
- **Swagger Integration**: Automatic OpenAPI documentation with proper schemas
- **Response Interceptors**: Consistent API response format with metadata
**Key Capabilities:**
- ✅ Type-safe CRUD operations
- ✅ Dynamic query filtering (`?filter[name_cont]=john&filter[age_gte]=18`)
- ✅ Automatic Swagger documentation
- ✅ Global exception handling for database errors
- ✅ Extensible architecture for custom business logic
### 2. 🛠️ ncnu (NestJS CRUD Generator)
A professional code generation CLI tool to scaffold your NestJS resources:
- **Rapid Prototyping**: Generate Entity, Service, Controller, and DTOs in seconds
- **Smart Type Mapping**: Automatically handles TypeORM column types and Swagger decorators
- **Definite Assignment**: Generates code compatible with strict TypeScript property initialization
- **Organized Structure**: Creates dedicated folders with all necessary files
- **Production Ready**: Generated code includes proper imports, decorators, and type annotations
**What Gets Generated:**
- `{model}.entity.ts` - TypeORM entity with proper column decorators
- `create-{model}.dto.ts` - DTO for creation with validation decorators
- `update-{model}.dto.ts` - DTO for updates with optional fields
- `{model}.service.ts` - Service extending `NestCrudService`
- `{model}.controller.ts` - Controller extending `CreateNestedCrudController`
### 3. 🔐 @nest-util/nest-auth
A dynamic and flexible authentication library:
- **`AuthModule`**: Dynamic configuration for entities, fields, and JWT settings
- **`AuthService`**: Built-in registration and login with bcrypt hashing
- **Token Security**: Refresh token rotation with nonce-based validation
- **Custom Decorators**: `@Public()`, `@CurrentUser()`, `@AuthOptions()`
- **Flexible DTOs**: Bring your own DTOs for full control over validation and documentation
- **Route Control**: Enable/disable auth endpoints via configuration
**Security Features:**
- ✅ JWT access and refresh token rotation
- ✅ Bcrypt password hashing
- ✅ Single-use refresh tokens with nonce validation
- ✅ Automatic token invalidation on refresh
- ✅ No sensitive data in auth responses
- ✅ Configurable token expiration
## 🛠️ Installation
### Prerequisites
- **Node.js**: v18 or higher
- **pnpm** (recommended) or npm
- **PostgreSQL** (or your preferred database)
- **NestJS**: v10+
- **TypeORM**: v0.3+
### Installing Libraries
Install the packages directly from GitHub releases:
```bash
# Install nest-crud library
pnpm add https://github.com/nigussolomon/nest-util/releases/download/latest/nest-util-nest-crud-0.0.1.tgz
# Install nest-auth library
pnpm add https://github.com/nigussolomon/nest-util/releases/download/latest/nest-util-nest-auth-0.0.1.tgz
# Required peer/runtime dependencies
pnpm add @nestjs/typeorm typeorm @nestjs/passport passport passport-jwt @nestjs/jwt bcrypt
pnpm add -D @types/passport-jwt @types/bcrypt
```
### Installing the Code Generator
Install `ncnu` globally for easy access:
```bash
# Global installation
pnpm add -g https://github.com/nigussolomon/nest-util/releases/download/latest/ncnu-0.0.1.tgz
# Verify installation
ncnu --help
```
Alternatively, use with `npx`:
```bash
npx https://github.com/nigussolomon/nest-util/releases/download/latest/ncnu-0.0.1.tgz --gen User --path ./src/app email:string
```
---
## ⚡ Quick Start
### Step 1: Generate Your First Resource
Use the `ncnu` CLI to scaffold a complete CRUD resource:
```bash
ncnu --gen Post --path apps/my-api/src/app \
title:string \
content:string \
published:boolean \
publishedAt:date \
authorId:number
```
This generates:
```
apps/my-api/src/app/post/
├── post.entity.ts
├── create-post.dto.ts
├── update-post.dto.ts
├── post.service.ts
└── post.controller.ts
```
### Step 2: Register the Module
Create a module for your resource:
```typescript
// apps/my-api/src/app/post/post.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PostController } from './post.controller';
import { PostService } from './post.service';
import { Post } from './post.entity';
@Module({
imports: [TypeOrmModule.forFeature([Post])],
controllers: [PostController],
providers: [PostService],
exports: [PostService],
})
export class PostModule {}
```
Import it in your `AppModule`:
```typescript
import { PostModule } from './post/post.module';
@Module({
imports: [
// ... other imports
PostModule,
],
})
export class AppModule {}
```
### Step 3: Configure Global Settings
For optimal functionality, add these global configurations in your `main.ts`:
```typescript
import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import { TypeOrmExceptionFilter } from '@nest-util/nest-crud';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app/app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Enable transformation and validation
app.useGlobalPipes(
new ValidationPipe({
transform: true,
enableImplicitConversion: true,
})
);
// Handle database errors gracefully
app.useGlobalFilters(new TypeOrmExceptionFilter());
// Configure query parser for complex filtering
const adapter = app.getHttpAdapter();
adapter.getInstance().set('query parser', 'extended');
// Setup Swagger documentation
const config = new DocumentBuilder()
.setTitle('My API')
.setDescription('API documentation')
.setVersion('1.0')
.addBearerAuth()
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api/docs', app, document);
await app.listen(3000);
}
bootstrap();
```
### Step 4: Test Your API
Your CRUD endpoints are now available:
```bash
# Create a post
curl -X POST http://localhost:3000/post \
-H "Content-Type: application/json" \
-d '{"title":"Hello","content":"World","published":true}'
# Get all posts with pagination
curl "http://localhost:3000/post?page=1&limit=10"
# Filter posts
curl "http://localhost:3000/post?filter[published_eq]=true&filter[title_cont]=Hello"
# Get one post
curl http://localhost:3000/post/1
# Update a post
curl -X PATCH http://localhost:3000/post/1 \
-H "Content-Type: application/json" \
-d '{"title":"Updated Title"}'
# Delete a post
curl -X DELETE http://localhost:3000/post/1
```
Visit `http://localhost:3000/api/docs` for interactive Swagger documentation!
---
## 🔐 Adding Authentication
### Step 1: Generate User Entity
```bash
ncnu --gen User --path apps/my-api/src/app \
email:string \
password:hash \
accessToken:hash \
refreshToken:hash
```
### Step 2: Configure AuthModule
```typescript
import { AuthModule } from '@nest-util/nest-auth';
import { User } from './user/user.entity';
import { LoginDto, RegisterDto, RefreshDto } from './auth/auth.dto';
@Module({
imports: [
AuthModule.forRoot({
userEntity: User,
identifierField: 'email',
passkeyField: 'password',
jwtSecret: process.env.JWT_SECRET || 'your-secret-key',
loginDto: LoginDto,
registerDto: RegisterDto,
refreshDto: RefreshDto,
accessTokenField: 'accessToken',
refreshTokenField: 'refreshToken',
}),
],
})
export class AppModule {}
```
### Step 3: Protect Routes
```typescript
import { JwtAuthGuard, CurrentUser, AuthUser } from '@nest-util/nest-auth';
@Controller('post')
@UseGuards(JwtAuthGuard) // Protect all routes
export class PostController
extends CreateNestedCrudController(CreatePostDto, UpdatePostDto, Post)
implements IBaseController
{
constructor(override readonly service: PostService) {
super(service);
}
// Access current user in custom endpoints
@Get('my-posts')
getMyPosts(@CurrentUser() user: AuthUser) {
return this.service.findAll({ filter: { authorId_eq: user.id } });
}
}
```
Authentication endpoints are now available:
- `POST /auth/register` - Create new user
- `POST /auth/login` - Login and get tokens
- `POST /auth/refresh` - Refresh access token
- `GET /auth/me` - Get current user profile
- `POST /auth/logout` - Logout (invalidate tokens)
---
## 🧑💻 Development
This workspace uses [Nx](https://nx.dev) for efficient monorepo management.
### Repository Setup
```bash
# Clone the repository
git clone https://github.com/nigussolomon/nest-util.git
cd nest-util
# Install dependencies
pnpm install
# Start the database (PostgreSQL via Docker)
./db.sh
# Run the demo API
npx nx serve demo-api
```
Explore the demo API at `http://localhost:3000/api/docs`
### Useful Commands
```bash
# View dependency graph
npx nx graph
# Lint a specific library
npx nx lint nest-crud
# Build all libraries
npx nx run-many -t build
# Run tests for a library
npx nx test nest-crud
# Run affected tests (only projects affected by changes)
npx nx affected -t test
# Type check all projects
npx nx run-many -t typecheck
```
---
## 📚 Advanced Features
### Custom Filtering
The CRUD system supports advanced filtering with various operators:
```typescript
// Filter by exact match
GET /post?filter[published_eq]=true
// Filter by contains (case-insensitive)
GET /post?filter[title_cont]=hello
// Filter by greater than or equal
GET /post?filter[views_gte]=100
// Filter by less than or equal
GET /post?filter[createdAt_lte]=2024-01-01
// Combine multiple filters
GET /post?filter[published_eq]=true&filter[views_gte]=100&filter[title_cont]=nest
// OR groups (requires `query parser = extended`)
GET /post?filter[or][0][title_cont]=nestjs&filter[or][1][title_cont]=typeorm
// Nested group with advanced operators
GET /post?filter[and][0][status_ne]=archived&filter[and][1][views_in]=100,200,300
```
> For nested keys like `filter[or][0][title_cont]`, set Express query parsing to extended mode:
> `app.getHttpAdapter().getInstance().set('query parser', 'extended')`.
**Supported Operators:**
- `eq` - Equals
- `ne` - Not equals
- `cont` - Contains (case-insensitive)
- `notcont` - Does not contain (case-insensitive)
- `starts` - Starts with (case-insensitive)
- `ends` - Ends with (case-insensitive)
- `gte` - Greater than or equal
- `lte` - Less than or equal
- `gt` - Greater than
- `lt` - Less than
- `in` - Matches any value from a comma-separated list
- `nin` - Does not match values from a comma-separated list
- `isnull` - `true` for `IS NULL`, `false` for `IS NOT NULL`
**Grouping Keys:**
- `and` - Combine nested filters with AND
- `or` - Combine nested filters with OR
### Extending CRUD Services
Add custom business logic while keeping CRUD functionality:
```typescript
@Injectable()
export class PostService extends NestCrudService<
Post,
CreatePostDto,
UpdatePostDto
> {
constructor(@InjectRepository(Post) repository: Repository) {
super({
repository,
allowedFilters: ['title', 'published', 'authorId'], // Whitelist filterable fields
});
}
// Add custom methods
async findPublished(): Promise {
return this.repository.find({ where: { published: true } });
}
async publishPost(id: number): Promise {
const post = await this.findOne(id);
return this.update(id, { published: true, publishedAt: new Date() } as any);
}
}
```
### Custom Controller Endpoints
Mix generated CRUD endpoints with custom routes:
```typescript
@Controller('post')
export class PostController
extends CreateNestedCrudController(CreatePostDto, UpdatePostDto, Post)
implements IBaseController
{
constructor(override readonly service: PostService) {
super(service);
}
// Add custom endpoints alongside CRUD routes
@Get('published')
@Message('fetched published posts')
async getPublished() {
return this.service.findPublished();
}
@Post(':id/publish')
@Message('published')
async publish(@Param('id', ParseIntPipe) id: number) {
return this.service.publishPost(id);
}
}
```
---
## 🐛 Troubleshooting
### TypeScript Error: TS2742 (Inferred type is not portable)
**Error:**
```
The inferred type of 'MyController' cannot be named without a reference to
'../node_modules/@nestjs/common'. This is likely not portable.
```
**Solution:**
Add explicit `implements IBaseController` to your controller:
```typescript
import {
CreateNestedCrudController,
IBaseController,
} from '@nest-util/nest-crud';
export class MyController
extends CreateNestedCrudController(CreateDto, UpdateDto, ResponseDto)
implements IBaseController {
// ...
}
```
> **Note:** The `ncnu` generator automatically includes this fix in generated code.
### Database Connection Issues
Ensure your `TypeOrmModule` is properly configured:
```typescript
TypeOrmModule.forRoot({
type: 'postgres',
host: process.env.DB_HOST || 'localhost',
port: parseInt(process.env.DB_PORT) || 5432,
username: process.env.DB_USER || 'postgres',
password: process.env.DB_PASSWORD || 'postgres',
database: process.env.DB_NAME || 'mydb',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: process.env.NODE_ENV !== 'production', // Disable in production!
});
```
### Filtering Not Working
Make sure you've configured the query parser correctly:
```typescript
// In main.ts
const adapter = app.getHttpAdapter();
adapter.getInstance().set('query parser', 'extended');
```
And whitelist fields in your service:
```typescript
super({
repository,
allowedFilters: ['name', 'email', 'status'], // Only these fields can be filtered
});
```
### Authentication Token Issues
Check that:
1. Your user entity has `accessToken` and `refreshToken` fields
2. JWT secret is consistent across requests
3. Token fields are excluded from default queries (add `select: false` in entity)
```typescript
@Column({ select: false })
refreshToken?: string;
```
---
## 📖 Documentation
- **Docs Index**: [docs/README.md](./docs/README.md)
- **demo-api setup**: [docs/demo-api/README.md](./docs/demo-api/README.md)
- **nest-auth guide**: [docs/nest-auth/README.md](./docs/nest-auth/README.md)
- **nest-crud guide**: [docs/nest-crud/README.md](./docs/nest-crud/README.md)
- **nest-audit guide**: [docs/nest-audit/README.md](./docs/nest-audit/README.md)
---
## 🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
---
## 📝 License
This project is licensed under the MIT License.
---
## 🌟 Show Your Support
If this project helped you, please give it a ⭐ on [GitHub](https://github.com/nigussolomon/nest-util)!
---
> [!TIP]
> Start from [docs/README.md](./docs/README.md). The module guides are split by package and include demo-api-specific configuration notes.