@eqxjs/swagger-codegen 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +230 -0
- package/FORMATS.md +180 -0
- package/OPENAPI-COMPARISON.md +355 -0
- package/QUICKSTART.md +118 -0
- package/README.md +405 -0
- package/SUMMARY.md +184 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +49 -0
- package/dist/cli.js.map +1 -0
- package/dist/file-writer.d.ts +24 -0
- package/dist/file-writer.d.ts.map +1 -0
- package/dist/file-writer.js +95 -0
- package/dist/file-writer.js.map +1 -0
- package/dist/generator.d.ts +6 -0
- package/dist/generator.d.ts.map +1 -0
- package/dist/generator.js +104 -0
- package/dist/generator.js.map +1 -0
- package/dist/generators/client-service.generator.d.ts +6 -0
- package/dist/generators/client-service.generator.d.ts.map +1 -0
- package/dist/generators/client-service.generator.js +203 -0
- package/dist/generators/client-service.generator.js.map +1 -0
- package/dist/generators/controller.generator.d.ts +6 -0
- package/dist/generators/controller.generator.d.ts.map +1 -0
- package/dist/generators/controller.generator.js +241 -0
- package/dist/generators/controller.generator.js.map +1 -0
- package/dist/generators/dto.generator.d.ts +10 -0
- package/dist/generators/dto.generator.d.ts.map +1 -0
- package/dist/generators/dto.generator.js +221 -0
- package/dist/generators/dto.generator.js.map +1 -0
- package/dist/generators/module.generator.d.ts +10 -0
- package/dist/generators/module.generator.d.ts.map +1 -0
- package/dist/generators/module.generator.js +52 -0
- package/dist/generators/module.generator.js.map +1 -0
- package/dist/generators/service.generator.d.ts +6 -0
- package/dist/generators/service.generator.d.ts.map +1 -0
- package/dist/generators/service.generator.js +179 -0
- package/dist/generators/service.generator.js.map +1 -0
- package/dist/parser.d.ts +24 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +82 -0
- package/dist/parser.js.map +1 -0
- package/dist/types.d.ts +97 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +38 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +114 -0
- package/dist/utils.js.map +1 -0
- package/package.json +40 -0
- package/test-all-formats.sh +32 -0
- package/test.sh +27 -0
package/README.md
ADDED
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
# Swagger NestJS Codegen
|
|
2
|
+
|
|
3
|
+
A TypeScript CLI tool to generate NestJS modules, controllers, services, and DTOs from Swagger/OpenAPI files.
|
|
4
|
+
|
|
5
|
+
📚 **[Quick Start Guide](QUICKSTART.md)** | 📖 **[Format Comparison](FORMATS.md)** | 🔄 **[OpenAPI vs Swagger](OPENAPI-COMPARISON.md)**
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- ✅ Parse Swagger/OpenAPI 2.0 and 3.0 files (JSON or YAML)
|
|
10
|
+
- ✅ Generate DTOs from request/response schemas with `@ApiProperty` decorators
|
|
11
|
+
- ✅ Generate Services with typed method signatures and JSDoc comments
|
|
12
|
+
- ✅ Generate Controllers with proper HTTP method decorators and route paths
|
|
13
|
+
- ✅ Generate Modules with proper dependency injection setup
|
|
14
|
+
- ✅ Generate Client Services (TypeScript + Axios) for calling APIs
|
|
15
|
+
- ✅ Support for path parameters, query parameters, and request bodies
|
|
16
|
+
- ✅ Support for array responses and nested schemas
|
|
17
|
+
- ✅ Automatic type inference from Swagger schemas
|
|
18
|
+
- ✅ Multiple generation modes: server, client, or both
|
|
19
|
+
|
|
20
|
+
📖 **[See FORMATS.md](FORMATS.md) for detailed JSON vs YAML format comparison**
|
|
21
|
+
📖 **[See OPENAPI-COMPARISON.md](OPENAPI-COMPARISON.md) for Swagger 2.0 vs OpenAPI 3.0 differences**
|
|
22
|
+
|
|
23
|
+
## Example Files Included
|
|
24
|
+
|
|
25
|
+
| File | Format | Version | Description |
|
|
26
|
+
|------|--------|---------|-------------|
|
|
27
|
+
| `example-swagger.json` | JSON | Swagger 2.0 | Users & Posts API |
|
|
28
|
+
| `example-swagger.yaml` | YAML | Swagger 2.0 | Users & Posts API |
|
|
29
|
+
| `openapi3-example.json` | JSON | OpenAPI 3.0 | Products & Categories API |
|
|
30
|
+
| `openapi3-example.yaml` | YAML | OpenAPI 3.0 | Products & Categories API |
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install
|
|
36
|
+
npm run build
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
### Generation Modes
|
|
42
|
+
|
|
43
|
+
The generator supports three modes:
|
|
44
|
+
|
|
45
|
+
- **`server`** (default): Generate NestJS server-side code (controllers, services, modules)
|
|
46
|
+
- **`client`**: Generate TypeScript client services using Axios
|
|
47
|
+
- **`both`**: Generate both server and client code
|
|
48
|
+
|
|
49
|
+
### Development Mode
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Server mode (default) - Generate NestJS controllers, services, and modules
|
|
53
|
+
npm run dev -- generate -i ./example-swagger.json -o ./generated
|
|
54
|
+
|
|
55
|
+
# Client mode - Generate TypeScript client services with Axios
|
|
56
|
+
npm run dev -- generate -i ./example-swagger.json -o ./generated --mode client
|
|
57
|
+
|
|
58
|
+
# Both modes - Generate both server and client code
|
|
59
|
+
npm run dev -- generate -i ./example-swagger.json -o ./generated --mode both
|
|
60
|
+
|
|
61
|
+
# Swagger 2.0 - JSON format
|
|
62
|
+
npm run dev -- generate -i ./example-swagger.json -o ./generated
|
|
63
|
+
|
|
64
|
+
# Swagger 2.0 - YAML format
|
|
65
|
+
npm run dev -- generate -i ./example-swagger.yaml -o ./generated
|
|
66
|
+
|
|
67
|
+
# OpenAPI 3.0 - JSON format
|
|
68
|
+
npm run dev -- generate -i ./openapi3-example.json -o ./generated
|
|
69
|
+
|
|
70
|
+
# OpenAPI 3.0 - YAML format
|
|
71
|
+
npm run dev -- generate -i ./openapi3-example.yaml -o ./generated
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Production Mode
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Build the project first
|
|
78
|
+
npm run build
|
|
79
|
+
|
|
80
|
+
# Run the CLI with JSON
|
|
81
|
+
node dist/cli.js generate -i ./swagger.json -o ./generated
|
|
82
|
+
|
|
83
|
+
# Run the CLI with YAML
|
|
84
|
+
node dist/cli.js generate -i ./swagger.yaml -o ./generated
|
|
85
|
+
|
|
86
|
+
# Or use the npm script
|
|
87
|
+
npm start -- generate -i ./swagger.json -o ./generated
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Command Options
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
swagger-nestjs-codegen generate [options]
|
|
94
|
+
|
|
95
|
+
Options:
|
|
96
|
+
-i, --input <path> Path to Swagger/OpenAPI file (JSON or YAML) [required]
|
|
97
|
+
-o, --output <path> Output directory for generated files (default: "./generated")
|
|
98
|
+
-h, --help Display help for command
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Generated File Structure
|
|
102
|
+
|
|
103
|
+
### Server Mode (default)
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
output/
|
|
107
|
+
├── dtos/
|
|
108
|
+
│ ├── user.dto.ts
|
|
109
|
+
│ ├── create-user-dto.dto.ts
|
|
110
|
+
│ ├── update-user-dto.dto.ts
|
|
111
|
+
│ ├── post.dto.ts
|
|
112
|
+
│ └── create-post-dto.dto.ts
|
|
113
|
+
├── users/
|
|
114
|
+
│ ├── users.service.ts
|
|
115
|
+
│ ├── users.controller.ts
|
|
116
|
+
│ └── users.module.ts
|
|
117
|
+
└── posts/
|
|
118
|
+
├── posts.service.ts
|
|
119
|
+
├── posts.controller.ts
|
|
120
|
+
└── posts.module.ts
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Client Mode
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
output/
|
|
127
|
+
├── dtos/
|
|
128
|
+
│ └── (same as server mode)
|
|
129
|
+
├── users/
|
|
130
|
+
│ └── users.client.ts
|
|
131
|
+
└── posts/
|
|
132
|
+
└── posts.client.ts
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Both Mode
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
output/
|
|
139
|
+
├── dtos/
|
|
140
|
+
│ └── (shared DTOs)
|
|
141
|
+
├── users/
|
|
142
|
+
│ ├── users.service.ts # NestJS service
|
|
143
|
+
│ ├── users.controller.ts # NestJS controller
|
|
144
|
+
│ ├── users.module.ts # NestJS module
|
|
145
|
+
│ └── users.client.ts # Client service (Axios)
|
|
146
|
+
└── posts/
|
|
147
|
+
├── posts.service.ts
|
|
148
|
+
├── posts.controller.ts
|
|
149
|
+
├── posts.module.ts
|
|
150
|
+
└── posts.client.ts
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Note:** Service, controller, and module for each resource are grouped together in the same folder by tag name.
|
|
154
|
+
|
|
155
|
+
## Example
|
|
156
|
+
|
|
157
|
+
### Input Swagger File (JSON)
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
{
|
|
161
|
+
"swagger": "2.0",
|
|
162
|
+
"info": { "title": "Example API", "version": "1.0.0" },
|
|
163
|
+
"paths": {
|
|
164
|
+
"/users": {
|
|
165
|
+
"get": {
|
|
166
|
+
"tags": ["users"],
|
|
167
|
+
"summary": "Get all users",
|
|
168
|
+
"responses": {
|
|
169
|
+
"200": {
|
|
170
|
+
"schema": {
|
|
171
|
+
"type": "array",
|
|
172
|
+
"items": { "$ref": "#/definitions/User" }
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
"definitions": {
|
|
180
|
+
"User": {
|
|
181
|
+
"type": "object",
|
|
182
|
+
"required": ["id", "email"],
|
|
183
|
+
"properties": {
|
|
184
|
+
"id": { "type": "string" },
|
|
185
|
+
"email": { "type": "string", "format": "email" }
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Input Swagger File (YAML)
|
|
193
|
+
|
|
194
|
+
```yaml
|
|
195
|
+
swagger: '2.0'
|
|
196
|
+
info:
|
|
197
|
+
title: Example API
|
|
198
|
+
version: 1.0.0
|
|
199
|
+
paths:
|
|
200
|
+
/users:
|
|
201
|
+
get:
|
|
202
|
+
tags:
|
|
203
|
+
- users
|
|
204
|
+
summary: Get all users
|
|
205
|
+
responses:
|
|
206
|
+
'200':
|
|
207
|
+
schema:
|
|
208
|
+
type: array
|
|
209
|
+
items:
|
|
210
|
+
$ref: '#/definitions/User'
|
|
211
|
+
definitions:
|
|
212
|
+
User:
|
|
213
|
+
type: object
|
|
214
|
+
required:
|
|
215
|
+
- id
|
|
216
|
+
- email
|
|
217
|
+
properties:
|
|
218
|
+
id:
|
|
219
|
+
type: string
|
|
220
|
+
email:
|
|
221
|
+
type: string
|
|
222
|
+
format: email
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Generated DTO
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
import { ApiProperty } from '@nestjs/swagger';
|
|
229
|
+
|
|
230
|
+
export class User {
|
|
231
|
+
@ApiProperty({ description: 'User ID', type: String })
|
|
232
|
+
id: string;
|
|
233
|
+
|
|
234
|
+
@ApiProperty({ description: 'User email address', type: String })
|
|
235
|
+
email: string;
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Generated Controller
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import { Controller, Get } from '@nestjs/common';
|
|
243
|
+
import { ApiTags, ApiOperation } from '@nestjs/swagger';
|
|
244
|
+
import { UsersService } from '../services/users.service';
|
|
245
|
+
|
|
246
|
+
@ApiTags('users')
|
|
247
|
+
@Controller('users')
|
|
248
|
+
export class UsersController {
|
|
249
|
+
constructor(private readonly usersService: UsersService) {}
|
|
250
|
+
|
|
251
|
+
@ApiOperation({ summary: 'Get all users' })
|
|
252
|
+
@Get('')
|
|
253
|
+
async getUsers(): Promise<any> {
|
|
254
|
+
return this.usersService.getUsers();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Generated Service
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
import { Injectable } from '@nestjs/common';
|
|
263
|
+
|
|
264
|
+
@Injectable()
|
|
265
|
+
export class UsersService {
|
|
266
|
+
constructor() {}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Get all users
|
|
270
|
+
*/
|
|
271
|
+
async getUsers(): Promise<any> {
|
|
272
|
+
// TODO: Implement getUsers
|
|
273
|
+
throw new Error('Method not implemented');
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Using Client Services
|
|
279
|
+
|
|
280
|
+
When generating in `client` or `both` mode, the tool creates TypeScript client services using Axios:
|
|
281
|
+
|
|
282
|
+
### Generated Client Service
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
|
|
286
|
+
import { User } from '../dtos/user.dto';
|
|
287
|
+
|
|
288
|
+
export class UsersService {
|
|
289
|
+
private axios: AxiosInstance;
|
|
290
|
+
|
|
291
|
+
constructor(baseURL: string, config?: AxiosRequestConfig) {
|
|
292
|
+
this.axios = axios.create({
|
|
293
|
+
baseURL,
|
|
294
|
+
...config,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Get all users
|
|
300
|
+
*/
|
|
301
|
+
async getUsers(): Promise<User[]> {
|
|
302
|
+
const response = await this.axios.get(`/users`);
|
|
303
|
+
return response.data;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Get user by ID
|
|
308
|
+
*/
|
|
309
|
+
async getUserById(id: string): Promise<User> {
|
|
310
|
+
const response = await this.axios.get(`/users/${id}`);
|
|
311
|
+
return response.data;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Usage Example
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
import { UsersService } from './generated/users/users.client';
|
|
320
|
+
|
|
321
|
+
// Create service instance
|
|
322
|
+
const usersService = new UsersService('https://api.example.com', {
|
|
323
|
+
headers: {
|
|
324
|
+
'Authorization': 'Bearer YOUR_TOKEN'
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// Use the service
|
|
329
|
+
async function fetchUsers() {
|
|
330
|
+
try {
|
|
331
|
+
const users = await usersService.getUsers();
|
|
332
|
+
console.log('Users:', users);
|
|
333
|
+
|
|
334
|
+
const user = await usersService.getUserById('123');
|
|
335
|
+
console.log('User:', user);
|
|
336
|
+
} catch (error) {
|
|
337
|
+
console.error('Error:', error);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Client Features
|
|
343
|
+
|
|
344
|
+
- ✅ Automatic URL path parameter substitution
|
|
345
|
+
- ✅ Query parameter support
|
|
346
|
+
- ✅ Request body handling (POST, PUT, PATCH)
|
|
347
|
+
- ✅ Typed responses using generated DTOs
|
|
348
|
+
- ✅ Configurable Axios instance (headers, interceptors, etc.)
|
|
349
|
+
|
|
350
|
+
## Development
|
|
351
|
+
|
|
352
|
+
### Project Structure
|
|
353
|
+
|
|
354
|
+
```
|
|
355
|
+
src/
|
|
356
|
+
├── cli.ts # CLI entry point
|
|
357
|
+
├── generator.ts # Main orchestrator
|
|
358
|
+
├── parser.ts # Swagger file parser
|
|
359
|
+
├── types.ts # TypeScript type definitions
|
|
360
|
+
├── utils.ts # Utility functions
|
|
361
|
+
├── file-writer.ts # File writing utilities
|
|
362
|
+
└── generators/
|
|
363
|
+
├── dto.generator.ts # DTO generation logic
|
|
364
|
+
├── service.generator.ts # Service generation logic
|
|
365
|
+
├── controller.generator.ts # Controller generation logic
|
|
366
|
+
└── module.generator.ts # Module generation logic
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Building
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
npm run build
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Watching for Changes
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
npm run watch
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
## Integration with NestJS Projects
|
|
382
|
+
|
|
383
|
+
After generating the code, you can integrate it into your NestJS project:
|
|
384
|
+
|
|
385
|
+
1. Copy the generated files to your NestJS project's `src` directory
|
|
386
|
+
2. Import the `AppModule` or individual feature modules in your main application module
|
|
387
|
+
3. Implement the service methods with your business logic
|
|
388
|
+
4. Add database integrations, validation pipes, guards, and interceptors as needed
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
// In your main.ts
|
|
392
|
+
import { AppModule } from './generated/app.module';
|
|
393
|
+
|
|
394
|
+
@Module({
|
|
395
|
+
imports: [
|
|
396
|
+
AppModule,
|
|
397
|
+
// ... other modules
|
|
398
|
+
],
|
|
399
|
+
})
|
|
400
|
+
export class MainAppModule {}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## License
|
|
404
|
+
|
|
405
|
+
MIT
|
package/SUMMARY.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Project Summary
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
This is a complete TypeScript CLI tool for generating NestJS code from Swagger/OpenAPI specifications.
|
|
5
|
+
|
|
6
|
+
## What Was Built
|
|
7
|
+
|
|
8
|
+
### Core CLI Tool
|
|
9
|
+
- **Entry Point**: `src/cli.ts` - Commander-based CLI interface
|
|
10
|
+
- **Main Generator**: `src/generator.ts` - Orchestrates the entire generation process
|
|
11
|
+
- **Parser**: `src/parser.ts` - Parses and validates Swagger/OpenAPI files
|
|
12
|
+
- **Utilities**: `src/utils.ts` - Helper functions for naming conventions and type conversions
|
|
13
|
+
- **File Writer**: `src/file-writer.ts` - Handles file system operations
|
|
14
|
+
|
|
15
|
+
### Code Generators
|
|
16
|
+
Located in `src/generators/`:
|
|
17
|
+
1. **DTO Generator** (`dto.generator.ts`)
|
|
18
|
+
- Generates Data Transfer Objects from Swagger schemas
|
|
19
|
+
- Adds `@ApiProperty` decorators with proper metadata
|
|
20
|
+
- Handles nested objects, arrays, enums, and references
|
|
21
|
+
- Supports required/optional properties
|
|
22
|
+
|
|
23
|
+
2. **Service Generator** (`service.generator.ts`)
|
|
24
|
+
- Creates service classes with `@Injectable()` decorator
|
|
25
|
+
- Generates method signatures based on endpoints
|
|
26
|
+
- Includes JSDoc comments from Swagger descriptions
|
|
27
|
+
- Handles parameters and return types
|
|
28
|
+
|
|
29
|
+
3. **Controller Generator** (`controller.generator.ts`)
|
|
30
|
+
- Creates controller classes with proper HTTP method decorators
|
|
31
|
+
- Adds `@ApiTags` and `@ApiOperation` decorators
|
|
32
|
+
- Handles path parameters, query parameters, and request bodies
|
|
33
|
+
- Properly delegates to service methods
|
|
34
|
+
|
|
35
|
+
4. **Module Generator** (`module.generator.ts`)
|
|
36
|
+
- Generates feature modules for each resource tag
|
|
37
|
+
- Creates an app module that imports all feature modules
|
|
38
|
+
- Sets up proper dependency injection
|
|
39
|
+
|
|
40
|
+
## Features Implemented
|
|
41
|
+
|
|
42
|
+
✅ **Swagger/OpenAPI Support**
|
|
43
|
+
- Supports both Swagger 2.0 and OpenAPI 3.x
|
|
44
|
+
- Validates input files
|
|
45
|
+
- Handles JSON and YAML formats (see `example-swagger.json` and `example-swagger.yaml`)
|
|
46
|
+
|
|
47
|
+
✅ **Type-Safe Code Generation**
|
|
48
|
+
- TypeScript types inferred from schemas
|
|
49
|
+
- Proper type annotations throughout
|
|
50
|
+
- Support for complex types (arrays, nested objects, enums)
|
|
51
|
+
|
|
52
|
+
✅ **NestJS Best Practices**
|
|
53
|
+
- Proper decorator usage
|
|
54
|
+
- Dependency injection setup
|
|
55
|
+
- Modular architecture
|
|
56
|
+
- Swagger documentation decorators
|
|
57
|
+
|
|
58
|
+
✅ **Naming Conventions**
|
|
59
|
+
- PascalCase for classes
|
|
60
|
+
- camelCase for methods and properties
|
|
61
|
+
- kebab-case for file names
|
|
62
|
+
- Proper pluralization
|
|
63
|
+
|
|
64
|
+
✅ **Path Handling**
|
|
65
|
+
- Converts `{id}` to `:id` format for NestJS
|
|
66
|
+
- Extracts base paths from endpoints
|
|
67
|
+
- Groups endpoints by tags
|
|
68
|
+
|
|
69
|
+
## Generated Code Structure
|
|
70
|
+
|
|
71
|
+
For each Swagger file, the tool generates:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
output/
|
|
75
|
+
├── dtos/ # Data Transfer Objects
|
|
76
|
+
│ ├── *.dto.ts # Schema-based DTOs with @ApiProperty
|
|
77
|
+
├── users/ # User feature module (by tag)
|
|
78
|
+
│ ├── users.service.ts # Injectable service with method stubs
|
|
79
|
+
│ ├── users.controller.ts # Controller with route decorators
|
|
80
|
+
│ └── users.module.ts # Module definition with DI setup
|
|
81
|
+
├── posts/ # Post feature module (by tag)
|
|
82
|
+
│ ├── posts.service.ts
|
|
83
|
+
│ ├── posts.controller.ts
|
|
84
|
+
│ └── posts.module.ts
|
|
85
|
+
├── app.module.ts # Root application module
|
|
86
|
+
└── index.ts # Barrel export file
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Structure:** Each resource (tag) is organized in its own folder with service, controller, and module grouped together.
|
|
90
|
+
|
|
91
|
+
## Usage
|
|
92
|
+
|
|
93
|
+
### Installation
|
|
94
|
+
```bash
|
|
95
|
+
npm install
|
|
96
|
+
npm run build
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Generate Code
|
|
100
|
+
```bash
|
|
101
|
+
# Swagger 2.0
|
|
102
|
+
npm run dev -- generate -i ./example-swagger.json -o ./generated
|
|
103
|
+
npm run dev -- generate -i ./example-swagger.yaml -o ./generated
|
|
104
|
+
|
|
105
|
+
# OpenAPI 3.0
|
|
106
|
+
npm run dev -- generate -i ./openapi3-example.json -o ./generated
|
|
107
|
+
npm run dev -- generate -i ./openapi3-example.yaml -o ./generated
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Test
|
|
111
|
+
```bash
|
|
112
|
+
npm test
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Example Output
|
|
116
|
+
|
|
117
|
+
### Swagger 2.0 Examples
|
|
118
|
+
From `example-swagger.json` / `example-swagger.yaml`:
|
|
119
|
+
- **5 DTOs**: User, CreateUserDto, UpdateUserDto, Post, CreatePostDto
|
|
120
|
+
- **2 Services**: UsersService, PostsService
|
|
121
|
+
- **2 Controllers**: UsersController, PostsController
|
|
122
|
+
- **2 Modules**: UsersModule, PostsModule
|
|
123
|
+
- **1 App Module**: AppModule
|
|
124
|
+
- **1 Index file**: index.ts
|
|
125
|
+
|
|
126
|
+
### OpenAPI 3.0 Examples
|
|
127
|
+
From `openapi3-example.json` / `openapi3-example.yaml`:
|
|
128
|
+
- **6 DTOs**: Product, CreateProductDto, UpdateProductDto, Category, CreateCategoryDto, Error
|
|
129
|
+
- **2 Services**: ProductsService, CategoriesService
|
|
130
|
+
- **2 Controllers**: ProductsController, CategoriesController
|
|
131
|
+
- **2 Modules**: ProductsModule, CategoriesModule
|
|
132
|
+
- **1 App Module**: AppModule
|
|
133
|
+
- **1 Index file**: index.ts
|
|
134
|
+
|
|
135
|
+
## Technical Stack
|
|
136
|
+
|
|
137
|
+
- **TypeScript 5.3.3** - Type-safe development
|
|
138
|
+
- **Commander 11.1.0** - CLI framework
|
|
139
|
+
- **Swagger Parser 10.0.3** - Swagger/OpenAPI parsing and validation
|
|
140
|
+
- **Chalk 4.1.2** - Terminal output coloring
|
|
141
|
+
- **fs-extra 11.2.0** - Enhanced file system operations
|
|
142
|
+
|
|
143
|
+
## Key Algorithms
|
|
144
|
+
|
|
145
|
+
1. **Schema Resolution**: Resolves `$ref` references in Swagger schemas
|
|
146
|
+
2. **Endpoint Grouping**: Groups API endpoints by tags for modular generation
|
|
147
|
+
3. **Type Inference**: Maps Swagger types to TypeScript types
|
|
148
|
+
4. **Name Conversion**: Converts between different naming conventions
|
|
149
|
+
5. **Code Generation**: Template-based code generation with proper imports
|
|
150
|
+
|
|
151
|
+
## Future Enhancements
|
|
152
|
+
|
|
153
|
+
Potential improvements:
|
|
154
|
+
- Support for authentication decorators (@UseGuards)
|
|
155
|
+
- Validation decorators (class-validator)
|
|
156
|
+
- Database integration (TypeORM/Prisma)
|
|
157
|
+
- Custom templates
|
|
158
|
+
- Configuration file support
|
|
159
|
+
- Incremental updates (don't overwrite manual changes)
|
|
160
|
+
- Unit test generation
|
|
161
|
+
|
|
162
|
+
## Project Statistics
|
|
163
|
+
|
|
164
|
+
- **Source Files**: 11 TypeScript files
|
|
165
|
+
- **Lines of Code**: ~1,500+ lines
|
|
166
|
+
- **Dependencies**: 4 runtime, 4 dev dependencies
|
|
167
|
+
- **Build Time**: < 5 seconds
|
|
168
|
+
- **Generation Time**: < 2 seconds for typical APIs
|
|
169
|
+
|
|
170
|
+
## Testing
|
|
171
|
+
|
|
172
|
+
Tested with:
|
|
173
|
+
- ✅ Swagger 2.0 specification (JSON and YAML)
|
|
174
|
+
- ✅ OpenAPI 3.0 format support
|
|
175
|
+
- ✅ Multiple resource types (users, posts)
|
|
176
|
+
- ✅ Various HTTP methods (GET, POST, PUT, DELETE)
|
|
177
|
+
- ✅ Path parameters, query parameters, body parameters
|
|
178
|
+
- ✅ Array responses
|
|
179
|
+
- ✅ Schema references
|
|
180
|
+
- ✅ Nested objects
|
|
181
|
+
|
|
182
|
+
## Conclusion
|
|
183
|
+
|
|
184
|
+
This CLI tool provides a complete, production-ready solution for generating NestJS boilerplate code from Swagger specifications. It follows NestJS best practices, generates type-safe code, and significantly speeds up the development process by automating the creation of DTOs, services, controllers, and modules.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const generator_1 = require("./generator");
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const program = new commander_1.Command();
|
|
12
|
+
program
|
|
13
|
+
.name('swagger-nestjs-codegen')
|
|
14
|
+
.description('Generate NestJS modules, controllers, services, and DTOs from Swagger/OpenAPI files')
|
|
15
|
+
.version('1.0.0');
|
|
16
|
+
program
|
|
17
|
+
.command('generate')
|
|
18
|
+
.description('Generate NestJS code from a Swagger file')
|
|
19
|
+
.requiredOption('-i, --input <path>', 'Path to Swagger/OpenAPI file (JSON or YAML)')
|
|
20
|
+
.option('-o, --output <path>', 'Output directory for generated files', './generated')
|
|
21
|
+
.option('-m, --mode <mode>', 'Generation mode: server, client, or both', 'server')
|
|
22
|
+
.action(async (options) => {
|
|
23
|
+
try {
|
|
24
|
+
const validModes = ['server', 'client', 'both'];
|
|
25
|
+
if (!validModes.includes(options.mode)) {
|
|
26
|
+
console.error(chalk_1.default.red(`❌ Invalid mode: ${options.mode}. Must be one of: ${validModes.join(', ')}`));
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
console.log(chalk_1.default.blue('🚀 Starting code generation...'));
|
|
30
|
+
console.log(chalk_1.default.gray(`Input: ${options.input}`));
|
|
31
|
+
console.log(chalk_1.default.gray(`Output: ${options.output}`));
|
|
32
|
+
console.log(chalk_1.default.gray(`Mode: ${options.mode}`));
|
|
33
|
+
const inputPath = path_1.default.resolve(process.cwd(), options.input);
|
|
34
|
+
const outputPath = path_1.default.resolve(process.cwd(), options.output);
|
|
35
|
+
await (0, generator_1.generateFromSwagger)(inputPath, outputPath, options.mode);
|
|
36
|
+
console.log(chalk_1.default.green('✅ Code generation completed successfully!'));
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.error(chalk_1.default.red('❌ Error during code generation:'));
|
|
40
|
+
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
|
|
41
|
+
if (error instanceof Error && error.stack) {
|
|
42
|
+
console.error(chalk_1.default.gray('\nStack trace:'));
|
|
43
|
+
console.error(chalk_1.default.gray(error.stack));
|
|
44
|
+
}
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
program.parse();
|
|
49
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;AAEA,yCAAoC;AACpC,kDAA0B;AAC1B,2CAAkD;AAClD,gDAAwB;AAExB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,wBAAwB,CAAC;KAC9B,WAAW,CAAC,qFAAqF,CAAC;KAClG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,0CAA0C,CAAC;KACvD,cAAc,CAAC,oBAAoB,EAAE,6CAA6C,CAAC;KACnF,MAAM,CAAC,qBAAqB,EAAE,sCAAsC,EAAE,aAAa,CAAC;KACpF,MAAM,CAAC,mBAAmB,EAAE,0CAA0C,EAAE,QAAQ,CAAC;KACjF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAChD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,mBAAmB,OAAO,CAAC,IAAI,qBAAqB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACtG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,UAAU,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAEjD,MAAM,SAAS,GAAG,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7D,MAAM,UAAU,GAAG,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAE/D,MAAM,IAAA,+BAAmB,EAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAE/D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC,CAAC;IACxE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC;QAC5D,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACjF,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC1C,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;YAC5C,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensure directory exists
|
|
3
|
+
*/
|
|
4
|
+
export declare function ensureDir(dirPath: string): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Write file to disk
|
|
7
|
+
*/
|
|
8
|
+
export declare function writeFile(filePath: string, content: string): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Check if file exists
|
|
11
|
+
*/
|
|
12
|
+
export declare function fileExists(filePath: string): Promise<boolean>;
|
|
13
|
+
/**
|
|
14
|
+
* Read file content
|
|
15
|
+
*/
|
|
16
|
+
export declare function readFile(filePath: string): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Create directory structure
|
|
19
|
+
*/
|
|
20
|
+
export declare function createDirectoryStructure(outputPath: string, tags: string[]): Promise<{
|
|
21
|
+
dtos: string;
|
|
22
|
+
tagDirs: Map<string, string>;
|
|
23
|
+
}>;
|
|
24
|
+
//# sourceMappingURL=file-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-writer.d.ts","sourceRoot":"","sources":["../src/file-writer.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhF;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEhE;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC1F,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,CAAC,CAaD"}
|