node-apis
Version:
๐ Advanced TypeScript API generator with clean architecture, comprehensive testing, and automatic formatting. Generate production-ready Node.js APIs with complete integration test suites.
1,513 lines (1,151 loc) โข 54.9 kB
Markdown
# Node APIs Generator
๐ **The most advanced TypeScript API generator for Node.js** - Create production-ready API modules with clean architecture, comprehensive testing, and automatic code formatting.
## โจ Why Choose Node APIs Generator?
- **๐ Object Destructuring** - Modern TypeScript patterns with clean parameter handling
- **๐ง Intelligent Validation** - Automatic Zod schema generation with pattern recognition
- **๐ Named Fields** - Production-ready default fields instead of empty placeholders
- **๐๏ธ Clean Architecture** - Controller โ Handler โ Repository pattern
- **๐ Multi-Framework** - Support for Express.js and Hono frameworks
- **๐จ Smart Naming** - Accepts any naming format, generates consistent professional code
- **โก Performance Monitoring** - Built-in execution timing and request correlation
- **๐ Request Tracing** - Complete payload logging for easy debugging
- **๐ฏ Type-Driven** - Intelligent code generation from TypeScript types
- **๐ง TypeScript Strict Mode** - Generated code passes strict TypeScript compilation
- **๐ฆ Dependency-Free** - Generated repositories have zero external dependencies
- **โจ Auto-Formatting** - Prettier integration for consistent code style
- **๐ Two-Phase Generation** - Review types first, then generate code with optimized folder structures
- **๐ฏ Smart Interactive Mode** - Numbered selection, validation, and existing module handling
- **๐งช Comprehensive Testing** - Complete integration test suite generated automatically
- **๐ก๏ธ Production Ready** - Error handling, validation, and observability built-in
- **๐ซ No Service Layer** - Direct handler-to-repository pattern for simplicity
- **โ๏ธ Smart Configuration** - Set preferences once, skip repetitive prompts
- **๐ฆ Zero Config** - Works out of the box with sensible defaults
## ๐ Try It Now!
```bash
# Install globally and start building amazing APIs
npm install -g node-apis
# Generate REST APIs
node-apis --name blog --crud --api-style rest --framework express
# Generate tRPC APIs
node-apis --name user --crud --api-style trpc --framework hono
# Run the comprehensive tests
npm test
```
**โญ Love this tool?** [Star it on GitHub](https://github.com/sobebarali/nodejs-api) and follow [@sobebarali](https://github.com/sobebarali) for more developer tools!
## ๐ฏ What Makes This Different?
Unlike other generators that create static boilerplate, this tool:
1. **Uses modern TypeScript patterns** with object destructuring and intelligent type inference
2. **Generates smart validation** with automatic Zod schema creation and pattern recognition
3. **Provides production-ready templates** with realistic named fields instead of empty placeholders
4. **Parses your TypeScript types** and generates intelligent code
5. **Includes performance monitoring** and request correlation out of the box
6. **Follows modern clean architecture** patterns
7. **Generates working, formatted code** that's ready for production
8. **Creates comprehensive test suites** with integration tests
9. **Supports iterative development** with smart type-driven regeneration
## ๐จ Smart Naming System
The generator accepts **any naming format** and automatically converts it to professional, consistent naming conventions:
| Input Format | Directory | Files | Classes | Variables | Constants |
| ----------------- | ------------------- | --------------------------- | ----------------------- | ----------------- | ------------------ |
| `user-profile` | `user-profile/` | `create.userProfile.ts` | `CreateUserProfile` | `userProfile` | `USER_PROFILE` |
| `blog_post` | `blog-post/` | `create.blogPost.ts` | `CreateBlogPost` | `blogPost` | `BLOG_POST` |
| `productCategory` | `product-category/` | `create.productCategory.ts` | `CreateProductCategory` | `productCategory` | `PRODUCT_CATEGORY` |
| `OrderHistory` | `order-history/` | `create.orderHistory.ts` | `CreateOrderHistory` | `orderHistory` | `ORDER_HISTORY` |
**Benefits:**
- โ
**Flexible Input** - Use any naming style you prefer
- โ
**Valid JavaScript** - All generated identifiers are syntactically correct
- โ
**Professional Output** - Follows industry-standard naming conventions
- โ
**Import Safety** - No path mismatches or file not found errors
## ๐จ Choose Your API Style
The generator supports **two distinct API paradigms**, each optimized for different use cases:
### ๐ **REST APIs** (Traditional HTTP)
- **Best for**: Public APIs, microservices, traditional web applications
- **Generates**: Controllers, routes, HTTP endpoints with Express/Hono
- **Benefits**: Standard HTTP patterns, widely adopted, framework agnostic
### ๐ **tRPC APIs** (Type-safe RPC)
- **Best for**: Full-stack TypeScript applications, internal APIs, type-safe client-server communication
- **Generates**: Procedures, routers, end-to-end type safety
- **Benefits**: Auto-completion, compile-time safety, seamless TypeScript integration
**Interactive Flow:**
```
๐ Which API style would you like to generate?
๐ REST APIs (traditional HTTP endpoints)
๐ tRPC (type-safe RPC procedures)
๐ ๏ธ Which web framework would you like to use?
Express.js (Traditional, widely adopted)
Hono (Modern, lightweight, fast)
```
## ๐ Quick Start
### Installation
```bash
# Global installation (recommended)
npm install -g node-apis
# Or use npx (no installation required)
npx node-apis
```
### First-Time Setup (Optional)
Set your framework preference to skip repetitive prompts:
```bash
# Interactive setup - choose your preferred framework
node-apis --init-config
# Or set directly
node-apis --set-framework hono # or express
```
#### ๐จ Monorepo Users - Important Note
If you're working in a **monorepo** (pnpm workspaces, Yarn workspaces, npm workspaces) and encounter this error:
```
npm error Unsupported URL Type "workspace:": workspace:*
```
**Solution**: Use global installation to avoid workspace conflicts:
```bash
# โ
Recommended: Install globally
npm install -g node-apis
# โ
Alternative: Use npx (no installation)
npx node-apis
# โ
pnpm users: Bypass workspace
pnpm add -g node-apis
# โ
Yarn users: Global install
yarn global add node-apis
```
**Why this happens**: Monorepos use `workspace:` protocol for local packages, which can conflict with npm registry installations. Global installation bypasses workspace resolution.
### Generate Your First API
```bash
# Interactive mode - just run the command!
node-apis
# Or specify directly - any naming format works!
node-apis --name user-profile --crud
node-apis --name blog_post --crud
node-apis --name productCategory --crud
# Choose your framework
node-apis --name book --crud --framework express # Default
node-apis --name book --crud --framework hono # Lightweight alternative
```
## ๐ฏ Three API Types
The generator supports three distinct API types with optimized folder structures:
### 1. **CRUD APIs** (`--crud`)
Full-stack database operations with HTTP endpoints:
- **Use for**: User management, product catalogs, blog posts
- **Generates**: Controllers, handlers, repository, validators, routes, tests
- **Pattern**: HTTP โ Controller โ Handler โ Repository โ Database
- **Folders**: `controllers/`, `handlers/`, `repository/`, `services/`, `types/`, `validators/`, `routes`
### 2. **Custom APIs** (`--custom`)
Business logic operations with HTTP endpoints:
- **Use for**: Authentication, notifications, file uploads
- **Generates**: Controllers, services, validators, routes, tests
- **Pattern**: HTTP โ Controller โ Service โ External APIs/Logic
- **Folders**: `controllers/`, `handlers/`, `repository/`, `services/`, `types/`, `validators/`, `routes`
### 3. **Internal Services** (`--services`) โญ **Optimized Structure**
Third-party integrations for internal use (no HTTP layer):
- **Use for**: Payment processing, email services, cloud APIs
- **Generates**: Pure service functions, types, comprehensive tests
- **Pattern**: Direct function calls โ External APIs
- **Folders**: Only `services/` and `types/` (clean & minimal)
- **Import**: Use in other modules via `import { serviceFunction } from '../module/services/...'`
## ๐ New in v3.5.0: Intelligent Code Generation
### ๐ง Smart Object Destructuring
Handlers now use modern TypeScript patterns with clean parameter destructuring:
```typescript
// โจ Generated handler with object destructuring
export default async function createProductHandler({
name,
description,
status,
requestId,
}: {
name: string;
description: string;
status: string;
requestId: string;
}): Promise<typeResult> {
const product = await create({ name, description, status });
// ...
}
```
### ๐ฏ Automatic Validation Generation
Smart Zod schema generation with pattern recognition:
```typescript
// โจ Generated validator with intelligent patterns
export const payloadSchema = z.object({
name: z.string(),
userEmail: z.string().email().optional(), // ๐ฏ Auto-detected email
userId: z.string().uuid(), // ๐ฏ Auto-detected UUID
phoneNumber: z.string().min(10), // ๐ฏ Auto-detected phone
profileUrl: z.string().url().optional(), // ๐ฏ Auto-detected URL
description: z.string().optional(),
});
```
### ๐ Production-Ready Named Fields
No more empty placeholders - every module generates with realistic, useful fields:
```typescript
// โจ Generated types with meaningful fields
export type typePayload = {
name: string; // Universal title/label field
description?: string; // Common descriptive field
status?: string; // Useful for state management
// Add more fields here
};
// โจ Module-specific IDs
export type typeResultData = {
productId: string; // Smart ID naming
name: string;
description: string | null;
status: string | null;
created_at: string;
updated_at: string;
};
```
### ๐ Type-Driven Intelligence
The generator analyzes your TypeScript types and generates intelligent code:
- **Smart ID Detection**: Automatically uses `todoId`, `userId`, `productId` instead of generic `id`
- **Optional Field Handling**: Proper handling in UPDATE operations (partial updates)
- **Pattern Recognition**: Field names trigger appropriate validation (email, URL, phone, UUID)
- **Framework Adaptation**: Same intelligent patterns work for both Express.js and Hono
## โ๏ธ Configuration
Set your preferences once and skip repetitive prompts:
```bash
# Initialize configuration (interactive)
node-apis --init-config
# Set default framework and API style
node-apis --set-framework express
node-apis --set-api-style trpc
# Now generate without specifying preferences
node-apis --name user --crud # Uses your configured framework and API style
```
The config file (`node-apis.config.json`) stores your preferences and is extensible for future features like database ORM selection.
### Configuration Workflow Example
```bash
# First time setup - choose your preferences interactively
node-apis --init-config
# โ
Configuration file created successfully!
# ๐ Default framework: express, API style: rest
# Change preferences anytime
node-apis --set-framework hono
node-apis --set-api-style trpc
# โ
Framework set to: hono
# โ
API style set to: tRPC procedures
# Now generate APIs without specifying preferences
node-apis --name user --crud
# Uses Hono + tRPC from config
# Override config for specific generation
node-apis --name admin --crud --api-style rest --framework express
# Uses Express + REST despite Hono + tRPC being configured
```
## ๐ข Monorepo Support
Working in a monorepo? The CLI supports custom target directories so you can generate APIs from any location:
### Option 1: Use `--target-dir` Flag
Generate APIs directly from your monorepo root:
```bash
# From monorepo root, generate in apps/server/
node-apis --name user --crud --target-dir apps/server
# From monorepo root, generate in packages/api/
node-apis --name product --crud --target-dir packages/api
# Target directory can be absolute or relative
node-apis --name order --crud --target-dir /path/to/your/backend
```
### Option 2: Global Installation
Install globally to avoid workspace protocol errors:
```bash
# โ
Recommended for monorepos
npm install -g node-apis
# Use from anywhere in your monorepo
cd monorepo-root
node-apis --name user --crud --target-dir apps/api
```
### Option 3: Use npx
Run without installation:
```bash
# Always works, no conflicts
npx node-apis --name user --crud --target-dir apps/server
```
### Monorepo Examples
```bash
# Nx monorepo
node-apis --name auth --crud --target-dir apps/backend
# Lerna/Rush monorepo
node-apis --name user --crud --target-dir packages/api
# Yarn/pnpm workspaces
node-apis --name product --crud --target-dir services/catalog-api
# Custom structure
node-apis --name notification --services --target-dir infrastructure/email-service
```
The generated structure will be:
```
your-target-dir/
โโโ src/apis/your-module/
โโโ controllers/
โโโ handlers/
โโโ ...
```
> ๐ก **Pro Tip**: Use global installation (`npm install -g node-apis`) to avoid workspace conflicts and enable usage from any directory.
**That's it!** You'll get a complete, production-ready API module with:
- โ
Controllers with request logging
- โ
Handlers with performance monitoring
- โ
Repository with clean data access
- โ
TypeScript types and validation
- โ
Comprehensive integration test suite
- โ
Test configuration (Vitest + Supertest)
- โ
Automatic code formatting
## ๐๏ธ Generated Architecture
Your APIs follow a clean, modern architecture with smart naming and comprehensive testing:
```
src/apis/user-profile/ # kebab-case directories
โโโ controllers/ # HTTP routing with payload logging
โ โโโ create.userProfile.ts # camelCase files โ POST /api/user-profiles
โ โโโ get.userProfile.ts # GET /api/user-profiles/:id
โ โโโ list.userProfile.ts # GET /api/user-profiles
โ โโโ update.userProfile.ts # PUT /api/user-profiles/:id
โ โโโ delete.userProfile.ts # DELETE /api/user-profiles/:id
โโโ handlers/ # Business logic with performance monitoring
โ โโโ create.userProfile.ts # โ
Execution timing
โ โโโ get.userProfile.ts # โ
Error handling
โ โโโ ... # โ
Request correlation
โโโ repository/ # Data access layer
โ โโโ user-profile.repository.ts # โ
Clean functions
โโโ types/ # TypeScript definitions
โ โโโ create.userProfile.ts # โ
Type-safe payloads
โ โโโ ... # โ
Result types
โโโ validators/ # Zod validation schemas
โ โโโ create.userProfile.ts # โ
Input validation
โ โโโ ... # โ
Error handling
โโโ user-profile.routes.ts # Express/Hono router
tests/user-profile/ # Comprehensive test suite
โโโ create/
โ โโโ validation.test.ts # Input validation tests
โ โโโ success.test.ts # Happy path integration tests
โ โโโ errors.test.ts # Error handling tests
โโโ get/
โ โโโ ... (same pattern for all operations)
โโโ shared/
โโโ helpers.ts # Test utilities
```
## ๐ก Improved Two-Phase Generation Process
### **Phase 1: Type Definition & Review**
```bash
node-apis --name book --crud
# ๐ Phase 1: Generating directory structure and type files...
# โ
Type files generated successfully!
```
**What happens:**
- Creates main module directory and `types/` subdirectory only
- Generates TypeScript type files with placeholder interfaces
- Shows detailed instructions for each operation type
- Prompts you to review and customize the `typePayload` interfaces
**Example type file generated:**
```typescript
export type typePayload = {
// Add your specific fields here
// name: string;
// description: string;
// category?: string;
};
```
### **Phase 2: Code Generation & Testing**
```bash
# After you review types and confirm (type 'yes' or 'y')
# ๐ Phase 2: Generating services and repositories...
# ๐งช Phase 3: Generating comprehensive test suite...
```
**What happens:**
- Creates remaining directories based on API type:
- **Services**: Only `services/` (no HTTP layer)
- **CRUD/Custom**: All folders (controllers, handlers, repository, validators, routes)
- Generates all code files using your confirmed type definitions
- Auto-formats all generated code with Prettier
- Creates comprehensive test suite with validation, success, and error cases
### **Benefits of Two-Phase Approach**
- **๐ฏ Type-First Development**: Define your data structures before implementation
- **๐ง Customizable**: Edit types to match your exact requirements
- **๐ซ No Rework**: Generated code uses your confirmed field definitions
- **๐ Clean Structure**: Services get minimal folders, APIs get full structure
- **โก Efficient**: Only creates what each API type actually needs
## ๐ฅ Generated Code Examples
### Controller (HTTP Layer) - Smart Naming in Action
```typescript
// Input: --name user-profile
// Generated: src/apis/user-profile/controllers/create.userProfile.ts
import { validatePayload } from '../validators/create.userProfile';
import createUserProfileHandler from '../handlers/create.userProfile';
export default async function createUserProfileController(
req: Request,
res: Response
): Promise<void> {
const requestId = (req.headers['x-request-id'] as string) || generateRequestId();
// Professional naming: USER_PROFILE (CONSTANT_CASE)
console.info(
`${requestId} [CONTROLLER] - CREATE USER_PROFILE payload:`,
JSON.stringify(req.body, null, 2)
);
// Validation with detailed error responses
const validation = validatePayload(req.body);
if (!validation.success) {
res.status(400).json({
data: null,
error: { code: 'VALIDATION_ERROR', message: validation.error.message, statusCode: 400 },
});
return;
}
// Call handler with request correlation - PascalCase function names
const result = await createUserProfileHandler(validation.data, requestId);
const statusCode = result.error ? result.error.statusCode : 201;
res.status(statusCode).json(result);
}
```
### Handler (Business Logic) - TypeScript Best Practices
```typescript
// TypeScript best practice: import type for type-only imports
import type {
typePayload,
typeResult,
typeResultData,
typeResultError,
} from '../types/create.userProfile';
import create from '../repository/user-profile.repository';
export default async function createUserProfileHandler(
payload: typePayload,
requestId: string
): Promise<typeResult> {
let data: typeResultData | null = null;
let error: typeResultError | null = null;
try {
const startTime = Date.now();
console.info(`${requestId} [USER_PROFILE] - CREATE handler started`);
// Direct repository call (no service layer)
const userProfile = await create(payload);
data = userProfile;
const duration = Date.now() - startTime;
console.info(
`${requestId} [USER_PROFILE] - CREATE handler completed successfully in ${duration}ms`
);
} catch (err) {
// TypeScript strict mode compatible error handling
const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';
console.error(`${requestId} [USER_PROFILE] - CREATE handler error: ${errorMessage}`);
error = {
code: 'CREATE_FAILED',
message: errorMessage,
statusCode: 500,
};
}
return { data, error };
}
```
### Repository (Data Access) - Dependency-Free & Type-Safe
```typescript
// TypeScript best practice: import type for type-only imports
import type { typePayload as CreatePayload } from '../types/create.userProfile';
export default async function create(payload: CreatePayload) {
try {
// TODO: Replace with your database implementation
// Example: return await db.userProfile.create({ data: payload });
// Mock implementation - replace with actual database call
const userProfile = {
id: `mock-id-${Date.now()}`,
...payload,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
};
return userProfile;
} catch (error) {
// TypeScript strict mode compatible - no custom error classes needed
throw new Error(
`Database error: Failed to create user profile: ${error instanceof Error ? error.message : 'Unknown error'}`
);
}
}
// โ
No external dependencies - completely self-contained
// โ
Uses native Error class instead of custom error classes
// โ
TypeScript strict mode compatible
// โ
Valid JavaScript identifiers (camelCase variables)
```
## ๐งช **Generated Test Suite**
### **Integration Tests (Focus on Real API Testing)**
```typescript
// tests/book/create-book/success.test.ts
import { describe, it, expect } from 'vitest';
import request from 'supertest';
import app from '../../../src/app';
import { typePayload } from '../../../src/apis/book/types/create.book';
describe('Create Book - Success Tests', () => {
it('should create book successfully', async () => {
const payload: typePayload = {
title: 'Test Book',
author: 'Test Author',
metadata: { publisher: 'Test Publisher' },
};
const response = await request(app).post('/api/books').send(payload).expect(201);
expect(response.body.data).toBeDefined();
expect(response.body.error).toBeNull();
});
});
```
### **Error Handling Tests**
```typescript
// tests/book/create-book/errors.test.ts
describe('Create Book - Error Tests', () => {
it('should return 400 for invalid payload', async () => {
const invalidPayload = { invalidField: 'invalid-value' };
const response = await request(app).post('/api/books').send(invalidPayload).expect(400);
expect(response.body.data).toBeNull();
expect(response.body.error.code).toBe('VALIDATION_ERROR');
});
});
```
### **Validation Tests**
```typescript
// tests/book/create-book/validation.test.ts
describe('Create Book - Validation Tests', () => {
it('should validate required fields', () => {
const payload: typePayload = {
title: 'Valid Book',
author: 'Valid Author',
metadata: { publisher: 'Valid Publisher' },
};
const result = validatePayload(payload);
expect(result.success).toBe(true);
});
});
```
## ๐ฏ Usage Examples
### Basic CRUD API with Smart Naming
```bash
# Any naming format works - the generator handles it intelligently!
node-apis --name user-profile --crud # kebab-case
node-apis --name blog_post --crud # snake_case
node-apis --name productCategory --crud # camelCase
node-apis --name OrderHistory --crud # PascalCase
# All generate professional, consistent code:
# โ
5 endpoints: POST, GET, GET/:id, PUT/:id, DELETE/:id
# โ
Complete TypeScript types with proper naming
# โ
Zod validation schemas
# โ
15 integration tests (3 per operation)
# โ
Test configuration (Vitest + Supertest)
# โ
Performance monitoring
# โ
Request correlation
# โ
Auto-formatted code
```
### Multi-Framework Support
```bash
# Express.js (default)
node-apis --name user-profile --crud --framework express
# Hono (lightweight alternative)
node-apis --name blog_post --crud --framework hono
# Both generate framework-specific code with consistent naming!
```
### Custom Operations with Tests
```bash
# Generate custom user operations
node-apis --name user --custom "login,logout,resetPassword"
# What you get:
# โ
3 custom endpoints with full implementation
# โ
Type-safe request/response interfaces
# โ
Validation schemas
# โ
9 integration tests (3 per operation)
# โ
Error handling tests
# โ
Validation tests
```
### Internal Service Operations
```bash
# Generate third-party service integrations
node-apis --name stripe --services "createPayment,refund,getPaymentStatus"
node-apis --name sendgrid --services "sendEmail,sendBulkEmail"
# What you get:
# โ
Pure service functions (no HTTP layer)
# โ
Clean folder structure (only services/ and types/)
# โ
Type-safe request/response interfaces
# โ
Error handling with consistent patterns
# โ
Comprehensive test suites (validation, success, error cases)
# โ
Ready for internal use in other modules
# โ
Template code with TODO comments for easy implementation
```
**Generated Structure for Services:**
```
src/apis/stripe/
โโโ services/
โ โโโ createPayment.stripe.ts
โ โโโ refund.stripe.ts
โ โโโ getPaymentStatus.stripe.ts
โโโ types/
โโโ createPayment.stripe.ts
โโโ refund.stripe.ts
โโโ getPaymentStatus.stripe.ts
# No controllers/, handlers/, validators/, repository/ folders
# Services are pure functions for internal use
```
### Interactive Mode (Recommended) โญ
```bash
# Just run the command - it's smart and user-friendly!
node-apis
# ๐ฏ Smart Features:
# โ
Numbered selection (works in all terminals)
# โ
Existing module detection with smart options
# โ
Enhanced validation with helpful examples
# โ
Clear visual feedback with emojis and formatting
# ๐ Interactive Flow:
# 1. ๐ Detect existing modules (if any)
# 2. ๐ Enter module name with validation
# 3. ๐ฏ Choose API type (1-3 numbered selection):
# 1. ๐๏ธ CRUD operations (Create, Read, Update, Delete)
# 2. โก Custom API operations (Business logic endpoints)
# 3. ๐ง Internal service operations (Third-party integrations)
# 4. ๐ Enter operation names with smart validation
# 5. ๐ Choose API style (REST or tRPC) - NEW!
# 6. โ๏ธ Framework selection (Express or Hono)
# 7. ๐จ Handle existing modules:
# โข ๐ Overwrite existing module (replace all files)
# โข โ Add operations to existing module
# โข โ Cancel generation
# 8. โจ Two-phase generation with type review
# 9. ๐งช Comprehensive test suite generation
```
#### ๐ฏ **Interactive Mode Benefits**
- **Terminal Compatible**: Numbered selection works everywhere
- **Smart Validation**: Helpful examples and error messages
- **Existing Module Handling**: Never accidentally overwrite work
- **Visual Feedback**: Emojis and clear formatting
- **Type-First**: Review and customize types before code generation
### Type-Driven Development with Smart Naming
```bash
# 1. Generate types first (any naming format!)
node-apis --name product_category --crud
# 2. Edit the types (add your fields)
# Edit: src/apis/product-category/types/create.productCategory.ts
# 3. Code and tests automatically use your exact types!
# All generated code is type-safe and uses consistent naming:
# - Directory: product-category/ (kebab-case)
# - Files: create.productCategory.ts (camelCase)
# - Classes: CreateProductCategoryController (PascalCase)
# - Variables: productCategory (camelCase)
# - Constants: PRODUCT_CATEGORY (CONSTANT_CASE)
```
### Run Your Tests
```bash
# Run all tests
npm test
# Run tests for specific module
npm run test:module -- product
# Run with coverage
npm run test:coverage
# Watch mode for development
npm run test:watch
```
## ๐ฅ tRPC Support - Type-Safe APIs Made Easy
**New in v3.6.1**: Enhanced tRPC procedures with consistent error handling and improved type safety!
### ๐ฏ What is tRPC Style?
tRPC (TypeScript Remote Procedure Call) provides **end-to-end type safety** from your backend to frontend. Instead of traditional REST endpoints, you get type-safe procedure calls with automatic validation.
### ๐ Quick tRPC Example
```bash
# Generate tRPC procedures instead of REST controllers
node-apis --name blog --crud --trpc-style
# Set tRPC as your default style
node-apis --set-trpc-style true
node-apis --name user --crud # Uses tRPC style
```
### ๐๏ธ tRPC vs REST Structure Comparison
| **tRPC Style** | **REST Style** |
|----------------|----------------|
| ```src/apis/blog/``` | ```src/apis/blog/``` |
| ```โโโ procedures/``` | ```โโโ controllers/``` |
| ```โโโ handlers/``` | ```โโโ handlers/``` |
| ```โโโ repository/``` | ```โโโ repository/``` |
| ```โโโ types/``` | ```โโโ types/``` |
| ```โโโ validators/``` | ```โโโ validators/``` |
| ```โโโ blog.router.ts``` | ```โโโ blog.routes.ts``` |
### ๐ฏ Generated tRPC Code Examples
#### **tRPC Procedure** (`procedures/create.blog.ts`)
```typescript
import { publicProcedure } from '../../../trpc';
import { payloadSchema } from '../validators/create.blog';
import createBlogHandler from '../handlers/create.blog';
import type { typePayload } from '../types/create.blog';
export const createBlogProcedure = publicProcedure
.input(payloadSchema) // ๐ฏ Automatic validation
.mutation(async ({ input }: { input: typePayload }) => { // ๐ฏ Enhanced type safety
const requestId = generateRequestId();
try {
return await createBlogHandler({ // ๐ฏ Same business logic
...input,
requestId,
});
} catch (error) { // ๐ก๏ธ Consistent error handling
return {
data: null,
error: {
code: 'INTERNAL_ERROR',
message: error instanceof Error ? error.message : 'Something went wrong',
statusCode: 500,
requestId
}
};
}
});
```
#### **tRPC Router** (`blog.router.ts`)
```typescript
import { router } from '../../trpc';
import { createBlogProcedure } from './procedures/create.blog';
import { getBlogProcedure } from './procedures/get.blog';
// ...
export const blogRouter = router({
create: createBlogProcedure, // ๐ฏ Procedure mapping
get: getBlogProcedure,
list: listBlogsProcedure,
update: updateBlogProcedure,
delete: deleteBlogProcedure,
});
export type BlogRouter = typeof blogRouter; // ๐ฏ Type export
```
### ๐ง Required tRPC Setup
To use the generated tRPC code, you'll need to set up tRPC in your project:
#### 1. Install Dependencies
```bash
npm install @trpc/server @trpc/client zod
```
#### 2. Create tRPC Setup (`src/trpc/index.ts`)
```typescript
import { initTRPC } from '@trpc/server';
const t = initTRPC.create();
export const router = t.router;
export const publicProcedure = t.procedure;
// Main app router
import { blogRouter } from '../apis/blog/blog.router';
export const appRouter = router({
blog: blogRouter,
// Add more modules here
});
export type AppRouter = typeof appRouter;
```
#### 3. Express Integration (`src/server.ts`)
```typescript
import express from 'express';
import { createExpressMiddleware } from '@trpc/server/adapters/express';
import { appRouter } from './trpc';
const app = express();
app.use(
'/trpc',
createExpressMiddleware({
router: appRouter,
})
);
app.listen(3000);
```
### ๐ Client Usage Examples
#### Next.js Client
```typescript
import { createTRPCNext } from '@trpc/next';
import type { AppRouter } from '../server/trpc';
export const trpc = createTRPCNext<AppRouter>({
config() {
return { url: '/api/trpc' };
},
});
// In a React component
function BlogManager() {
const createBlog = trpc.blog.create.useMutation();
const { data: blogs } = trpc.blog.list.useQuery({ page: 1 });
const handleCreate = async () => {
const result = await createBlog.mutateAsync({
name: 'My Blog Post', // โ
Type-safe
description: 'Great post!', // โ
Auto-complete
status: 'published', // โ
Validated
});
if (result.data) {
console.log('Created:', result.data.blogId); // โ
Type inference
}
};
return (
<div>
<button onClick={handleCreate}>Create Blog</button>
{blogs?.data?.items.map(blog => (
<div key={blog.blogId}>{blog.name}</div>
))}
</div>
);
}
```
### ๐ฏ Key Benefits of tRPC Style
#### โ
**End-to-End Type Safety**
```typescript
// Full TypeScript inference
const blog = await trpc.blog.create.mutate({
name: "Post Title", // โ
Type-safe
description: "Content", // โ
Optional field
// status: 123 // โ TypeScript error!
});
// Automatic return type inference
blog.data?.blogId; // โ
string
blog.data?.created_at; // โ
string
```
#### โ
**Enhanced Error Handling** (New in v3.6.1)
```typescript
// Consistent error format across all procedures
const result = await trpc.blog.create.mutate({ name: "Test" });
if (result.error) {
console.log(result.error.code); // โ
'INTERNAL_ERROR'
console.log(result.error.message); // โ
Descriptive error message
console.log(result.error.statusCode); // โ
HTTP status code
console.log(result.error.requestId); // โ
Request tracing ID
}
```
#### โ
**Same Business Logic**
The handlers, repository, and types are **identical** to REST - only the transport layer changes!
#### โ
**Smart Validation**
```typescript
// Automatic Zod validation
trpc.blog.create.mutate({
name: "", // โ Validation error
description: null, // โ Type error
});
```
#### โ
**Performance Benefits**
- Direct procedure calls (no HTTP overhead)
- Built-in caching with React Query
- Automatic request deduplication
- Optimistic updates support
### ๐ฏ When to Use Each Style
#### **Use tRPC Style When:**
- โ
Full-stack TypeScript projects
- โ
Team values type safety
- โ
Modern development workflow
- โ
React/Next.js frontend
- โ
API consumed primarily by your own frontend
#### **Use REST Style When:**
- โ
Public APIs for third parties
- โ
Multiple different client technologies
- โ
Traditional HTTP/JSON APIs
- โ
OpenAPI/Swagger documentation needed
### ๐ tRPC Configuration
Set tRPC as your default style:
```bash
# Set tRPC style preference
node-apis --set-trpc-style true
# Now all generations use tRPC style by default
node-apis --name user --crud # Uses tRPC procedures
node-apis --name auth --custom "login,logout" # Uses tRPC procedures
# Override for specific generation
node-apis --name public-api --crud --framework express # Uses REST despite tRPC config
```
### ๐ฅ Complete tRPC Example
Generate a complete blog API with tRPC:
```bash
# Generate blog API with tRPC style (new syntax)
node-apis --name blog --crud --api-style trpc --framework express
# Or using deprecated syntax (shows warning)
node-apis --name blog --crud --trpc-style
# What you get:
# โ
5 tRPC procedures (create, get, list, update, delete)
# โ
Type-safe validation with Zod schemas
# โ
Business logic handlers with object destructuring
# โ
Repository functions for data access
# โ
TypeScript types for requests/responses
# โ
Complete test suite for all operations
# โ
tRPC router combining all procedures
# โ
Production-ready code with error handling
```
**Generated structure:**
```
src/apis/blog/
โโโ procedures/ # ๐ tRPC procedures
โ โโโ create.blog.ts
โ โโโ get.blog.ts
โ โโโ ...
โโโ handlers/ # โ
Same business logic
โโโ repository/ # โ
Same data access
โโโ types/ # โ
Same TypeScript types
โโโ validators/ # โ
Same Zod schemas (perfect for tRPC!)
โโโ blog.router.ts # ๐ tRPC router
```
This is a **complete, production-ready tRPC API** generated in seconds! ๐
## ๐ Command Line Options
| Option | Alias | Description |
| --------------------------- | ----- | ----------------------------------------------------------------- |
| `--name <name>` | `-n` | Module name (skips interactive prompt) |
| `--crud` | | Generate CRUD operations (create, get, list, update, delete) |
| `--custom <names>` | | Generate custom operations (comma-separated) |
| `--services <names>` | | Generate internal service operations (comma-separated) |
| `--api-style <style>` | | API style to generate (rest\|trpc), defaults to rest ๐ |
| `--framework <framework>` | | Web framework to use (express\|hono), defaults to express |
| `--target-dir <dir>` | | Target directory for generated files (default: current directory) |
| `--set-api-style <style>` | | Set default API style in config (rest\|trpc) ๐ |
| `--set-framework <framework>` | | Set default framework in config (express\|hono) |
| `--trpc-style` | | โ ๏ธ **Deprecated**: Use `--api-style trpc` instead |
| `--set-trpc-style <bool>` | | โ ๏ธ **Deprecated**: Use `--set-api-style` instead |
| `--force` | `-f` | Overwrite existing files |
| `--no-interactive` | | Skip interactive prompts |
| `--init-config` | | Initialize configuration file |
| `--version` | `-V` | Show version number |
| `--help` | `-h` | Show help information |
## ๐จ What Makes the Generated Code Special?
### โ
Performance Monitoring Built-In
```bash
req-1703123456789-abc123 [BOOK] - CREATE handler started
req-1703123456789-abc123 [BOOK] - CREATE handler completed successfully in 45ms
```
### โ
Complete Request Tracing
```bash
req-1703123456789-abc123 [CONTROLLER] - CREATE BOOK payload: {
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald"
}
```
### โ
Production-Ready Error Handling
```typescript
{
"data": null,
"error": {
"code": "VALIDATION_ERROR",
"message": "Title is required",
"statusCode": 400
}
}
```
### โ
Type-Safe Throughout
- Controllers know exact request/response types
- Handlers use your custom field definitions
- Repositories match your data structure
- Validators enforce your business rules
## ๐ก๏ธ Production-Ready Error Handling
### Defense in Depth Architecture (New in v3.6.1)
The generator now implements **comprehensive error handling** across all API layers, ensuring your applications are resilient and production-ready:
#### **Complete Coverage Across All Layers**
```
๐ API Entry Points
โโโ ๐ก๏ธ Controllers (Express/Hono) - Framework & validation errors
โโโ ๐ก๏ธ tRPC Procedures - Procedure-level errors (NEW!)
โโโ ๐ก๏ธ Handlers - Business logic errors
โโโ ๐ก๏ธ Repository - Data access errors
```
#### **Consistent Error Format**
All layers return the same standardized error structure:
```typescript
{
data: null,
error: {
code: 'VALIDATION_ERROR' | 'NOT_FOUND' | 'INTERNAL_ERROR',
message: 'Descriptive error message',
statusCode: 400 | 404 | 500,
requestId: 'req-abc123...' // For request tracing
}
}
```
#### **Enhanced tRPC Error Handling**
```typescript
// Every tRPC procedure now includes robust error handling
export const createUserProcedure = publicProcedure
.input(payloadSchema)
.mutation(async ({ input }: { input: typePayload }) => {
const requestId = randomBytes(16).toString('hex');
try {
return await createUserHandler({ ...input, requestId });
} catch (error) {
// Consistent error format with request tracing
return {
data: null,
error: {
code: 'INTERNAL_ERROR',
message: error instanceof Error ? error.message : 'Something went wrong',
statusCode: 500,
requestId // Essential for debugging
}
};
}
});
```
#### **Benefits of This Approach**
- **๐ Request Tracing**: Every error includes a `requestId` for debugging
- **๐ Consistency**: Same error format across Express, Hono, and tRPC
- **๐ก๏ธ Reliability**: Prevents unhandled promise rejections
- **๐ Monitoring**: Structured errors perfect for logging systems
- **๐ฏ Production Ready**: Built for real-world application requirements
## ๐ Advanced Features
### Smart Type-Driven Generation
- **Parses your TypeScript types** and generates matching code
- **Regenerates handlers** when you update type definitions
- **Maintains consistency** between types and implementation
- **Tests automatically use your exact types** for complete type safety
### Comprehensive Testing
- **Integration tests only** - focus on real API behavior
- **No complex mocking** - tests actual endpoints with supertest
- **Type-safe tests** - all tests use your TypeScript types
- **Complete coverage** - validation, success, and error scenarios
- **Ready-to-run** - includes Vitest configuration and scripts
### Automatic Code Formatting
- **Prettier integration** formats all generated code
- **Consistent style** across your entire codebase
- **No manual formatting** needed
### Clean Architecture
- **No service layer bloat** - direct handler-to-repository pattern
- **Single responsibility** - each layer has a clear purpose
- **Easy to test** - clean separation of concerns
- **Performance monitoring** built into every handler
### Developer Experience
- **Interactive CLI** that guides you through the process
- **Smart defaults** that work out of the box
- **Incremental development** - add operations to existing modules
- **Type safety** throughout the entire stack
- **Test-driven development** ready out of the box
## ๐ฆ Requirements
- **Node.js >= 16.0.0**
- **TypeScript project** (the generator creates TypeScript files)
## ๐ง Troubleshooting
### Common Issues and Solutions
#### ๐จ Workspace Protocol Error (Monorepo Users)
```
npm error Unsupported URL Type "workspace:": workspace:*
```
**Solution**: Install globally to avoid workspace conflicts:
```bash
npm install -g node-apis # โ
Recommended
# or
npx node-apis # โ
No installation needed
```
#### ๐จ Permission Denied (macOS/Linux)
```
Error: EACCES: permission denied
```
**Solution**: Use sudo or fix npm permissions:
```bash
sudo npm install -g node-apis # Quick fix
# or
npm config set prefix ~/.npm-global # Better long-term solution
```
#### ๐จ Command Not Found After Global Install
```
bash: node-apis: command not found
```
**Solution**: Check your PATH or use npx:
```bash
npx node-apis # Always works
# or
echo $PATH # Check if npm global bin is in PATH
```
#### ๐จ TypeScript Compilation Errors in Generated Code
**Solution**: Ensure you have TypeScript installed and compatible version:
```bash
npm install -g typescript # Global TypeScript
# or in your project
npm install --save-dev typescript
```
**Note**: Generated code is compatible with TypeScript strict mode and follows best practices:
- Uses `import type` for type-only imports
- Proper error handling with `instanceof Error` checks
- Valid JavaScript identifiers for all variable names
#### ๐จ Tests Failing After Generation
**Solution**: Install test dependencies:
```bash
npm install --save-dev vitest supertest @types/supertest
```
### ๐ก Pro Tips
- **Always use global installation** for CLI tools like `node-apis`
- **Use npx** if you prefer not to install globally
- **Check the generated files** - they include helpful TODO comments
- **Customize the types first** before generating the full code
- **Generated code is TypeScript strict mode ready** - no compilation errors
- **No external dependencies** - generated repositories are completely self-contained
- **Use any naming format** - the smart naming system handles everything
## ๐ค Contributing
We welcome contributions! Here's how:
1. **Fork** the repository
2. **Create** your feature branch (`git checkout -b feature/amazing-feature`)
3. **Commit** your changes (`git commit -m 'Add amazing feature'`)
4. **Push** to the branch (`git push origin feature/amazing-feature`)
5. **Open** a Pull Request
## ๐ Changelog
### v3.6.1 - Enhanced Error Handling & Type Safety ๐ก๏ธ
**๐ฅ Major Enhancement: Consistent Error Handling**
- โ
**Enhanced tRPC Procedures**: Added try-catch blocks to all tRPC procedure templates
- โ
**Type Safety Improvements**: Explicit `typePayload` typing in all procedures
- โ
**Consistent Error Format**: All procedures return standardized error structure
- โ
**Defense in Depth**: Complete error handling coverage across all API layers
- โ
**Request Tracing**: Request IDs included in all error responses for debugging
- โ
**Production Ready**: Prevents unhandled promise rejections and crashes
### v3.5.1 - tRPC Integration & Monorepo Support ๐
**๐ฅ Major Feature: tRPC Support**
- โ
**tRPC Style Generation**: Generate tRPC procedures instead of REST controllers
- โ
**Type-Safe APIs**: Full end-to-end type safety from backend to frontend
- โ
**CLI Integration**: `--trpc-style` flag and `--set-trpc-style` configuration
- โ
**Smart Templates**: New tRPC procedure, router, and test templates
- โ
**Same Business Logic**: Reuses existing handlers, repository, types, and validators
- โ
**Conditional Generation**: Switch between tRPC and REST styles seamlessly
**๐ข Monorepo Support**
- โ
**Target Directory**: `--target-dir` flag for generating in specific directories
- โ
**Flexible Paths**: Support for absolute and relative target paths
- โ
**Root Generation**: Generate APIs from monorepo root without cd commands
- โ
**Global Installation**: Improved compatibility with workspace protocols
**๐ฏ Enhanced Developer Experience**
- โ
**Interactive tRPC Setup**: Prompts for setting tRPC style preference
- โ
**Configuration Management**: Persistent tRPC style settings in config file
- โ
**Comprehensive Documentation**: Complete tRPC setup and usage examples
- โ
**Performance Benefits**: Direct procedure calls with built-in validation
### v3.5.0 - Major Code Generation Revolution ๐
**๐ง Handler Destructuring Revolution**
- โ
**Modern TypeScript Patterns**: All handlers now use object destructuring
- โ
**Clean Parameter Handling**: `({ name, email, requestId }: HandlerParams) => {}`
- โ
**Type-Safe Function Signatures**: Full TypeScript inference and validation
- โ
**Repository Consistency**: Matching destructuring patterns across all layers
**๐ Intelligent Validation & Auto-Population**
- โ
**Smart Pattern Recognition**: Email, URL, phone, UUID auto-detection
- โ
**Realistic Default Fields**: `name`, `description`, `status` in every module
- โ
**Module-Specific IDs**: `todoId`, `userId`, `productId` instead of generic `id`
- โ
**Enhanced Type System**: Better optional field handling in UPDATE operations
**๐๏ธ Framework & Architecture Improvements**
- โ
**Hono Compatibility**: Full support for Hono framework with destructuring
- โ
**Express Enhancement**: Improved Express.js templates with modern patterns
- โ
**Clean Architecture**: Refined handler โ repository pattern
- โ
**Type-First Development**: Types drive intelligent code generation
**โจ Developer Experience & Quality**
- โ
**Production-Ready Code**: Realistic fields and professional patterns
- โ
**Zero Configuration Issues**: All generated code passes strict TypeScript
- โ
**Smart Naming**: Consistent professional naming across all generated files
- โ
**Enhanced Testing**: Tests automatically use exact type definitions
### v3.1.6 - TypeScript & Build Fixes ๐ง
**๐ง Critical Fixes:**
- โ
**TypeScript Strict Mode**: Fixed `'error' is of type 'unknown'` compilation errors
- โ
**Variable Naming**: Fixed invalid JavaScript identifiers in generated repository code
- โ
**Build Stability**: All generated code now passes strict TypeScript compilation
- โ
**Error Handling**: Improved error handling patterns for better type safety
**๐จ Code Quality Improvements:**
- โ
**Import Type**: All templates now use `import type` for type-only imports (TypeScript best practice)
- โ
**Dependency-Free**: Removed shared errors dependency from generated repositories
- โ
**Smart Variables**: Variable names now use camelCase regardless of input format
### v3.1.5 - Critical Bug Fix ๐
**๐ง Critical Fix:**
- โ
**Module Import Error**: Fixed `Cannot find module 'test-config-generator.service'` error
- โ
**Package Stability**: Temporarily disabled test config generation to ensure package works
- โ
**Global Installation**: Package now works correctly when installed globally
### v3.1.4 - Bug Fix Release ๐
**๐ง Critical Fix:**
- โ
**Missing Module Fix**: Fixed missing `test-config-generator.service` in published package
- โ
**Import Resolution**: Resolved module import errors when using the npm package globally
### v3.1.3 - Smart Naming System ๐จ
**๐ Major Enhancement: Smart Naming Transformation**
- โ
**Flexible Input**: Accept any naming format (`kebab-case`, `snake_case`, `camelCase`, `PascalCase`)
- โ
**Professional Output**: Generate consistent, industry-standard naming conventions
- โ
**Import Safety**: Eliminate path mismatches and file not found errors
- โ
**Framework Consistency**: Works seamlessly with both Express and Hono
**๐ง Technical Improvements:**
- โ
**Template System**: Updated all templates for consistent naming
- โ
**Path Resolution**: Fixed CLI path generation bugs
- โ
**Code Quality**: Professional naming throughout generated code
- โ
**Error Prevention**: No more invalid JavaScript identifiers
**๐ Examples:**
```bash
# All of these work perfectly now!
node-apis --name user-profile --crud # โ user-profile/ directory
node-apis --name blog_post --crud # โ blog-post/ directory
node-apis --name productCategory --crud # โ product-category/ directory
```
## ๐ License
MIT License - see the [LICENSE](LICENSE) file for details.
## ๐ Why Developers Love This Tool
> _"Finally, a code generator that creates code I actually want to use in production!"_
> _"The smart naming system is incredible - I can use any naming style and get perfect output!"_
> _"The comprehensive test suite saved me days of writing tests manually."_
> _"The performance monitoring and request tracing saved me hours of debugging."_
> _"Clean architecture out of the box - no more service layer spaghetti!"_
> _"The type-driven approach is genius - my handlers always match my data structure."_
> _"Integration tests that actually test the real API - brilliant!"_
> _"No more worrying about naming conventions - the generator handles it all professionally!"_
> _"The generated code passes TypeScript strict mode without any errors - amazing!"_
## ๐ **What You Get**
### **For CRUD APIs:**
- ๐๏ธ **22 files generated** (5 operat