@eqxjs/swagger-codegen
v1.0.0-beta.5
Published
CLI tool to generate NestJS modules, controllers, services, and DTOs from Swagger/OpenAPI files
Readme
Swagger NestJS Codegen
A TypeScript CLI tool to generate NestJS modules, controllers, services, and DTOs from Swagger/OpenAPI files.
📚 Quick Start Guide | 📖 Format Comparison | 🔄 OpenAPI vs Swagger
Features
- ✅ Parse Swagger/OpenAPI 2.0 and 3.0 files (JSON or YAML)
- ✅ Generate DTOs from request/response schemas with
@ApiPropertydecorators - ✅ Generate Services with typed method signatures and JSDoc comments
- ✅ Generate Controllers with proper HTTP method decorators and route paths
- ✅ Generate Modules with proper dependency injection setup
- ✅ Generate Client Services (TypeScript + Axios) for calling APIs
- ✅ Support for path parameters, query parameters, and request bodies
- ✅ Support for array responses and nested schemas
- ✅ Automatic type inference from Swagger schemas
- ✅ Multiple generation modes: server, client, or both
📖 See FORMATS.md for detailed JSON vs YAML format comparison 📖 See OPENAPI-COMPARISON.md for Swagger 2.0 vs OpenAPI 3.0 differences
Example Files Included
| File | Format | Version | Description |
|------|--------|---------|-------------|
| example-swagger.json | JSON | Swagger 2.0 | Users & Posts API |
| example-swagger.yaml | YAML | Swagger 2.0 | Users & Posts API |
| openapi3-example.json | JSON | OpenAPI 3.0 | Products & Categories API |
| openapi3-example.yaml | YAML | OpenAPI 3.0 | Products & Categories API |
Installation
From NPM
npm install -g @eqxjs/swagger-codegenFrom Source
git clone <repository-url>
cd swagger-nestjs-codegen
npm install
npm run buildUsage
Generation Modes
The generator supports three modes:
server(default): Generate NestJS server-side code (controllers, services, modules)client: Generate TypeScript client services using Axiosboth: Generate both server and client code
Development Mode
# Server mode (default) - Generate NestJS controllers, services, and modules
npm run dev -- generate -i ./example-swagger.json -o ./generated
# Client mode - Generate TypeScript client services with Axios
npm run dev -- generate -i ./example-swagger.json -o ./generated --mode client
# Both modes - Generate both server and client code
npm run dev -- generate -i ./example-swagger.json -o ./generated --mode both
# Swagger 2.0 - JSON format
npm run dev -- generate -i ./example-swagger.json -o ./generated
# Swagger 2.0 - YAML format
npm run dev -- generate -i ./example-swagger.yaml -o ./generated
# OpenAPI 3.0 - JSON format
npm run dev -- generate -i ./openapi3-example.json -o ./generated
# OpenAPI 3.0 - YAML format
npm run dev -- generate -i ./openapi3-example.yaml -o ./generatedProduction Mode
# Using the global CLI
eqxjs-swagger-codegen generate -i ./swagger.json -o ./generated
# Using npx (no installation required)
npx @eqxjs/swagger-codegen generate -i ./swagger.json -o ./generated
# With YAML files
eqxjs-swagger-codegen generate -i ./swagger.yaml -o ./generated
# Local installation
node dist/cli.js generate -i ./swagger.json -o ./generatedCommand Options
eqxjs-swagger-codegen generate [options]
Options:
-i, --input <path> Path to Swagger/OpenAPI file (JSON or YAML) [required]
-o, --output <path> Output directory for generated files (default: "./generated")
-m, --mode <mode> Generation mode: server, client, or both (default: "server")
--with-test Generate test files (.spec.ts) for all generated files
--with-validate Add class-validator decorators to DTOs for validation
--only-dtos Generate only DTOs (skip services, controllers, modules)
-h, --help Display help for commandGenerating with Test Files
Use the --with-test flag to automatically generate test files for all controllers, services, and DTOs:
# Generate with test files
eqxjs-swagger-codegen generate -i ./example-swagger.json -o ./generated --with-test
# Using npx
npx @eqxjs/swagger-codegen generate -i ./swagger.json -o ./generated --with-test
# Development mode
npm run dev -- generate -i ./example-swagger.json -o ./generated --with-testGenerating with Validation Decorators
Use the --with-validate flag to add class-validator decorators to all DTO properties:
# Generate DTOs with validation decorators
eqxjs-swagger-codegen generate -i ./swagger.json -o ./generated --with-validate
# Combine with test generation
eqxjs-swagger-codegen generate -i ./swagger.json -o ./generated --with-validate --with-testGenerated validators include:
@IsString(),@IsNumber(),@IsInt(),@IsBoolean(),@IsDate()for basic types@IsEmail()for email format@IsUUID()for UUID format@IsUrl()for URL format@IsEnum()for enum values@IsArray()with@IsString({ each: true })for arrays@ValidateNested()with@Type()for nested objects@Min(),@Max()for number constraints@MinLength(),@MaxLength()for string length@Matches()for regex patterns
Example output:
import { ApiProperty } from '@nestjs/swagger';
import { IsString, IsEmail, IsInt, Min } from 'class-validator';
export class CreateUserDto {
@IsString()
@IsEmail()
@ApiProperty({ description: 'User email', type: String })
email!: string;
@IsInt()
@Min(18)
@ApiProperty({ description: 'User age', type: Number })
age!: number;
}Generating Only DTOs
Use the --only-dtos flag to generate only Data Transfer Objects without services, controllers, or modules:
# Generate only DTOs
eqxjs-swagger-codegen generate -i ./swagger.json -o ./dtos --only-dtos
# DTOs with validators
eqxjs-swagger-codegen generate -i ./swagger.json -o ./dtos --only-dtos --with-validateThis is useful when you:
- Only need the data models for a separate project
- Want to share DTOs between multiple services
- Are building a monorepo and need consistent type definitions
- Want to generate TypeScript interfaces from your API spec
This will create test files alongside their corresponding source files:
- Controller specs: Test files with mocked services and test cases for each endpoint
- Service specs: Test files with basic setup and method existence checks
- DTO specs: Test files with class-validator integration for validating DTOs
Example output:
generated/
├── dtos/
│ ├── user.dto.ts
│ └── post.dto.ts
├── users/
│ ├── users.service.ts
│ ├── users.controller.ts
│ └── users.module.ts
├── posts/
│ ├── posts.service.ts
│ ├── posts.controller.ts
│ └── posts.module.ts
└── tests/ # 🧪 Test files with same structure
├── dtos/
│ ├── user.dto.spec.ts
│ └── post.dto.spec.ts
├── users/
│ ├── users.controller.spec.ts
│ └── users.service.spec.ts
└── posts/
├── posts.controller.spec.ts
└── posts.service.spec.tsGenerated File Structure
Server Mode (default)
output/
├── dtos/
│ ├── user.dto.ts
│ ├── create-user-dto.dto.ts
│ ├── update-user-dto.dto.ts
│ ├── post.dto.ts
│ └── create-post-dto.dto.ts
├── users/
│ ├── users.service.ts
│ ├── users.controller.ts
│ └── users.module.ts
└── posts/
├── posts.service.ts
├── posts.controller.ts
└── posts.module.tsClient Mode
output/
├── dtos/
│ └── (same as server mode)
├── users/
│ └── users.client.ts
└── posts/
└── posts.client.tsBoth Mode
output/
├── dtos/
│ └── (shared DTOs)
├── users/
│ ├── users.service.ts # NestJS service
│ ├── users.controller.ts # NestJS controller
│ ├── users.module.ts # NestJS module
│ └── users.client.ts # Client service (Axios)
└── posts/
├── posts.service.ts
├── posts.controller.ts
├── posts.module.ts
└── posts.client.tsNote: Service, controller, and module for each resource are grouped together in the same folder by tag name.
App Module Auto-Generation
When generating in server or both modes, the tool automatically creates or updates an app.module.ts file in the output directory that imports all generated feature modules.
Features:
- ✅ Auto-creates
app.module.tsif it doesn't exist - ✅ Auto-updates existing
app.module.tswith all generated modules - ✅ Preserves custom imports (e.g.,
ConfigModule,DatabaseModule, etc.) - ✅ Updates module imports array automatically
Example Generated app.module.ts:
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';
import { PostsModule } from './posts/posts.module';
@Module({
imports: [
UsersModule,
PostsModule
],
})
export class AppModule {}With Custom Imports:
If your app.module.ts already has custom imports like ConfigModule, they will be preserved:
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config'; // ✅ Preserved
import { UsersModule } from './users/users.module';
import { PostsModule } from './posts/posts.module';
@Module({
imports: [
UsersModule,
PostsModule
],
})
export class AppModule {}Note: The generator will replace all feature module imports but preserve any custom third-party module imports you've added.
Example
Input Swagger File (JSON)
{
"swagger": "2.0",
"info": { "title": "Example API", "version": "1.0.0" },
"paths": {
"/users": {
"get": {
"tags": ["users"],
"summary": "Get all users",
"responses": {
"200": {
"schema": {
"type": "array",
"items": { "$ref": "#/definitions/User" }
}
}
}
}
}
},
"definitions": {
"User": {
"type": "object",
"required": ["id", "email"],
"properties": {
"id": { "type": "string" },
"email": { "type": "string", "format": "email" }
}
}
}
}Input Swagger File (YAML)
swagger: '2.0'
info:
title: Example API
version: 1.0.0
paths:
/users:
get:
tags:
- users
summary: Get all users
responses:
'200':
schema:
type: array
items:
$ref: '#/definitions/User'
definitions:
User:
type: object
required:
- id
- email
properties:
id:
type: string
email:
type: string
format: emailGenerated DTO
import { ApiProperty } from '@nestjs/swagger';
export class User {
@ApiProperty({ description: 'User ID', type: String })
id: string;
@ApiProperty({ description: 'User email address', type: String })
email: string;
}Generated Controller
import { Controller, Get } from '@nestjs/common';
import { ApiTags, ApiOperation } from '@nestjs/swagger';
import { UsersService } from '../services/users.service';
@ApiTags('users')
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@ApiOperation({ summary: 'Get all users' })
@Get('')
async getUsers(): Promise<any> {
return this.usersService.getUsers();
}
}Generated Service
import { Injectable } from '@nestjs/common';
@Injectable()
export class UsersService {
constructor() {}
/**
* Get all users
*/
async getUsers(): Promise<any> {
// TODO: Implement getUsers
throw new Error('Method not implemented');
}
}Using Client Services
When generating in client or both mode, the tool creates TypeScript client services using Axios:
Generated Client Service
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
import { User } from '../dtos/user.dto';
export class UsersService {
private axios: AxiosInstance;
constructor(baseURL: string, config?: AxiosRequestConfig) {
this.axios = axios.create({
baseURL,
...config,
});
}
/**
* Get all users
*/
async getUsers(): Promise<User[]> {
const response = await this.axios.get(`/users`);
return response.data;
}
/**
* Get user by ID
*/
async getUserById(id: string): Promise<User> {
const response = await this.axios.get(`/users/${id}`);
return response.data;
}
}Usage Example
import { UsersService } from './generated/users/users.client';
// Create service instance
const usersService = new UsersService('https://api.example.com', {
headers: {
'Authorization': 'Bearer YOUR_TOKEN'
}
});
// Use the service
async function fetchUsers() {
try {
const users = await usersService.getUsers();
console.log('Users:', users);
const user = await usersService.getUserById('123');
console.log('User:', user);
} catch (error) {
console.error('Error:', error);
}
}Client Features
- ✅ Automatic URL path parameter substitution
- ✅ Query parameter support
- ✅ Request body handling (POST, PUT, PATCH)
- ✅ Typed responses using generated DTOs
- ✅ Configurable Axios instance (headers, interceptors, etc.)
Development
Project Structure
src/
├── cli.ts # CLI entry point
├── generator.ts # Main orchestrator
├── parser.ts # Swagger file parser
├── types.ts # TypeScript type definitions
├── utils.ts # Utility functions
├── file-writer.ts # File writing utilities
└── generators/
├── dto.generator.ts # DTO generation logic
├── service.generator.ts # Service generation logic
├── controller.generator.ts # Controller generation logic
└── module.generator.ts # Module generation logicBuilding
npm run buildWatching for Changes
npm run watchIntegration with NestJS Projects
After generating the code, you can integrate it into your NestJS project:
- Copy the generated files to your NestJS project's
srcdirectory - Import the
AppModuleor individual feature modules in your main application module - Implement the service methods with your business logic
- Add database integrations, validation pipes, guards, and interceptors as needed
// In your main.ts
import { AppModule } from './generated/app.module';
@Module({
imports: [
AppModule,
// ... other modules
],
})
export class MainAppModule {}License
MIT
