@eqxjs/swagger-codegen 1.0.0-beta.1 → 1.0.0-beta.2

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 CHANGED
@@ -2,183 +2,273 @@
2
2
 
3
3
  ## System Architecture
4
4
 
5
- ```
6
- ┌─────────────────────────────────────────────────────────────┐
7
- CLI Entry Point
8
- (src/cli.ts)
9
- │ Commander.js Interface │
10
- └──────────────────────────┬──────────────────────────────────┘
11
-
12
-
13
- ┌─────────────────────────────────────────────────────────────┐
14
- │ Main Generator
15
- │ (src/generator.ts) │
16
- │ Orchestrates the generation flow │
17
- └──────┬──────────────────┬──────────────────┬────────────────┘
18
- │ │ │
19
- ▼ ▼ ▼
20
- ┌───────────────┐ ┌─────────────┐ ┌──────────────────┐
21
- │ Swagger │ │ Utilities │ │ File Writer │
22
- │ Parser │ │ │ │ │
23
- (parser.ts) │ │ (utils.ts) │ │(file-writer.ts) │
24
- └───────┬───────┘ └──────┬──────┘ └────────┬─────────┘
25
- │ │ │
26
- │ ┌────────┴────────┐ │
27
- │ │ │ │
28
- ▼ ▼ ▼ ▼
29
- ┌────────────────────────────────────────────────────────┐
30
- │ Code Generators (src/generators/) │
31
- ├────────────┬─────────────┬──────────────┬──────────────┤
32
- DTO │ Service │ Controller │ Module │
33
- Generator │ Generator │ Generator │ Generator │
34
- └────────────┴─────────────┴──────────────┴──────────────┘
35
- │ │ │ │
36
- └───────────┴────────────┴──────────────┘
37
-
38
-
39
- ┌────────────────┐
40
- │ Output Files │
41
- │ (generated/) │
42
- └────────────────┘
5
+ ```mermaid
6
+ graph TD
7
+ CLI["CLI Entry Point<br/>(src/cli.ts)<br/>Commander.js Interface"]
8
+ MAIN["Main Generator<br/>(src/generator.ts)<br/>Orchestrates the generation flow"]
9
+ PARSER["Swagger Parser<br/>(parser.ts)"]
10
+ UTILS["Utilities<br/>(utils.ts)"]
11
+ WRITER["File Writer<br/>(file-writer.ts)"]
12
+ GENS["Code Generators<br/>(src/generators/)"]
13
+ DTO["DTO Generator"]
14
+ SERVICE["Service Generator"]
15
+ CONTROLLER["Controller Generator"]
16
+ MODULE["Module Generator"]
17
+ OUTPUT["Output Files<br/>(generated/)"]
18
+
19
+ CLI --> MAIN
20
+ MAIN --> PARSER
21
+ MAIN --> UTILS
22
+ MAIN --> WRITER
23
+ PARSER --> GENS
24
+ UTILS --> GENS
25
+ WRITER --> GENS
26
+ GENS --> DTO
27
+ GENS --> SERVICE
28
+ GENS --> CONTROLLER
29
+ GENS --> MODULE
30
+ DTO --> OUTPUT
31
+ SERVICE --> OUTPUT
32
+ CONTROLLER --> OUTPUT
33
+ MODULE --> OUTPUT
34
+
35
+ style CLI fill:#4FC3F7,stroke:#01579B,stroke-width:3px,color:#000
36
+ style MAIN fill:#FFB74D,stroke:#E65100,stroke-width:3px,color:#000
37
+ style GENS fill:#BA68C8,stroke:#4A148C,stroke-width:3px,color:#fff
38
+ style OUTPUT fill:#81C784,stroke:#1B5E20,stroke-width:3px,color:#000
43
39
  ```
44
40
 
45
41
  ## Data Flow
46
42
 
47
- ```
48
- 1. Input
49
- └─> Swagger/OpenAPI File (JSON/YAML)
50
-
51
- 2. Parsing
52
- └─> SwaggerParser.validate()
53
- └─> Validated SwaggerSpec object
54
-
55
- 3. Analysis
56
- ├─> Extract schemas (definitions/components.schemas)
57
- ├─> Group endpoints by tags
58
- └─> Resolve $ref references
59
-
60
- 4. Generation (Parallel)
61
- ├─> DTOs
62
- │ └─> For each schema:
63
- │ ├─> Generate class
64
- │ ├─> Add @ApiProperty decorators
65
- │ └─> Handle types, arrays, refs
66
-
67
- ├─> Services
68
- │ └─> For each tag:
69
- │ ├─> Generate @Injectable class
70
- │ ├─> Create method for each endpoint
71
- │ └─> Add JSDoc comments
72
-
73
- ├─> Controllers
74
- │ └─> For each tag:
75
- │ ├─> Generate @Controller class
76
- │ ├─> Add HTTP method decorators
77
- │ ├─> Add @ApiTags, @ApiOperation
78
- │ └─> Wire to service methods
79
-
80
- └─> Modules
81
- └─> For each tag:
82
- ├─> Generate @Module class
83
- ├─> Import controller & service
84
- └─> Configure providers/exports
85
-
86
- 5. Output
87
- └─> Write TypeScript files to disk
43
+ ```mermaid
44
+ graph LR
45
+ INPUT["1. Input<br/>Swagger/OpenAPI File<br/>(JSON/YAML)"]
46
+ PARSE["2. Parsing<br/>SwaggerParser.validate()<br/>→ Validated SwaggerSpec"]
47
+ ANALYZE["3. Analysis"]
48
+ SCHEMAS["Extract schemas<br/>(definitions/components)"]
49
+ TAGS["Group endpoints<br/>by tags"]
50
+ REFS["Resolve $ref<br/>references"]
51
+ GEN["4. Generation<br/>(Parallel)"]
52
+ DTOS["DTOs<br/>• Generate class<br/>• @ApiProperty decorators<br/>• Handle types, arrays, refs"]
53
+ SERVICES["Services<br/>• @Injectable class<br/>• Methods per endpoint<br/>• JSDoc comments"]
54
+ CONTROLLERS["Controllers<br/>• @Controller class<br/>• HTTP decorators<br/>• @ApiTags, @ApiOperation"]
55
+ MODULES["Modules<br/>• @Module class<br/>• Import controller & service<br/>• Configure providers"]
56
+ OUTPUT["5. Output<br/>Write TypeScript files<br/>to disk"]
57
+
58
+ INPUT --> PARSE
59
+ PARSE --> ANALYZE
60
+ ANALYZE --> SCHEMAS
61
+ ANALYZE --> TAGS
62
+ ANALYZE --> REFS
63
+ SCHEMAS --> GEN
64
+ TAGS --> GEN
65
+ REFS --> GEN
66
+ GEN --> DTOS
67
+ GEN --> SERVICES
68
+ GEN --> CONTROLLERS
69
+ GEN --> MODULES
70
+ DTOS --> OUTPUT
71
+ SERVICES --> OUTPUT
72
+ CONTROLLERS --> OUTPUT
73
+ MODULES --> OUTPUT
74
+
75
+ style INPUT fill:#42A5F5,stroke:#0D47A1,stroke-width:2px,color:#fff
76
+ style PARSE fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
77
+ style ANALYZE fill:#AB47BC,stroke:#4A148C,stroke-width:2px,color:#fff
78
+ style GEN fill:#EC407A,stroke:#880E4F,stroke-width:2px,color:#fff
79
+ style OUTPUT fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
88
80
  ```
89
81
 
90
82
  ## Naming Convention Flow
91
83
 
92
- ```
93
- Input: "/api/v1/user-profiles/{userId}"
94
-
95
- ┌──────────────────────────────────────┐
96
- │ Path Analysis │
97
- ├──────────────────────────────────────┤
98
- │ Extract tag: "user-profiles" │
99
- │ Extract params: ["userId"]
100
- └───────────┬──────────────────────────┘
101
-
102
-
103
- ┌──────────────────────────────────────┐
104
- Name Transformations │
105
- ├──────────────────────────────────────┤
106
- │ PascalCase: "UserProfiles"
107
- │ ├─> UserProfilesService │
108
- │ ├─> UserProfilesController │
109
- │ ├─> UserProfilesModule │
110
- │ └─> UserProfileDto │
111
- │ │
112
- camelCase: "userProfiles" │
113
- │ └─> userProfilesService (property) │
114
- │ │
115
- kebab-case: "user-profiles" │
116
- │ ├─> user-profiles.service.ts │
117
- │ ├─> user-profiles.controller.ts
118
- │ └─> user-profiles.module.ts │
119
- └───────────────────────────────────────┘
84
+ ```mermaid
85
+ graph TD
86
+ INPUT["Input Path<br/>/api/v1/user-profiles/{userId}"]
87
+ ANALYZE["Path Analysis<br/>• Extract tag: 'user-profiles'<br/>• Extract params: ['userId']"]
88
+ TRANSFORM["Name Transformations"]
89
+ PASCAL["PascalCase: 'UserProfiles'"]
90
+ CAMEL["camelCase: 'userProfiles'"]
91
+ KEBAB["kebab-case: 'user-profiles'"]
92
+
93
+ PS1["UserProfilesService"]
94
+ PS2["UserProfilesController"]
95
+ PS3["UserProfilesModule"]
96
+ PS4["UserProfileDto"]
97
+
98
+ CS1["userProfilesService<br/>(property)"]
99
+
100
+ KS1["user-profiles.service.ts"]
101
+ KS2["user-profiles.controller.ts"]
102
+ KS3["user-profiles.module.ts"]
103
+
104
+ INPUT --> ANALYZE
105
+ ANALYZE --> TRANSFORM
106
+ TRANSFORM --> PASCAL
107
+ TRANSFORM --> CAMEL
108
+ TRANSFORM --> KEBAB
109
+
110
+ PASCAL --> PS1
111
+ PASCAL --> PS2
112
+ PASCAL --> PS3
113
+ PASCAL --> PS4
114
+
115
+ CAMEL --> CS1
116
+
117
+ KEBAB --> KS1
118
+ KEBAB --> KS2
119
+ KEBAB --> KS3
120
+
121
+ style INPUT fill:#29B6F6,stroke:#01579B,stroke-width:2px,color:#000
122
+ style ANALYZE fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
123
+ style TRANSFORM fill:#AB47BC,stroke:#4A148C,stroke-width:2px,color:#fff
124
+ style PASCAL fill:#EF5350,stroke:#B71C1C,stroke-width:2px,color:#fff
125
+ style CAMEL fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
126
+ style KEBAB fill:#FFEE58,stroke:#F57F17,stroke-width:2px,color:#000
120
127
  ```
121
128
 
122
129
  ## Type Mapping
123
130
 
124
- ```
125
- Swagger Type TypeScript Type Decorator Type
126
- ─────────────────────────────────────────────────────────
127
- string -> string -> type: String
128
- integer -> number -> type: Number
129
- number -> number -> type: Number
130
- boolean -> boolean -> type: Boolean
131
- array -> T[] -> isArray: true
132
- object -> Record<string,any> -> type: Object
133
- string(date) -> Date -> type: Date
134
- string(date-time) -> Date -> type: Date
135
- $ref -> ClassName -> type: () => ClassName
136
- enum -> string -> enum: [values]
131
+ ```mermaid
132
+ graph LR
133
+ subgraph "Swagger Types"
134
+ ST1["string"]
135
+ ST2["integer"]
136
+ ST3["number"]
137
+ ST4["boolean"]
138
+ ST5["array"]
139
+ ST6["object"]
140
+ ST7["string(date)"]
141
+ ST8["string(date-time)"]
142
+ ST9["$ref"]
143
+ ST10["enum"]
144
+ end
145
+
146
+ subgraph "TypeScript Types"
147
+ TS1["string"]
148
+ TS2["number"]
149
+ TS3["number"]
150
+ TS4["boolean"]
151
+ TS5["T[]"]
152
+ TS6["Record&lt;string,any&gt;"]
153
+ TS7["Date"]
154
+ TS8["Date"]
155
+ TS9["ClassName"]
156
+ TS10["string"]
157
+ end
158
+
159
+ subgraph "Decorator Types"
160
+ DT1["type: String"]
161
+ DT2["type: Number"]
162
+ DT3["type: Number"]
163
+ DT4["type: Boolean"]
164
+ DT5["isArray: true"]
165
+ DT6["type: Object"]
166
+ DT7["type: Date"]
167
+ DT8["type: Date"]
168
+ DT9["type: () => ClassName"]
169
+ DT10["enum: [values]"]
170
+ end
171
+
172
+ ST1 --> TS1 --> DT1
173
+ ST2 --> TS2 --> DT2
174
+ ST3 --> TS3 --> DT3
175
+ ST4 --> TS4 --> DT4
176
+ ST5 --> TS5 --> DT5
177
+ ST6 --> TS6 --> DT6
178
+ ST7 --> TS7 --> DT7
179
+ ST8 --> TS8 --> DT8
180
+ ST9 --> TS9 --> DT9
181
+ ST10 --> TS10 --> DT10
182
+
183
+ style ST1 fill:#42A5F5,stroke:#0D47A1,stroke-width:2px,color:#fff
184
+ style ST2 fill:#42A5F5,stroke:#0D47A1,stroke-width:2px,color:#fff
185
+ style ST3 fill:#42A5F5,stroke:#0D47A1,stroke-width:2px,color:#fff
186
+ style ST4 fill:#42A5F5,stroke:#0D47A1,stroke-width:2px,color:#fff
187
+ style ST5 fill:#42A5F5,stroke:#0D47A1,stroke-width:2px,color:#fff
188
+ style ST6 fill:#42A5F5,stroke:#0D47A1,stroke-width:2px,color:#fff
189
+ style ST7 fill:#42A5F5,stroke:#0D47A1,stroke-width:2px,color:#fff
190
+ style ST8 fill:#42A5F5,stroke:#0D47A1,stroke-width:2px,color:#fff
191
+ style ST9 fill:#42A5F5,stroke:#0D47A1,stroke-width:2px,color:#fff
192
+ style ST10 fill:#42A5F5,stroke:#0D47A1,stroke-width:2px,color:#fff
193
+
194
+ style TS1 fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
195
+ style TS2 fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
196
+ style TS3 fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
197
+ style TS4 fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
198
+ style TS5 fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
199
+ style TS6 fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
200
+ style TS7 fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
201
+ style TS8 fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
202
+ style TS9 fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
203
+ style TS10 fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
204
+
205
+ style DT1 fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
206
+ style DT2 fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
207
+ style DT3 fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
208
+ style DT4 fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
209
+ style DT5 fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
210
+ style DT6 fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
211
+ style DT7 fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
212
+ style DT8 fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
213
+ style DT9 fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
214
+ style DT10 fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
137
215
  ```
138
216
 
139
217
  ## Generation Workflow Example
140
218
 
141
- ```
142
- Step 1: Parse Swagger
143
- Input: example-swagger.json
144
- Output: SwaggerSpec object
145
-
146
- Step 2: Extract Schemas
147
- Found: User, CreateUserDto, UpdateUserDto, Post, CreatePostDto
148
-
149
- Step 3: Group Endpoints
150
- Tags:
151
- ├─> users: [GET /users, POST /users, GET /users/{id}, ...]
152
- └─> posts: [GET /posts, POST /posts]
153
-
154
- Step 4: Generate DTOs
155
- ├─> user.dto.ts
156
- ├─> create-user-dto.dto.ts
157
- ├─> update-user-dto.dto.ts
158
- ├─> post.dto.ts
159
- └─> create-post-dto.dto.ts
160
-
161
- Step 5: Generate Services
162
- ├─> users.service.ts
163
- │ Methods: getUsers(), createUser(), getUserById(), ...
164
- └─> posts.service.ts
165
- Methods: getPosts(), createPost()
166
-
167
- Step 6: Generate Controllers
168
- ├─> users.controller.ts
169
- │ Routes: @Get(''), @Post(''), @Get(':id'), ...
170
- └─> posts.controller.ts
171
- Routes: @Get(''), @Post('')
172
-
173
- Step 7: Generate Modules
174
- ├─> users.module.ts
175
- ├─> posts.module.ts
176
- └─> app.module.ts (imports both)
177
-
178
- Step 8: Generate Index
179
- └─> index.ts (exports all)
180
-
181
- Done!
219
+ ```mermaid
220
+ graph TD
221
+ STEP1["Step 1: Parse Swagger<br/>Input: example-swagger.json<br/>Output: SwaggerSpec object"]
222
+ STEP2["Step 2: Extract Schemas<br/>Found: User, CreateUserDto,<br/>UpdateUserDto, Post, CreatePostDto"]
223
+ STEP3["Step 3: Group Endpoints<br/>Tags:<br/>• users: GET /users, POST /users, GET /users/{id}<br/>• posts: GET /posts, POST /posts"]
224
+ STEP4["Step 4: Generate DTOs"]
225
+ STEP5["Step 5: Generate Services"]
226
+ STEP6["Step 6: Generate Controllers"]
227
+ STEP7["Step 7: Generate Modules"]
228
+ STEP8["Step 8: Generate Index"]
229
+ DONE["✅ Done!"]
230
+
231
+ DTO1["user.dto.ts"]
232
+ DTO2["create-user-dto.dto.ts"]
233
+ DTO3["update-user-dto.dto.ts"]
234
+ DTO4["post.dto.ts"]
235
+ DTO5["create-post-dto.dto.ts"]
236
+
237
+ SVC1["users.service.ts<br/>Methods: getUsers(),<br/>createUser(), getUserById()"]
238
+ SVC2["posts.service.ts<br/>Methods: getPosts(),<br/>createPost()"]
239
+
240
+ CTL1["users.controller.ts<br/>Routes: @Get(''),<br/>@Post(''), @Get(':id')"]
241
+ CTL2["posts.controller.ts<br/>Routes: @Get(''),<br/>@Post('')"]
242
+
243
+ MOD1["users.module.ts"]
244
+ MOD2["posts.module.ts"]
245
+ MOD3["app.module.ts<br/>(imports both)"]
246
+
247
+ IDX["index.ts<br/>(exports all)"]
248
+
249
+ STEP1 --> STEP2
250
+ STEP2 --> STEP3
251
+ STEP3 --> STEP4
252
+ STEP4 --> DTO1 & DTO2 & DTO3 & DTO4 & DTO5
253
+ DTO1 & DTO2 & DTO3 & DTO4 & DTO5 --> STEP5
254
+ STEP5 --> SVC1 & SVC2
255
+ SVC1 & SVC2 --> STEP6
256
+ STEP6 --> CTL1 & CTL2
257
+ CTL1 & CTL2 --> STEP7
258
+ STEP7 --> MOD1 & MOD2 & MOD3
259
+ MOD1 & MOD2 & MOD3 --> STEP8
260
+ STEP8 --> IDX
261
+ IDX --> DONE
262
+
263
+ style STEP1 fill:#42A5F5,stroke:#0D47A1,stroke-width:2px,color:#fff
264
+ style STEP2 fill:#AB47BC,stroke:#4A148C,stroke-width:2px,color:#fff
265
+ style STEP3 fill:#FFA726,stroke:#E65100,stroke-width:2px,color:#000
266
+ style STEP4 fill:#EC407A,stroke:#880E4F,stroke-width:2px,color:#fff
267
+ style STEP5 fill:#66BB6A,stroke:#1B5E20,stroke-width:2px,color:#000
268
+ style STEP6 fill:#FFEE58,stroke:#F57F17,stroke-width:2px,color:#000
269
+ style STEP7 fill:#26A69A,stroke:#00695C,stroke-width:2px,color:#fff
270
+ style STEP8 fill:#FF7043,stroke:#BF360C,stroke-width:2px,color:#fff
271
+ style DONE fill:#4CAF50,stroke:#1B5E20,stroke-width:4px,color:#fff
182
272
  ```
183
273
 
184
274
  ## File Organization