fork of hey-api/openapi-ts because I need some additional things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs: add NestJS plugin research and requirements document.

+328
+328
docs/openapi-ts/plugins/nestjs-research.md
··· 1 + # NestJS Plugin Research & Requirements 2 + 3 + ## Context 4 + 5 + Investigate NestJS plugin following Fastify plugin pattern. Generate type-safe controller interfaces from OpenAPI specs for NestJS applications. 6 + 7 + ## Fastify Baseline 8 + 9 + **Current implementation:** 10 + - Location: `packages/openapi-ts/src/plugins/fastify/` 11 + - Output: `RouteHandlers` interface mapping operation IDs to typed handlers 12 + - Pattern: `RouteHandler<{ Body?, Headers?, Params?, Querystring?, Reply }>` 13 + - Size: ~155 lines core logic 14 + - Deps: `@hey-api/typescript` plugin 15 + - Runtime: Uses `fastify-openapi-glue` library for route registration 16 + - Example: `examples/openapi-ts-fastify/` 17 + - Docs: `docs/openapi-ts/plugins/fastify.md` (~100 lines) 18 + 19 + ## NestJS vs Fastify 20 + 21 + | Aspect | Fastify | NestJS | 22 + |--------|---------|--------| 23 + | **Style** | Functional handlers | Class-based controllers | 24 + | **Typing** | Type generics | DTOs + decorators | 25 + | **DI** | Manual | Built-in container | 26 + | **Runtime lib** | `fastify-openapi-glue` | `@nestjs/swagger` | 27 + | **Module system** | None (flat object) | `@Module` required | 28 + | **Parameters** | Generic types | Decorator metadata (`@Param`, `@Query`, `@Body`) | 29 + 30 + ## Research Questions 31 + 32 + ### High Priority (MVP) 33 + 34 + **1. Output Format** 35 + - Option A: Generate controller interface (recommended - mirrors Fastify pattern) 36 + - Option B: Generate controller class with decorators 37 + - Option C: Generate decorator metadata types 38 + 39 + **Recommendation**: Controller interface. Simple, type-safe, lets devs write decorators. 40 + 41 + **2. Method Mapping** 42 + - Map operation IDs to camelCase method names (matches SDK functions) 43 + - Example: `GET /pets` with operationId `listPets` → `listPets()` method 44 + 45 + **3. Type Structure** 46 + Request parameters: 47 + - Path params: `operation.parameters.path` → method param type 48 + - Query params: `operation.parameters.query` → method param type 49 + - Request body: `operation.body` → method param type 50 + - Headers: `operation.parameters.header` → method param type 51 + 52 + Response: 53 + - Success responses: `operation.responses` → Promise return type 54 + - Error responses: Include in union type 55 + 56 + **4. Platform Support** 57 + - NestJS supports both Express and Fastify adapters 58 + - Generated types should be adapter-agnostic 59 + - Let runtime decorators handle platform differences 60 + 61 + ### Medium Priority (Future) 62 + 63 + **5. @nestjs/swagger Integration** 64 + - Current: Generate standalone types 65 + - Future: Optionally generate `@ApiResponse()`, `@ApiOperation()` decorators 66 + - Requires config flag: `generateDecorators?: boolean` 67 + 68 + **6. Validation** 69 + - Current: Type-only validation via TypeScript 70 + - Future: Generate `class-validator` decorators in DTOs 71 + - Requires config flag: `generateValidation?: boolean` 72 + 73 + **7. Module Generation** 74 + - Current: Generate controller interface only 75 + - Future: Generate full `@Module()` setup 76 + - Requires config option: `moduleGeneration?: 'interface' | 'class' | 'module'` 77 + 78 + **8. DI Layer** 79 + - Current: Controller interface only 80 + - Future: Generate service interfaces for business logic separation 81 + - Common NestJS pattern: Controllers → Services → Repositories 82 + 83 + ### Low Priority (v2+) 84 + 85 + 9. Guards/interceptors/pipes type generation 86 + 10. Exception filters for typed error responses 87 + 11. SwaggerModule auto-configuration 88 + 12. Validation pipe integration 89 + 90 + ## Proposed MVP Output 91 + 92 + ### Generated Interface 93 + 94 + ```typescript 95 + // client/nestjs.gen.ts 96 + import type { 97 + ListPetsData, 98 + ListPetsResponses, 99 + CreatePetsData, 100 + CreatePetsResponses, 101 + ShowPetByIdData, 102 + ShowPetByIdResponses 103 + } from './types.gen'; 104 + 105 + export interface PetsController { 106 + listPets(query?: ListPetsData['query']): Promise<ListPetsResponses>; 107 + createPets(body: CreatePetsData['body']): Promise<CreatePetsResponses>; 108 + showPetById(params: ShowPetByIdData['path']): Promise<ShowPetByIdResponses>; 109 + } 110 + ``` 111 + 112 + ### Usage Pattern 113 + 114 + ```typescript 115 + // controllers/pets.controller.ts 116 + import { Controller, Get, Post, Param, Query, Body } from '@nestjs/common'; 117 + import type { PetsController } from '../client/nestjs.gen'; 118 + 119 + @Controller('pets') 120 + export class PetsControllerImpl implements PetsController { 121 + @Get() 122 + async listPets(@Query() query?) { 123 + return []; 124 + } 125 + 126 + @Post() 127 + async createPets(@Body() body) { 128 + return { id: 1 }; 129 + } 130 + 131 + @Get(':petId') 132 + async showPetById(@Param() params) { 133 + return { id: params.petId, name: 'Kitty' }; 134 + } 135 + } 136 + ``` 137 + 138 + ## Example Structure 139 + 140 + ``` 141 + examples/openapi-ts-nestjs/ 142 + ├── openapi-ts.config.ts # plugins: ['nestjs', '@hey-api/sdk'] 143 + ├── openapi.json # Petstore spec (same as Fastify example) 144 + ├── package.json # @nestjs/core, @nestjs/common, @nestjs/platform-express 145 + ├── src/ 146 + │ ├── client/ 147 + │ │ ├── nestjs.gen.ts # Generated controller interface 148 + │ │ ├── types.gen.ts # Shared types (from TypeScript plugin) 149 + │ │ ├── sdk.gen.ts # Client SDK (from SDK plugin) 150 + │ │ └── index.ts 151 + │ ├── controllers/ 152 + │ │ └── pets.controller.ts # Implements PetsController interface 153 + │ ├── app.module.ts # NestJS module setup 154 + │ └── main.ts # Bootstrap app 155 + └── test/ 156 + └── pets.test.ts # Supertest integration tests 157 + ``` 158 + 159 + ## Documentation Structure 160 + 161 + Mirror Fastify docs style (~100 lines): 162 + 163 + ```markdown 164 + --- 165 + title: NestJS Plugin 166 + description: Generate NestJS controller interfaces from OpenAPI with type safety 167 + --- 168 + 169 + # NestJS 170 + 171 + ::: warning 172 + NestJS plugin is currently in beta. Interface might change before stable. 173 + ::: 174 + 175 + ## About 176 + 177 + [NestJS](https://nestjs.com) is a progressive Node.js framework for building 178 + efficient, reliable server-side applications. 179 + 180 + The NestJS plugin generates type-safe controller interfaces from OpenAPI specs. 181 + 182 + ## Features 183 + 184 + - NestJS v10 support 185 + - seamless integration with @hey-api/openapi-ts ecosystem 186 + - type-safe controller interfaces 187 + - minimal learning curve 188 + 189 + ## Installation 190 + 191 + Add `nestjs` to your plugins: 192 + 193 + ```js 194 + export default { 195 + input: 'openapi.json', 196 + output: 'src/client', 197 + plugins: [ 198 + 'nestjs', // [!code ++] 199 + ], 200 + }; 201 + ``` 202 + 203 + ## Output 204 + 205 + ### Controller Types 206 + 207 + Generated controller interfaces from all endpoints. Follows SDK naming conventions. 208 + 209 + ::: code-group 210 + 211 + ```ts [example] 212 + import { Controller, Get, Post } from '@nestjs/common'; 213 + import type { PetsController } from '../client/nestjs.gen'; 214 + 215 + @Controller('pets') 216 + export class PetsControllerImpl implements PetsController { 217 + @Get() 218 + async listPets(query?) { 219 + return []; 220 + } 221 + 222 + @Post() 223 + async createPets(body) { 224 + return { id: 1 }; 225 + } 226 + } 227 + ``` 228 + 229 + ```js [config] 230 + export default { 231 + input: 'openapi.json', 232 + output: 'src/client', 233 + plugins: [ 234 + { 235 + name: 'nestjs', 236 + }, 237 + ], 238 + }; 239 + ``` 240 + 241 + ::: 242 + 243 + ## API 244 + 245 + See [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/nestjs/types.ts). 246 + ``` 247 + 248 + ## Dependencies 249 + 250 + ### Plugin (dev) 251 + - `@hey-api/typescript` - Base type generation (required dependency) 252 + 253 + ### Example (runtime) 254 + - `@nestjs/core` (^10.0.0) 255 + - `@nestjs/common` (^10.0.0) 256 + - `@nestjs/platform-express` (^10.0.0) or `@nestjs/platform-fastify` 257 + 258 + ### Optional (future) 259 + - `@nestjs/swagger` - For decorator generation 260 + - `class-validator` - For DTO validation decorators 261 + - `class-transformer` - For DTO transformation 262 + 263 + ## Implementation Approach 264 + 265 + 1. **Copy Fastify plugin structure** as baseline: 266 + - `packages/openapi-ts/src/plugins/nestjs/plugin.ts` 267 + - `packages/openapi-ts/src/plugins/nestjs/types.ts` 268 + - `packages/openapi-ts/src/plugins/nestjs/config.ts` 269 + - `packages/openapi-ts/src/plugins/nestjs/index.ts` 270 + 271 + 2. **Adapt type generation** for controller interface pattern: 272 + - Iterate operations via `plugin.forEach('operation')` 273 + - Extract request params (path, query, body, headers) 274 + - Extract response types 275 + - Generate method signature with typed params and Promise return 276 + 277 + 3. **Parameter mapping**: 278 + ```typescript 279 + // For each operation: 280 + { 281 + methodName: operationId, 282 + params: [ 283 + ...(hasPathParams ? ['params: OperationData["path"]'] : []), 284 + ...(hasQueryParams ? ['query?: OperationData["query"]'] : []), 285 + ...(hasBody ? ['body: OperationData["body"]'] : []), 286 + ...(hasHeaders ? ['headers?: OperationData["headers"]'] : []), 287 + ], 288 + returns: 'Promise<OperationResponses>' 289 + } 290 + ``` 291 + 292 + 4. **Generate interface**: 293 + ```typescript 294 + export interface {ControllerName}Controller { 295 + operation1(...params): Promise<Response1>; 296 + operation2(...params): Promise<Response2>; 297 + } 298 + ``` 299 + 300 + 5. **Create example** at `examples/openapi-ts-nestjs/` 301 + 302 + 6. **Write docs** at `docs/openapi-ts/plugins/nestjs.md` 303 + 304 + ## Deferred Features (v2+) 305 + 306 + - Full `@ApiResponse()`, `@ApiOperation()` decorator generation 307 + - `class-validator` decorators in generated DTOs 308 + - Full module generation with `@Module()` decorator 309 + - Service interface generation for DI layer 310 + - Guard/interceptor/pipe type generation 311 + - Exception filter types 312 + - SwaggerModule auto-configuration 313 + 314 + ## Critical Files Reference 315 + 316 + **Study for implementation:** 317 + - `/Users/undgrnd/Code/openapi-ts/packages/openapi-ts/src/plugins/fastify/plugin.ts` - Core logic template 318 + - `/Users/undgrnd/Code/openapi-ts/packages/openapi-ts/src/plugins/fastify/types.ts` - UserConfig pattern 319 + - `/Users/undgrnd/Code/openapi-ts/packages/openapi-ts/src/plugins/fastify/config.ts` - Plugin registration 320 + - `/Users/undgrnd/Code/openapi-ts/examples/openapi-ts-fastify/src/handlers.ts` - Handler pattern 321 + - `/Users/undgrnd/Code/openapi-ts/docs/openapi-ts/plugins/fastify.md` - Docs template 322 + 323 + ## Next Steps 324 + 325 + 1. Review this research doc 326 + 2. Clarify any open questions with team 327 + 3. Get approval for MVP scope (controller interface only) 328 + 4. Proceed with implementation following Fastify plugin structure