Isam NestJS Starter CLI
A powerful tool to generate production-ready NestJS applications with authentication, database integration, and more.
Installation
Prerequisites
Before installing Isam NestJS Starter CLI, ensure you have:
- Node.js (version 16 or higher)
- npm or yarn package manager
- Git (for version control)
Global Installation
Install using npm Recommended:
npm install -g isam-nestjs-starter-cli
Or using yarn:
yarn global add isam-nestjs-starter-cli
Verify Installation
Check if the CLI is installed correctly:
isam-nestjs-starter --version
You should see the version number displayed.
Local Installation (Development)
If you want to contribute or modify the CLI:
# Clone the repository
git clone https://github.com/isamch/nestjs-starter-cli.git
# Navigate to directory
cd isam-nestjs-starter-cli
# Install dependencies
npm install
# Build the project
npm run build
# Link globally for testing
npm link
Updating
To update to the latest version:
npm update -g isam-nestjs-starter-cli
Uninstalling
To remove the CLI:
npm uninstall -g isam-nestjs-starter-cli
Troubleshooting
Permission Issues (macOS/Linux)
If you encounter permission errors, use:
sudo npm install -g isam-nestjs-starter-cli
Or configure npm to use a different directory:
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH
Windows Issues
On Windows, you might need to run Command Prompt or PowerShell as Administrator.
Command Not Found
If isam-nestjs-starter command is not found after installation:
- Check if npm global bin directory is in your PATH
- Restart your terminal
- Try reinstalling the package
Quick Start
Step 1: Create Your First Project
isam-nestjs-starter create my-awesome-api
You'll be prompted to configure your project:
Project Configuration
? Project name: my-awesome-api
? Project description: My awesome NestJS API
? Author: Your Name
? Choose database: PostgreSQL
? Add authentication? Yes
? Add Refresh Tokens? Yes
? Add Email Verification? Yes
? Add Forgot Password? Yes
? Add File Upload? Yes
? Add Swagger Documentation? Yes
? Include Docker configuration? Yes
Step 2: Navigate and Install
cd my-awesome-api
npm install
Step 3: Configure Environment
cp .env.example .env
# Edit .env file with your settings
Essential Environment Variables
# Database
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USER=postgres
DATABASE_PASSWORD=your-password
DATABASE_NAME=my_awesome_api
# JWT
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
# Email
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
Step 4: Start Development Server
npm run start:dev
Your API will be available at http://localhost:3000
Step 5: Explore Your API
Swagger Documentation
Visit http://localhost:3000/api to see your API documentation.
Test Authentication
Register a new user:
curl -X POST http://localhost:3000/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123",
"firstName": "John",
"lastName": "Doe"
}'
Login:
curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "password123"
}'
Step 6: Generate New Modules
Use the built-in Isam Generator to create new modules:
# Generate a products module
npm run isam:generate products
# Generate a categories module
npm run isam:generate categories
This creates a complete module with:
- Controller with CRUD operations
- Service with business logic
- Entity with database model
- DTOs with validation
- Repository with custom queries
- Permissions enum
- Audit middleware
What's Generated?
Your project includes:
🔐 Authentication System
- JWT-based authentication
- User registration and login
- Email verification
- Password reset functionality
- Refresh tokens
👥 User Management
- User CRUD operations
- Role-based access control
- User permissions system
- Audit logging
📧 Email Service
- SMTP integration
- HTML email templates
- Bulk email support
- Email validation
📁 File Upload
- Image and document upload
- File validation
- Storage management
- Multiple file support
🛡️ Security Features
- Request logging middleware
- Input validation
- Error handling
- CORS configuration
Project Structure
This guide explains the structure of projects generated by Isam NestJS Starter CLI.
Basic Project Structure
my-app/
├── src/
│ ├── common/ # Shared utilities
│ ├── config/ # Configuration files
│ ├── modules/ # Feature modules
│ │ ├── auth/ # Authentication
│ │ ├── email/ # Email service
│ │ └── users/ # User management
│ ├── app.module.ts # Root module
│ └── main.ts # Application entry
├── .env
├── .env.example
├── package.json
└── README.md
Core Directories
/src/common- Shared utilities, decorators, guards, and middleware/src/config- Configuration files for database, JWT, email, and other services/src/modules- Feature modules organized by domain
Module Structure
Each generated module follows this structure:
module-name/
├── controllers/
├── dto/
├── entities/
├── repositories/
├── services/
├── permissions/
└── middlewares/
Authentication
The authentication module provides JWT-based authentication with email verification and password reset functionality.
Features
- User registration with email verification
- JWT token-based authentication
- Password reset via email
- Email verification resend
- Secure password hashing
Endpoints
Registration
POST /auth/register
{
"email": "user@example.com",
"password": "password123",
"firstName": "John",
"lastName": "Doe"
}
Login
POST /auth/login
{
"email": "user@example.com",
"password": "password123"
}
Email Verification
POST /auth/verify-email
{
"token": "verification-token"
}
Password Reset Request
POST /auth/forgot-password
{
"email": "user@example.com"
}
Password Reset
POST /auth/reset-password
{
"token": "reset-token",
"newPassword": "newpassword123"
}
Environment Variables
JWT_SECRET=your-jwt-secret
JWT_EXPIRES_IN=1d
EMAIL_VERIFICATION_EXPIRES_IN=24h
PASSWORD_RESET_EXPIRES_IN=1h
Usage with Guards
@UseGuards(JwtAuthGuard)
@Get('profile')
getProfile(@Request() req) {
return req.user;
}
Database Configuration
This guide covers database setup and configuration for your NestJS project.
Supported Databases
- PostgreSQL recommended
- MySQL
- SQLite
- MongoDB
Configuration
Environment Variables
# PostgreSQL
DB_TYPE=postgres
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=your_username
DB_PASSWORD=your_password
DB_DATABASE=your_database
# MySQL
DB_TYPE=mysql
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=your_username
DB_PASSWORD=your_password
DB_DATABASE=your_database
# SQLite
DB_TYPE=sqlite
DB_DATABASE=./database.sqlite
# MongoDB
DB_TYPE=mongodb
DB_HOST=localhost
DB_PORT=27017
DB_USERNAME=your_username
DB_PASSWORD=your_password
DB_DATABASE=your_database
TypeORM Configuration
export const databaseConfig = {
type: process.env.DB_TYPE,
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT),
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
synchronize: process.env.NODE_ENV !== 'production',
logging: process.env.NODE_ENV === 'development',
};
Migrations
Generate Migration
npm run migration:generate -- -n MigrationName
Run Migrations
npm run migration:run
Revert Migration
npm run migration:revert
Best Practices
- Use migrations in production
- Set
synchronize: falsein production - Use connection pooling for better performance
- Implement proper indexing for frequently queried fields
Email Service
The email service handles sending emails for authentication and notifications.
Configuration
Environment Variables
# SMTP Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
# Email Settings
FROM_EMAIL=noreply@yourapp.com
FROM_NAME=Your App Name
Gmail Setup
- Enable 2-factor authentication
- Generate an app password
- Use the app password in
SMTP_PASS
Other Providers
SendGrid
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USER=apikey
SMTP_PASS=your-sendgrid-api-key
Mailgun
SMTP_HOST=smtp.mailgun.org
SMTP_PORT=587
SMTP_USER=your-mailgun-username
SMTP_PASS=your-mailgun-password
Email Templates
Templates are located in src/modules/email/templates/:
verification.html- Email verificationpassword-reset.html- Password resetwelcome.html- Welcome email
Template Variables
Templates support variable substitution:
<h1>Hello {{name}}!</h1>
<p>Click <a href="{{verificationUrl}}">here</a> to verify your email.</p>
Usage
Send Email
await this.emailService.sendEmail({
to: 'user@example.com',
subject: 'Welcome!',
template: 'welcome',
context: {
name: 'John Doe',
appName: 'Your App'
}
});
Send Verification Email
await this.emailService.sendVerificationEmail(
'user@example.com',
'verification-token'
);
Troubleshooting
Common Issues
- Authentication failed: Check SMTP credentials
- Connection timeout: Verify SMTP host and port
- Template not found: Ensure template file exists
- Variables not replaced: Check template syntax
Isam Generator
The Isam Generator creates complete NestJS modules with all necessary components.
Usage
npm run isam:generate module-name
Generated Components
- Controller - CRUD endpoints with Swagger documentation
- Service - Business logic with validation and error handling
- Entity - TypeORM entity with database mapping
- Repository - Custom database queries and operations
- DTOs - Data transfer objects with validation decorators
- Permissions - Enum with CRUD and management permissions
- Middleware - Audit logging for tracking changes
Example
Generate a "products" module:
npm run isam:generate products
This creates:
src/modules/products/
├── controllers/
│ └── products.controller.ts
├── dto/
│ ├── create-product.dto.ts
│ ├── update-product.dto.ts
│ └── product-response.dto.ts
├── entities/
│ └── product.entity.ts
├── repositories/
│ └── products.repository.ts
├── services/
│ └── products.service.ts
├── permissions/
│ └── products.permissions.ts
├── middlewares/
│ └── products-audit.middleware.ts
└── products.module.ts
Working with Generated Files
Detailed guide on how to customize and work with each file generated by Isam Generator.
Controller (`controllers/products.controller.ts`)
What it does:
Handles HTTP requests and responses for your module.
How to customize:
@Controller('products')
export class ProductsController {
constructor(private readonly productsService: ProductsService) {}
// GET /products - List all products with pagination
@Get()
async findAll(@Query() query: any) {
return this.productsService.findAll(query);
}
// GET /products/:id - Get single product
@Get(':id')
async findOne(@Param('id') id: string) {
return this.productsService.findOne(id);
}
// POST /products - Create new product
@Post()
async create(@Body() createDto: CreateProductDto) {
return this.productsService.create(createDto);
}
// PUT /products/:id - Update product
@Put(':id')
async update(@Param('id') id: string, @Body() updateDto: UpdateProductDto) {
return this.productsService.update(id, updateDto);
}
// DELETE /products/:id - Delete product
@Delete(':id')
async remove(@Param('id') id: string) {
return this.productsService.remove(id);
}
}
Add custom endpoints:
// GET /products/search - Search products
@Get('search')
async search(@Query('q') query: string) {
return this.productsService.search(query);
}
// POST /products/:id/activate - Activate product
@Post(':id/activate')
async activate(@Param('id') id: string) {
return this.productsService.activate(id);
}
Service (`services/products.service.ts`)
What it does:
Contains business logic and coordinates with repository.
How to customize:
@Injectable()
export class ProductsService {
constructor(private readonly productsRepository: ProductsRepository) {}
async findAll(query: any) {
const { page = 1, limit = 10, search } = query;
return this.productsRepository.findWithPagination(page, limit, search);
}
async findOne(id: string) {
const product = await this.productsRepository.findById(id);
if (!product) {
throw new NotFoundException('Product not found');
}
return product;
}
async create(createDto: CreateProductDto) {
// Add business logic here
if (createDto.price < 0) {
throw new BadRequestException('Price cannot be negative');
}
return this.productsRepository.create(createDto);
}
async update(id: string, updateDto: UpdateProductDto) {
await this.findOne(id); // Check if exists
return this.productsRepository.update(id, updateDto);
}
}
Add custom business logic:
async calculateDiscount(productId: string, discountPercent: number) {
const product = await this.findOne(productId);
const discountedPrice = product.price * (1 - discountPercent / 100);
return this.update(productId, { price: discountedPrice });
}
async getProductsByCategory(categoryId: string) {
return this.productsRepository.findByCategory(categoryId);
}
Entity (`entities/product.entity.ts`)
What it does:
Defines database table structure and relationships.
How to customize:
@Entity('products')
export class Product {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ length: 255 })
name: string;
@Column('text', { nullable: true })
description: string;
@Column('decimal', { precision: 10, scale: 2 })
price: number;
@Column({ default: 0 })
stock: number;
@Column({ default: true })
isActive: boolean;
// Add relationships
@ManyToOne(() => Category, category => category.products)
category: Category;
@OneToMany(() => OrderItem, orderItem => orderItem.product)
orderItems: OrderItem[];
// Add indexes for performance
@Index()
@Column({ nullable: true })
sku: string;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
}
Common customizations:
// Add enum column
@Column({ type: 'enum', enum: ProductStatus, default: ProductStatus.DRAFT })
status: ProductStatus;
// Add JSON column
@Column('json', { nullable: true })
metadata: Record<string, any>;
// Add unique constraint
@Column({ unique: true })
slug: string;
Repository (`repositories/products.repository.ts`)
What it does:
Handles database operations and complex queries.
How to customize:
@Injectable()
export class ProductsRepository extends Repository<Product> {
constructor(
@InjectRepository(Product)
private repository: Repository<Product>,
) {
super(repository.target, repository.manager, repository.queryRunner);
}
async findWithPagination(page: number, limit: number, search?: string) {
const query = this.createQueryBuilder('product');
if (search) {
query.where('product.name ILIKE :search OR product.description ILIKE :search',
{ search: `%${search}%` });
}
return query
.skip((page - 1) * limit)
.take(limit)
.getManyAndCount();
}
async findByCategory(categoryId: string) {
return this.find({
where: { category: { id: categoryId } },
relations: ['category']
});
}
async findLowStock(threshold: number = 10) {
return this.find({
where: { stock: LessThan(threshold) }
});
}
}
Add complex queries:
async getProductStats() {
return this.createQueryBuilder('product')
.select([
'COUNT(*) as total',
'AVG(product.price) as avgPrice',
'SUM(product.stock) as totalStock'
])
.getRawOne();
}
async findTopSelling(limit: number = 10) {
return this.createQueryBuilder('product')
.leftJoin('product.orderItems', 'orderItem')
.select('product.*')
.addSelect('COUNT(orderItem.id)', 'orderCount')
.groupBy('product.id')
.orderBy('orderCount', 'DESC')
.limit(limit)
.getMany();
}
DTOs (`dto/`)
Create DTO (`create-product.dto.ts`)
export class CreateProductDto {
@IsString()
@IsNotEmpty()
@MaxLength(255)
name: string;
@IsString()
@IsOptional()
description?: string;
@IsNumber()
@IsPositive()
@Type(() => Number)
price: number;
@IsNumber()
@Min(0)
@Type(() => Number)
stock: number;
@IsUUID()
@IsOptional()
categoryId?: string;
}
Update DTO (`update-product.dto.ts`)
export class UpdateProductDto extends PartialType(CreateProductDto) {
@IsBoolean()
@IsOptional()
isActive?: boolean;
}
Response DTO (`product-response.dto.ts`)
export class ProductResponseDto {
id: string;
name: string;
description: string;
price: number;
stock: number;
isActive: boolean;
createdAt: Date;
updatedAt: Date;
// Include related data
category?: CategoryResponseDto;
}
Permissions (`permissions/products.permissions.ts`)
What it does:
Defines access control for the module.
How to customize:
export const PRODUCTS_PERMISSIONS = {
CREATE: 'products:create',
READ: 'products:read',
UPDATE: 'products:update',
DELETE: 'products:delete',
MANAGE: 'products:manage',
} as const;
// Use in controller
@UseGuards(JwtAuthGuard, PermissionsGuard)
@RequirePermissions(PRODUCTS_PERMISSIONS.CREATE)
@Post()
async create(@Body() createDto: CreateProductDto) {
return this.productsService.create(createDto);
}
Role-based permissions:
export const PRODUCTS_ROLE_PERMISSIONS = {
ADMIN: [
PRODUCTS_PERMISSIONS.CREATE,
PRODUCTS_PERMISSIONS.READ,
PRODUCTS_PERMISSIONS.UPDATE,
PRODUCTS_PERMISSIONS.DELETE,
PRODUCTS_PERMISSIONS.MANAGE,
],
MANAGER: [
PRODUCTS_PERMISSIONS.CREATE,
PRODUCTS_PERMISSIONS.READ,
PRODUCTS_PERMISSIONS.UPDATE,
],
USER: [
PRODUCTS_PERMISSIONS.READ,
],
};
Middleware (`middlewares/products-audit.middleware.ts`)
What it does:
Logs operations and handles cross-cutting concerns.
How to customize:
@Injectable()
export class ProductsAuditMiddleware implements NestMiddleware {
private readonly logger = new Logger(ProductsAuditMiddleware.name);
use(req: Request, res: Response, next: NextFunction) {
const { method, url, body } = req;
const user = req.user;
// Log the operation
this.logger.log(`${method} ${url} by user ${user?.id}`);
// Add custom logic
if (method === 'POST' || method === 'PUT') {
this.logger.log(`Data: ${JSON.stringify(body)}`);
}
next();
}
}
Add validation middleware:
@Injectable()
export class ProductsValidationMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
if (req.method === 'POST' && req.body.price > 10000) {
throw new BadRequestException('Price too high, requires approval');
}
next();
}
}
Module Registration (`products.module.ts`)
How to register everything:
@Module({
imports: [TypeOrmModule.forFeature([Product])],
controllers: [ProductsController],
providers: [ProductsService, ProductsRepository],
exports: [ProductsService], // Export for use in other modules
})
export class ProductsModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(ProductsAuditMiddleware)
.forRoutes(ProductsController);
}
}
Quick Customization Checklist
- Entity: Add your fields, relationships, and constraints
- DTOs: Update validation rules and add/remove fields
- Repository: Add custom queries for your business needs
- Service: Implement your business logic and validations
- Controller: Add custom endpoints and modify existing ones
- Permissions: Define who can access what operations
- Middleware: Add logging, validation, or other cross-cutting concerns
CLI Commands Reference
Complete reference for all Isam NestJS Starter CLI commands.
Global Commands
`create`
Create a new NestJS project with custom features.
isam-nestjs-starter create <project-name>
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| project-name | string | Yes | Name of the project (lowercase with hyphens) |
Interactive Options
The CLI will prompt you for the following options:
| Option | Type | Default | Description |
|---|---|---|---|
| Project description | string | "A NestJS API" | Brief description of your project |
| Author | string | - | Your name or organization |
| Database | choice | PostgreSQL | Database type (PostgreSQL, MySQL, MongoDB) |
| Authentication | boolean | true | Include authentication system |
| Refresh Tokens | boolean | true | JWT refresh token support |
| Email Verification | boolean | true | Email verification system |
| Forgot Password | boolean | true | Password reset functionality |
| File Upload | boolean | false | File upload capabilities |
| Swagger Documentation | boolean | true | API documentation |
| Docker Configuration | boolean | false | Docker setup files |
Examples
# Basic project creation
isam-nestjs-starter create my-api
# Project with specific name format
isam-nestjs-starter create e-commerce-api
isam-nestjs-starter create blog-system
Generated Project Structure
my-api/
├── src/
│ ├── common/ # Shared utilities
│ ├── config/ # Configuration files
│ ├── modules/ # Feature modules
│ │ ├── auth/ # Authentication
│ │ ├── users/ # User management
│ │ ├── email/ # Email service
│ │ └── upload/ # File upload (if enabled)
│ ├── app.module.ts # Root module
│ └── main.ts # Application entry
├── scripts/
│ └── generate-module.js # Module generator
├── .env.example # Environment template
├── docker-compose.yml # Docker setup (if enabled)
├── package.json
└── README.md
Project-Level Commands
These commands are available within generated projects:
`isam:generate`
Generate a new module with complete CRUD structure.
npm run isam:generate <module-name>
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| module-name | string | Yes | Name of the module (lowercase) |
Generated Files
src/modules/<module-name>/
├── controllers/
│ └── <module-name>.controller.ts
├── services/
│ └── <module-name>.service.ts
├── entities/
│ └── <module-name>.entity.ts
├── dto/
│ ├── create-<module-name>.dto.ts
│ └── update-<module-name>.dto.ts
├── repositories/
│ └── <module-name>.repository.ts
├── permissions/
│ └── <module-name>.permissions.ts
├── middlewares/
│ └── <module-name>-audit.middleware.ts
└── <module-name>.module.ts
Examples
# Generate a products module
npm run isam:generate products
# Generate a categories module
npm run isam:generate categories
# Generate an orders module
npm run isam:generate orders
What's Generated
Each module includes:
- Controller: Complete CRUD endpoints with Swagger documentation
- Service: Business logic with validation and error handling
- Entity: TypeORM entity with database mapping
- DTOs: Data transfer objects with validation decorators
- Repository: Custom database queries and operations
- Permissions: Enum with CRUD and management permissions
- Middleware: Audit logging for tracking changes
Development Commands
`start:dev`
Start the application in development mode with hot reload.
npm run start:dev
`start:prod`
Start the application in production mode.
npm run start:prod
`build`
Build the application for production.
npm run build
`test`
Run unit tests.
npm run test
`test:e2e`
Run end-to-end tests.
npm run test:e2e
`lint`
Run ESLint to check code quality.
npm run lint
Global CLI Options
`--version`
Display the CLI version.
isam-nestjs-starter --version
`--help`
Display help information.
isam-nestjs-starter --help
isam-nestjs-starter create --help
Environment Variables
Required Variables
| Variable | Description | Example |
|---|---|---|
DATABASE_HOST |
Database server host | localhost |
DATABASE_PORT |
Database server port | 5432 |
DATABASE_USER |
Database username | postgres |
DATABASE_PASSWORD |
Database password | mypassword |
DATABASE_NAME |
Database name | my_api_db |
JWT_SECRET |
JWT signing secret | your-secret-key |
SMTP_HOST |
Email server host | smtp.gmail.com |
SMTP_PORT |
Email server port | 587 |
SMTP_USER |
Email username | your-email@gmail.com |
SMTP_PASS |
Email password | your-app-password |
Optional Variables
| Variable | Description | Default |
|---|---|---|
PORT |
Application port | 3000 |
NODE_ENV |
Environment mode | development |
APP_URL |
Application URL | http://localhost:3000 |
CORS_ORIGIN |
CORS allowed origins | * |
Exit Codes
| Code | Description |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Invalid arguments |
| 3 | Project already exists |
| 4 | Template not found |
Examples
Complete Project Setup
# 1. Create project
isam-nestjs-starter create my-ecommerce-api
# 2. Navigate and install
cd my-ecommerce-api
npm install
# 3. Configure environment
cp .env.example .env
# Edit .env with your settings
# 4. Start development
npm run start:dev
# 5. Generate modules
npm run isam:generate products
npm run isam:generate categories
npm run isam:generate orders
Production Deployment
# Build for production
npm run build
# Start production server
npm run start:prod
# Or using Docker
docker-compose up -d
Examples
Create Basic Project
# Create project with authentication
isam-nestjs-starter create my-app --auth --database postgres --email
# Create minimal project
isam-nestjs-starter create simple-app --database sqlite
Generate E-commerce Product Module
isam-nestjs-starter generate module products
Blog Post Module
isam-nestjs-starter generate module posts
Update the entity for blog functionality:
@Entity('posts')
export class Post {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
title: string;
@Column('text')
content: string;
@Column()
slug: string;
@Column({ default: false })
published: boolean;
@ManyToOne(() => User)
author: User;
}
API Usage Examples
Authentication Flow
// Register user
const registerResponse = await fetch('/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'user@example.com',
password: 'password123',
firstName: 'John',
lastName: 'Doe'
})
});
// Login user
const loginResponse = await fetch('/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'user@example.com',
password: 'password123'
})
});
const { access_token } = await loginResponse.json();
// Use token for authenticated requests
const profileResponse = await fetch('/users/profile', {
headers: { 'Authorization': `Bearer ${access_token}` }
});
CRUD Operations
// Create resource
const createResponse = await fetch('/products', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
name: 'Product Name',
description: 'Product Description',
price: 29.99
})
});
// Get all resources
const listResponse = await fetch('/products?page=1&limit=10', {
headers: { 'Authorization': `Bearer ${token}` }
});
// Update resource
const updateResponse = await fetch('/products/123', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
name: 'Updated Product Name',
price: 39.99
})
});
Deployment Guide
Environment Setup
Production environment variables:
NODE_ENV=production
PORT=3000
# Database
DB_TYPE=postgres
DB_HOST=your-production-db-host
DB_PORT=5432
DB_USERNAME=your-db-user
DB_PASSWORD=your-secure-password
DB_DATABASE=your-production-db
# JWT
JWT_SECRET=your-very-secure-jwt-secret-key
JWT_EXPIRES_IN=1d
# Email
SMTP_HOST=your-smtp-host
SMTP_PORT=587
SMTP_USER=your-smtp-user
SMTP_PASS=your-smtp-password
FROM_EMAIL=noreply@yourdomain.com
Build for Production
# Install dependencies
npm ci --only=production
# Build the application
npm run build
# Start the application
npm run start:prod
Docker Deployment
Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "run", "start:prod"]
Docker Compose
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
depends_on:
- postgres
postgres:
image: postgres:15
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Database Migration
npm run migration:run
Cloud Deployment
AWS Elastic Beanstalk
- Install EB CLI
- Initialize application:
eb init eb create production eb deploy
Heroku
- Create Heroku app:
heroku create your-app-name - Set environment variables:
heroku config:set NODE_ENV=production heroku config:set JWT_SECRET=your-secret - Deploy:
git push heroku main
DigitalOcean App Platform
- Connect GitHub repository
- Configure environment variables
- Set build and run commands:
- Build:
npm run build - Run:
npm run start:prod
- Build:
Health Checks
@Get('health')
healthCheck() {
return { status: 'ok', timestamp: new Date().toISOString() };
}
Monitoring
- Use PM2 for process management
- Set up logging with Winston
- Monitor with tools like New Relic or DataDog
- Configure error tracking with Sentry
Security Best Practices
Authentication Security
JWT Configuration
# Use strong, random secret (32+ characters)
JWT_SECRET=your-very-long-random-secret-key-here
JWT_EXPIRES_IN=15m # Short expiration for access tokens
Password Security
- Minimum 8 characters
- Bcrypt hashing with salt rounds 12+
- Password complexity validation
- Rate limiting on auth endpoints
Environment Variables
Secure Storage
- Never commit
.envfiles - Use environment-specific configs
- Rotate secrets regularly
- Use secret management services in production
Required Security Variables
# Strong JWT secret
JWT_SECRET=
# Secure database credentials
DB_PASSWORD=
# SMTP credentials
SMTP_PASS=
# CORS origins
CORS_ORIGINS=https://yourdomain.com
Database Security
Connection Security
- Use SSL/TLS connections
- Implement connection pooling
- Set connection timeouts
- Use read-only users for queries
Query Security
- Use parameterized queries (TypeORM handles this)
- Validate all inputs
- Implement proper authorization
- Audit sensitive operations
API Security
Input Validation
@IsEmail()
@IsNotEmpty()
email: string;
@IsString()
@MinLength(8)
@Matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/)
password: string;
Rate Limiting
@UseGuards(ThrottlerGuard)
@Throttle(5, 60) // 5 requests per minute
@Post('login')
async login() {}
CORS Configuration
app.enableCors({
origin: process.env.CORS_ORIGINS?.split(',') || 'http://localhost:3000',
credentials: true,
});
Production Security
HTTPS Only
- Force HTTPS in production
- Use HSTS headers
- Implement proper SSL certificates
Security Headers
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
},
},
}));
Monitoring
- Log security events
- Monitor failed login attempts
- Set up alerts for suspicious activity
- Regular security audits
Frequently Asked Questions
General Questions
What is Isam NestJS Starter CLI?
A command-line tool that generates complete NestJS applications with authentication, database integration, email service, and module generation capabilities.
What databases are supported?
- PostgreSQL (recommended)
- MySQL
- SQLite
- MongoDB
Can I use it for production applications?
Yes, the generated code follows NestJS best practices and includes production-ready features like JWT authentication, email verification, and proper error handling.
Project Creation
Can I add authentication later?
Currently, authentication must be selected during project creation. You can manually integrate auth components from the templates.
How do I change the database after creation?
Update the database configuration in src/config/database.config.ts and install the appropriate database driver.
Can I customize the generated templates?
Yes, you can modify templates in the CLI source code or customize the generated files after creation.
Authentication
How secure is the authentication system?
The auth system uses:
- JWT tokens with configurable expiration
- Bcrypt password hashing
- Email verification
- Password reset functionality
- Rate limiting capabilities
Can I add social authentication?
Social auth is not included by default but can be added using Passport.js strategies.
How do I customize email templates?
Email templates are located in src/modules/email/templates/ and use HTML with variable substitution.
Module Generation
What components are generated for each module?
- Controller with CRUD endpoints
- Service with business logic
- Entity with TypeORM decorators
- Repository for database operations
- DTOs for validation
- Permissions for access control
- Audit middleware
Can I generate modules without certain components?
Currently, all components are generated together. You can delete unused files after generation.
How do I add relationships between modules?
Manually add TypeORM relationship decorators in entity files and update services accordingly.
Development
How do I add new CLI commands?
- Create command file in
src/commands/ - Implement command logic
- Register in
src/index.ts - Add documentation
Can I contribute new templates?
Yes! See the contributing guide for template development guidelines.
How do I test my changes?
Use npm link for local development and test with different project configurations.
Deployment
What's the recommended deployment method?
Docker containers with proper environment variable management and database migrations.
How do I handle database migrations in production?
Run npm run migration:run as part of your deployment process, preferably in a separate step before starting the application.
Can I use serverless deployment?
The generated applications are designed for traditional server deployment. Serverless would require significant modifications.
Troubleshooting
The CLI command is not found after installation
Try:
- Reinstalling globally:
npm install -g isam-nestjs-starter-cli - Checking npm global path:
npm config get prefix - Adding npm global bin to PATH
Generated project won't start
Check:
- All dependencies installed:
npm install - Environment variables configured
- Database connection working
- Port not already in use
Email service not working
Verify:
- SMTP credentials correct
- SMTP host and port accessible
- Email provider allows SMTP
- Check spam folder for test emails
Troubleshooting
Installation Issues
Permission Errors
# Fix npm permissions
sudo chown -R $(whoami) ~/.npm
npm install -g isam-nestjs-starter-cli
Command Not Found
# Check global installation
npm list -g isam-nestjs-starter-cli
# Reinstall if needed
npm uninstall -g isam-nestjs-starter-cli
npm install -g isam-nestjs-starter-cli
Project Creation Issues
Template Errors
Problem: EJS template compilation fails
Solution: Check template syntax and ensure all variables are defined
Missing Dependencies
Problem: Generated project has missing packages
Solution: Run npm install in the project directory
Database Connection
Problem: Cannot connect to database
Solutions:
- Verify database is running
- Check connection credentials in
.env - Ensure database exists
- Test connection manually
Authentication Issues
JWT Token Errors
Problem: Invalid or expired tokens
Solutions:
- Check JWT_SECRET in environment
- Verify token expiration settings
- Ensure proper token format
Email Verification
Problem: Verification emails not sent
Solutions:
- Check SMTP configuration
- Verify email credentials
- Test SMTP connection
- Check spam folder
Runtime Errors
Port Already in Use
# Find process using port
lsof -i :3000
# Kill process
kill -9 <PID>
Database Migration Errors
# Reset migrations
npm run migration:revert
# Generate new migration
npm run migration:generate -- -n FixMigration
# Run migrations
npm run migration:run
Performance Issues
Slow Startup
- Check database connection timeout
- Optimize imports
- Review middleware stack
Memory Leaks
- Monitor database connections
- Check for unclosed resources
- Use proper error handling
Getting Help
- Check this troubleshooting guide
- Review error logs carefully
- Search existing GitHub issues
- Create new issue with:
- CLI version
- Operating system
- Full error message
- Steps to reproduce
Contributing Guide
Thank you for your interest in contributing to Isam NestJS Starter CLI!
Development Setup
Prerequisites
- Node.js 18+
- npm or yarn
- Git
Setup
# Fork and clone the repository
git clone https://github.com/your-username/isam-nestjs-starter-cli.git
cd isam-nestjs-starter-cli
# Install dependencies
npm install
# Link for local development
npm link
Project Structure
src/
├── commands/ # CLI command implementations
├── generators/ # Code generators
├── templates/ # EJS templates
├── utils/ # Utility functions
└── index.ts # CLI entry point
Making Changes
Adding New Templates
- Create template files in
templates/ - Use EJS syntax for dynamic content
- Update generator to include new templates
- Test with different configurations
Adding New Commands
- Create command file in
src/commands/ - Implement command logic
- Register command in
src/index.ts - Add tests and documentation
Submitting Changes
- Create a feature branch:
git checkout -b feature/your-feature-name - Make your changes and commit:
git commit -m "feat: add new feature" - Push and create pull request:
git push origin feature/your-feature-name